X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FPackets%2FGenericTLV.hh;h=7792653700b9c8fec866602cfd5f6d17e661c7be;hb=7661548b20e6c7627f54bff87e0758396fd523ef;hp=8d1357fda5d5c3e2c75eb1d98cdf7dbb135c7477;hpb=33d8f945cadcf912e8637a59d97ac1d1b320af9f;p=senf.git diff --git a/senf/Packets/GenericTLV.hh b/senf/Packets/GenericTLV.hh index 8d1357f..7792653 100644 --- a/senf/Packets/GenericTLV.hh +++ b/senf/Packets/GenericTLV.hh @@ -33,16 +33,16 @@ #include //#include "GenericTLV.hh.mpp" -///////////////////////////////hh.p//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// namespace senf { - + /** \brief Base class for generic TLV parsers - + This abstract base class can be used to define generic TLV parsers. The following class structure is assumed: \image html GenericTLV.png - + Your TLVParser base class has to define a \c type and a \c length field: \code struct MyTLVParserBase : public senf::PacketParserBase @@ -53,7 +53,7 @@ namespace senf { SENF_PARSER_FINALIZE ( MyTLVParserBase ); }; \endcode - + Your concrete TLV parsers will inherit from this base class and have to define a specific value field and a \c typeId member: \code @@ -63,34 +63,34 @@ namespace senf { SENF_PARSER_INHERIT ( MyTLVParserBase ); SENF_PARSER_FIELD ( myValue, senf::UInt32Parser ); SENF_PARSER_FINALIZE ( MyConcreteTLVParser ); - + SENF_PARSER_INIT() { type() = typeId; length_() = 4; - } + } static const type_t::value_type typeId = 0x42; }; \endcode - + With GenericTLVParserBase you can define a generic parser class which provides members to access the value data and and to cast the parser to a concrete tlv - parser: + parser: \code struct MyGenericTLVParser : public senf::GenericTLVParserBase { typedef senf::GenericTLVParserBase base; MyGenericTLVParser(data_iterator i, state_type s) : base(i,s) {} - + // members for your generic TLV parser... }; \endcode - + If your generic TLV parser just inherits from GenericTLVParserBase and doesn't add any additional functionality you can use a simple \c typedef as well: \code typedef senf::GenericTLVParserBase MyGenericTLVParser; \endcode - + This generic tlv parser can now be used for example in a list: \code class MyTestPacketParser : public senf::PacketParserBase @@ -101,7 +101,7 @@ namespace senf { SENF_PARSER_FINALIZE ( MyTestPacketParser ); }; \endcode - + Now, you can access the TLV parsers in the list in a generic way or you can cast the parsers to some concrete tlv parser: \code @@ -109,23 +109,23 @@ namespace senf { typedef MyTestPacket::Parser::tlv_list_t::container container_t; container_t tlvContainer (p->tlv_list() ); optContainer_t::iterator listIter (tlvContainer.begin()); - + // listIter points to a MyGenericTLVParser, so you have generic access: listIter->type() = 0x42; listIter->value( someRangeOfValueData); - + // cast to an instance of MyConcreteTLVParser: if (listIter->is()) { MyConcreteTLVParser concreteTLVParser ( listIter->as()); concreteTLVParser.myValue() = 0xabababab; } - + // add a MyConcreteTLV to the list: MyConcreteTLVParser tlv ( tlvContainer.push_back_space().init()); tlv.myValue() = 0xffff; - \endcode + \endcode - \see + \see IPv6GenericOptionParser, WLANGenericInfoElementParser, MIHGenericTLVParser \n GenericTLVParserRegistry */ @@ -133,25 +133,25 @@ namespace senf { class GenericTLVParserBase : public Base { public: - GenericTLVParserBase(senf::PacketParserBase::data_iterator i, senf::PacketParserBase::state_type s) + GenericTLVParserBase(senf::PacketParserBase::data_iterator i, senf::PacketParserBase::state_type s) : Base(i,s) {} - - senf::PacketParserBase::size_type bytes(); + + senf::PacketParserBase::size_type bytes() const; void init() const; template Parser init(); - + template Parser as() const; - + template bool is() const; senf::PacketInterpreterBase::range value() const; void dump(std::ostream & os) const; - + #ifndef DOXYGEN template void value(ForwardReadableRange const & val, @@ -163,31 +163,32 @@ namespace senf { template void value(std::pair const & val, - typename boost::enable_if >::type * = 0); + typename boost::enable_if >::type * = 0); #else template void value(ForwardReadableRange const & val); - + template void value(std::pair const & val); -#endif - +#endif + private: template void value_(ForwardReadableRange const &range); - + Base & self(); Base const & self() const; }; - - + + namespace detail { template struct GenericTLVParserRegistry_EntryBase { + virtual ~GenericTLVParserRegistry_EntryBase() {} virtual void dump(GenericTLVParserBase const & parser, std::ostream & os) const = 0; virtual PacketParserBase::size_type bytes(GenericTLVParserBase const & parser) const = 0; }; - + template struct GenericTLVParserRegistry_Entry : GenericTLVParserRegistry_EntryBase @@ -195,35 +196,35 @@ namespace senf { virtual void dump(GenericTLVParserBase const & parser, std::ostream & os) const; virtual PacketParserBase::size_type bytes(GenericTLVParserBase const & parser) const; }; - + //Helper Functor for STL-compatible predicate (E.g. find_if, for_each ...) template class Predicate { public: - const bool operator() (BaseParser const &p) const{ + bool operator() (BaseParser const &p) const { return p.template is(); } }; } - + /** \brief TLV parser registration facility The %GenericTLVParserRegistry provides a generic facility to globally register concrete TLV parser by the type value. The concrete TLV parser must therefore provide a \c typeId member. See GenericTLVParserBase for details about the assumed class structure. - - Every registry is identified by the base tlv parser class. Parsers can be registered - statically only: + + Every registry is identified by the base tlv parser class. Parsers can be registered + statically only: \code GenericTLVParserRegistry::RegistrationProxy registerConcreteTLVParser; - \endcode - This global variable declaration will register ConcreteTLVParser. The variable - registerConcreteTLVParser is a dummy. It's only function is to force the call of + \endcode + This global variable declaration will register ConcreteTLVParser. The variable + registerConcreteTLVParser is a dummy. It's only function is to force the call of it's constructor during global construction time. This static registration only works when the symbol is included into the final binary. - + To simplify the registration the \ref SENF_PACKET_TLV_REGISTRY_REGISTER macro can be used. The \c ConreteTLVParser must therefore provide a \c Registry typedef pointing to the %GenericTLVParserRegistry; typically you put this typedef to the TLVBaseParser class. @@ -239,34 +240,34 @@ namespace senf { static const type_t::value_type typeId = 0x42; void dump(std::ostream & os) const; }; - + // register MyConcreteTLVParser to the MyTLVParserBase-Registry with the type id 0x42: SENF_PACKET_TLV_REGISTRY_REGISTER( MyConcreteTLVParser ); \endcode - + The registry provides a dump() member to dump an instance of a generic TLV parser. If the type value of the given TLV parser is registered the generic tlv will be casted to the registered concrete TLV parser and the dump member from this parser will be called. - + \see GenericTLVParserBase for the general TLV class structure \n IPv6OptionParser::Registry, WLANInfoElementParser::Registry, - MIHBaseTLVParser::Registry + MIHBaseTLVParser::Registry */ template class GenericTLVParserRegistry : public senf::singleton > { - typedef boost::ptr_map > Map; Map map_; - + GenericTLVParserRegistry() {}; public: using senf::singleton >::instance; friend class senf::singleton >; - + template struct RegistrationProxy { RegistrationProxy(); @@ -274,27 +275,28 @@ namespace senf { template void registerParser(); - + typedef GenericTLVParserBase GenericTLVParser; - + bool isRegistered(GenericTLVParserBase const & parser) const; bool isRegistered(Keytype const & key) const; - + void dump(GenericTLVParser const & parser, std::ostream & os) const; void dump(GenericTLVParser const & parser, Keytype const & key, std::ostream & os) const; - + PacketParserBase::size_type bytes(GenericTLVParser const & parser) const; + PacketParserBase::size_type bytes(GenericTLVParser const & parser, Keytype const & key) const; }; - + struct TLVParserNotRegisteredException : public senf::Exception - { - TLVParserNotRegisteredException() : senf::Exception("tlv parser not registered") {} + { + TLVParserNotRegisteredException() : senf::Exception("tlv parser not registered") {} }; - + /** \brief Statically add an entry to a TLV parser registry - This macro will declare an anonymous global variable in such a way, that constructing + This macro will declare an anonymous global variable in such a way, that constructing this variable will register the given tlv parser. \hideinitializer @@ -305,10 +307,10 @@ namespace senf { ConreteTLVParser::Registry::RegistrationProxy \ BOOST_PP_CAT(tlvparserRegistration_, __LINE__); \ } - + } -///////////////////////////////hh.e//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// //#include "GenericTLV.cci" #include "GenericTLV.ct" #include "GenericTLV.cti"