X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2F80221Bundle%2FTLVPacket.hh;h=4c1a5882506dac2ebc363bdf55c6fc36fc6328ad;hb=a1fdb7bb122f0b05be809a922d4b7ef5e125fa67;hp=1180839dc4f0d05b5a50fb558f64066818790d41;hpb=9c3803e6f6a6073a43524940307b7dd7de8b16d9;p=senf.git diff --git a/Packets/80221Bundle/TLVPacket.hh b/Packets/80221Bundle/TLVPacket.hh index 1180839..4c1a588 100644 --- a/Packets/80221Bundle/TLVPacket.hh +++ b/Packets/80221Bundle/TLVPacket.hh @@ -35,22 +35,13 @@ namespace senf { - /** \brief xxx - - \todo document me - \todo add usefull exceptions strings - - \ingroup protocolbundle_80221 - */ - struct UnsuportedTLVPacketException : public senf::Exception - { UnsuportedTLVPacketException() - : senf::Exception("length of length can be max. 4 bytes. Sorry."){} }; + struct TLVLengthException : public senf::Exception + { + TLVLengthException() + : senf::Exception("TLVLengthException") {} + }; - /** \brief xxx - \todo document me - - \ingroup protocolbundle_80221 - */ + class DynamicTLVLengthParser : public detail::packet::IntParserOps, public PacketParserBase @@ -71,48 +62,113 @@ namespace senf { void init() const; # include SENF_PARSER() - SENF_PARSER_PRIVATE_BITFIELD ( extended_length_flag, 1, bool ); SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field, 7, unsigned ); - + + void shrink(); + void maxValue(DynamicTLVLengthParser::value_type v); private: + void resize(size_type size); + }; + -// typedef FlagParser < 0 > ExtendedLengthFlagParser; -// typedef UIntFieldParser < 1, 8 > FixedLengthParser; -// -// ExtendedLengthFlagParser extended_length_flag() const { -// return parse( 0 ); -// } -// -// FixedLengthParser fixed_length_field() const { -// return parse( 0 ); -// } + /** \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 ); - void resize(size_type size, SafePacketParserWrapper &safeThis); - }; + /** \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 parse TLVPacket Packet + /** \brief shrink size of length field to minimum - \todo document me - - \see TLVPacketType + The size of the length field will be decreased to minimum necessary to hold + the current length value. + */ + void shrinkLength() { + length_().shrink(); + }; - \ingroup protocolbundle_80221 + 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 PacketParserBase + struct GenericTLVPacketParser : public BaseTLVPacketParser { -# include SENF_PARSER() +# include SENF_PARSER() + SENF_PARSER_INHERIT ( BaseTLVPacketParser ); + SENF_PARSER_SKIP ( length(), 0 ); + SENF_PARSER_FINALIZE ( GenericTLVPacketParser ); - SENF_PARSER_FIELD ( type, UInt8Parser ); - SENF_PARSER_FIELD_RO ( length, DynamicTLVLengthParser ); - SENF_PARSER_VECTOR ( value, bytes(length), UInt8Parser ); + SENF_PARSER_INIT() { + maxLengthValue( DynamicTLVLengthParser::max_value); + } - SENF_PARSER_FINALIZE( GenericTLVPacketParser ); + senf::PacketInterpreterBase::range value() const; + + template + void value(ForwardReadableRange const &range); }; - /** \brief generic TLV Packet type - - \todo document me + /** \brief Generic TLV packet + + \par Packet type (typedef): + \ref GenericTLVPacket + + \image html TLV.png \ingroup protocolbundle_80221 */ @@ -120,26 +176,32 @@ namespace senf { : 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 -// static optional_range nextPacketRange(packet p); 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; } ///////////////////////////////hh.e//////////////////////////////////////// //#include "TLVPacket.cci" -//#include "TLVPacket.ct" +#include "TLVPacket.ct" //#include "TLVPacket.cti" #endif