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."){} };
- /** \brief xxx
- \todo document me
-
- \ingroup protocolbundle_80221
- */
+ struct TLVLengthException : public senf::Exception
+ { TLVLengthException()
+ : senf::Exception("TLVLengthException"){} };
+
+
class DynamicTLVLengthParser
: public detail::packet::IntParserOps<DynamicTLVLengthParser, boost::uint32_t>,
public PacketParserBase
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<ExtendedLengthFlagParser>( 0 );
-// }
-//
-// FixedLengthParser fixed_length_field() const {
-// return parse<FixedLengthParser>( 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<MacAddressesTLVPacketType> 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<DynamicTLVLengthParser> &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 <class ForwardReadableRange>
+ 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
*/
: public PacketTypeBase,
public PacketTypeMixin<GenericTLVPacketType>
{
+#ifndef DOXYGEN
typedef PacketTypeMixin<GenericTLVPacketType> mixin;
- typedef ConcretePacket<GenericTLVPacketType> packet;
- typedef GenericTLVPacketParser parser;
+#endif
+ typedef ConcretePacket<GenericTLVPacketType> 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<GenericTLVPacketType> GenericTLVPacket;
}
///////////////////////////////hh.e////////////////////////////////////////
//#include "TLVPacket.cci"
-//#include "TLVPacket.ct"
+#include "TLVPacket.ct"
//#include "TLVPacket.cti"
#endif