X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FPackets%2FGenericTLV.hh;h=8d1357fda5d5c3e2c75eb1d98cdf7dbb135c7477;hb=f13780e9e4da7df981d6f6542fbdc714beb34765;hp=b0dab34c8b252ce728a337edc19ecd7d5dbd845a;hpb=9ffdaae4804503c4f36a53747c852a87ee626b9e;p=senf.git diff --git a/senf/Packets/GenericTLV.hh b/senf/Packets/GenericTLV.hh index b0dab34..8d1357f 100644 --- a/senf/Packets/GenericTLV.hh +++ b/senf/Packets/GenericTLV.hh @@ -126,7 +126,8 @@ namespace senf { \endcode \see - IPv6GenericOptionTLVParser, WLANGenericInfoElementParser, MIHGenericTLVParser + IPv6GenericOptionParser, WLANGenericInfoElementParser, MIHGenericTLVParser \n + GenericTLVParserRegistry */ template class GenericTLVParserBase : public Base @@ -148,7 +149,7 @@ namespace senf { bool is() const; senf::PacketInterpreterBase::range value() const; - + void dump(std::ostream & os) const; #ifndef DOXYGEN @@ -183,30 +184,88 @@ namespace senf { namespace detail { template struct GenericTLVParserRegistry_EntryBase { - virtual void dump(GenericTLVParserBase const & parser, std::ostream & os) = 0; + 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 { - virtual void dump(GenericTLVParserBase const & parser, std::ostream & os); + 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{ + return p.template is(); + } }; } - template + /** \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: + \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 + 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. + \code + struct MyTLVParserBase : public senf::PacketParserBase + { + ... + typedef GenericTLVParserRegistry Registry; + }; + struct MyConcreteTLVParser : public MyTLVParserBase + { + .... + 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 + */ + template class GenericTLVParserRegistry - : public senf::singleton > + : public senf::singleton > { - typedef boost::ptr_map< - typename BaseParser::type_t::value_type, + typedef boost::ptr_map > Map; Map map_; GenericTLVParserRegistry() {}; public: - using senf::singleton >::instance; - friend class senf::singleton >; + using senf::singleton >::instance; + friend class senf::singleton >; template struct RegistrationProxy { @@ -216,14 +275,35 @@ namespace senf { template void registerParser(); - void dump(GenericTLVParserBase const & parser, std::ostream & os); + 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; + }; + + struct TLVParserNotRegisteredException : public senf::Exception + { + TLVParserNotRegisteredException() : senf::Exception("tlv parser not registered") {} }; + -# define SENF_PACKET_TLV_REGISTRY_REGISTER( BaseTLVParser, ConreteTLVParser ) \ - namespace { \ - senf::GenericTLVParserRegistry \ - ::RegistrationProxy \ - BOOST_PP_CAT(tlvparserRegistration_, __LINE__); \ + /** \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 variable will register the given tlv parser. + + \hideinitializer + \see senf::GenericTLVParserRegistry + */ +# define SENF_PACKET_TLV_REGISTRY_REGISTER( ConreteTLVParser ) \ + namespace { \ + ConreteTLVParser::Registry::RegistrationProxy \ + BOOST_PP_CAT(tlvparserRegistration_, __LINE__); \ } }