X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2F80221Bundle%2FTLVPacket.hh;h=4c1a5882506dac2ebc363bdf55c6fc36fc6328ad;hb=fd3a0e8ac95d1158e9ea661ddf9187b67c70169f;hp=057f06f6ecf6f38ae7babf8b76037fbe461363a1;hpb=2bf2d69ec97a475ca56b90f9abec1c1b5b0d6b82;p=senf.git diff --git a/Packets/80221Bundle/TLVPacket.hh b/Packets/80221Bundle/TLVPacket.hh index 057f06f..4c1a588 100644 --- a/Packets/80221Bundle/TLVPacket.hh +++ b/Packets/80221Bundle/TLVPacket.hh @@ -35,10 +35,11 @@ namespace senf { - struct TLVLengthException : public senf::Exception - { TLVLengthException() - : senf::Exception("TLVLengthException"){} }; + { + TLVLengthException() + : senf::Exception("TLVLengthException") {} + }; class DynamicTLVLengthParser @@ -71,31 +72,86 @@ namespace senf { }; + /** \brief Base class for TLV-Packet-Parsers + + BaseTLVPacketParser is the abstract base class for TLV-Packet-Parsers. It defines the + \ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a + DynamicTLVLengthParser. The length field is read-only. + + To create your own \c TLVParser you have to inherit from BaseTLVPacketParser (don't + forget \ref SENF_PARSER_INHERIT) and define the \c value field. In the following example + the value is a vector of MacAddresses: + \code + struct MacAddressesTLVParser : public BaseTLVPacketParser { + # include SENF_PARSER() + SENF_PARSER_INHERIT ( BaseTLVPacketParser ); + SENF_PARSER_VECTOR ( value, bytes(length), senf::MACAddressParser ); + SENF_PARSER_FINALIZE( MacAddressesTLVParser ); + }; + + struct MacAddressesTLVPacketType : public PacketTypeBase { + typedef MacAddressesTLVParser parser; + ... + static void finalize(ConcretePacket p) { + p->shrinkLength(); + } + }; + \endcode + + You have to adjust the maximum length value with the \ref maxLengthValue function + before the length value is set. The default maximum value is 127. So, in the above + example adding more than 21 MACAddresses to the vector will throw a TLVLengthException + if you don't call \c macAddressesTLVPacket->maxLengthValue( \e some_value) before. + + \see DynamicTLVLengthParser \n + GenericTLVPacketParser \n + */ class BaseTLVPacketParser : public PacketParserBase { + public: # include SENF_PARSER() SENF_PARSER_FIELD ( type, UInt8Parser ); SENF_PARSER_FIELD_RO ( length, DynamicTLVLengthParser ); SENF_PARSER_FINALIZE ( BaseTLVPacketParser ); + /** \brief set maximum value of length field + + The size of the length field will be increased if necessary. + \param v maximum value of length field + */ void maxLengthValue(DynamicTLVLengthParser::value_type v) const { length_().maxValue(v); } + + /** \brief shrink size of length field to minimum + + The size of the length field will be decreased to minimum necessary to hold + the current length value. + */ void shrinkLength() { length_().shrink(); }; protected: + /// return size of length field size_type length_bytes() const { return length_().bytes(); }; + /// set length field to given value void length(DynamicTLVLengthParser::value_type &v) { length_() = v; }; + /// resize the Packet after the length field to given size + senf::safe_data_iterator resizeValue(DynamicTLVLengthParser::value_type size); }; + /** \brief Parser for a generic TLV packet + + \see GenericTLVPacketType + */ struct GenericTLVPacketParser : public BaseTLVPacketParser { # include SENF_PARSER() - SENF_PARSER_INHERIT( BaseTLVPacketParser ) - SENF_PARSER_FINALIZE( GenericTLVPacketParser ); + SENF_PARSER_INHERIT ( BaseTLVPacketParser ); + SENF_PARSER_SKIP ( length(), 0 ); + SENF_PARSER_FINALIZE ( GenericTLVPacketParser ); SENF_PARSER_INIT() { maxLengthValue( DynamicTLVLengthParser::max_value); @@ -107,22 +163,38 @@ namespace senf { void value(ForwardReadableRange const &range); }; + /** \brief Generic TLV packet + + \par Packet type (typedef): + \ref GenericTLVPacket + + \image html TLV.png + + \ingroup protocolbundle_80221 + */ struct GenericTLVPacketType : public PacketTypeBase, public PacketTypeMixin { +#ifndef DOXYGEN typedef PacketTypeMixin mixin; - typedef ConcretePacket packet; - typedef GenericTLVPacketParser parser; +#endif + typedef ConcretePacket packet; ///< GenericTLV packet typedef + typedef GenericTLVPacketParser parser; ///< typedef to the parser of GenericTLV packet using mixin::nextPacketRange; using mixin::init; using mixin::initSize; - static void finalize(packet p); - static void dump(packet p, std::ostream & os); + /** \brief Dump given GenericTLVPacket in readable form to given output stream */ + static void dump(packet p, std::ostream & os); + static void finalize(packet p); ///< Finalize packet. + /**< shrink size of length field to minimum + \see BaseTLVPacketParser::shrinkLength() */ + }; + /** \brief GenericTLV packet typedef */ typedef ConcretePacket GenericTLVPacket; }