From: tho Date: Thu, 15 Oct 2009 12:23:32 +0000 (+0000) Subject: Packets: added GenericTLVParserRegistry X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=cf48e83de9d4793ca5bd67d1e5acdb5b20968638;p=senf.git Packets: added GenericTLVParserRegistry Utils: added signed/unsigned formatter for value parsers git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1498 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Packets/80211Bundle/InformationElements.hh b/senf/Packets/80211Bundle/InformationElements.hh index a40691c..69fa2a9 100644 --- a/senf/Packets/80211Bundle/InformationElements.hh +++ b/senf/Packets/80211Bundle/InformationElements.hh @@ -56,9 +56,9 @@ namespace senf { SENF_PARSER_FINALIZE ( WLANSSIDInfoElementParser ); SENF_PARSER_INIT() { - type() = TYPEID; + type() = typeId; } - static const type_t::value_type TYPEID = 0x00u; + static const type_t::value_type typeId = 0x00u; }; struct WLANSupportedRatesInfoElementParser @@ -72,9 +72,9 @@ namespace senf { SENF_PARSER_FINALIZE ( WLANSupportedRatesInfoElementParser ); SENF_PARSER_INIT() { - type() = TYPEID; + type() = typeId; } - static const type_t::value_type TYPEID = 0x01u; + static const type_t::value_type typeId = 0x01u; }; struct WLANPowerConstraintInfoElementParser @@ -86,10 +86,10 @@ namespace senf { SENF_PARSER_FINALIZE ( WLANPowerConstraintInfoElementParser ); SENF_PARSER_INIT() { - type() = TYPEID; + type() = typeId; length() = 1; } - static const type_t::value_type TYPEID = 0x20u; + static const type_t::value_type typeId = 0x20u; }; } diff --git a/senf/Packets/80211Bundle/WLANBeaconPacket.test.cc b/senf/Packets/80211Bundle/WLANBeaconPacket.test.cc index d38d2ad..13dce87 100644 --- a/senf/Packets/80211Bundle/WLANBeaconPacket.test.cc +++ b/senf/Packets/80211Bundle/WLANBeaconPacket.test.cc @@ -71,7 +71,7 @@ BOOST_AUTO_UNIT_TEST(WLANBeaconPacket_parse) BOOST_CHECK_EQUAL( i->type(), 0x07); //Country information ++i; //power constraint - BOOST_CHECK_EQUAL( i->type(), senf::WLANPowerConstraintInfoElementParser::TYPEID+0); + BOOST_CHECK_EQUAL( i->type(), senf::WLANPowerConstraintInfoElementParser::typeId+0); BOOST_CHECK( i->is()); senf::WLANPowerConstraintInfoElementParser ie ( i->as()); BOOST_CHECK_EQUAL( ie.value(), 0x42); diff --git a/senf/Packets/GenericTLV.ct b/senf/Packets/GenericTLV.ct index 110b3ed..9c36431 100644 --- a/senf/Packets/GenericTLV.ct +++ b/senf/Packets/GenericTLV.ct @@ -26,10 +26,17 @@ //#include "GenericTLV.ih" // Custom includes +#include +#include +#include +#include #define prefix_ ///////////////////////////////ct.p//////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +// senf::GenericTLVParserBase + template template prefix_ Parser senf::GenericTLVParserBase::init() @@ -53,6 +60,18 @@ prefix_ senf::PacketInterpreterBase::range senf::GenericTLVParserBase::va } template +prefix_ void senf::GenericTLVParserBase::dump(std::ostream & os) + const +{ + boost::io::ios_all_saver ias(os); + os << "GenericTLVParser<" << prettyName(typeid(Base)) << ">\n" + << " type: " << senf::format::dumpint(this->type()) << "\n" + << " length: " << senf::format::dumpint(this->length()) << "\n" + << " value:\n"; + hexdump(value().begin(), value().end(), os); +} + +template template prefix_ void senf::GenericTLVParserBase::value_(ForwardReadableRange const &range) { @@ -65,6 +84,32 @@ prefix_ void senf::GenericTLVParserBase::value_(ForwardReadableRange const this->length_() = rangeSize; } + +/////////////////////////////////////////////////////////////////////////// +// senf::GenericTLVParserRegistry + +template +template +prefix_ void senf::GenericTLVParserRegistry::registerParser() +{ + typename Map::iterator i (map_.find( Parser::typeId )); + if (i == map_.end() ) { + typename BaseParser::type_t::value_type k (Parser::typeId); + map_.insert(k , new detail::GenericTLVParserRegistry_Entry() ); + } +} + +template +prefix_ void senf::GenericTLVParserRegistry::dump( + std::ostream & os, GenericTLVParserBase const & parser) +{ + typename Map::iterator i (map_.find( parser.type())); + if (i == map_.end()) + parser.dump(os); + else + (i->second)->dump(os, parser); +} + ///////////////////////////////ct.e//////////////////////////////////////// #undef prefix_ diff --git a/senf/Packets/GenericTLV.cti b/senf/Packets/GenericTLV.cti index a5d39b5..82adea3 100644 --- a/senf/Packets/GenericTLV.cti +++ b/senf/Packets/GenericTLV.cti @@ -30,6 +30,9 @@ #define prefix_ inline ///////////////////////////////cti.p/////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +// senf::GenericTLVParserBase + template prefix_ senf::PacketParserBase::size_type senf::GenericTLVParserBase::bytes() { @@ -56,7 +59,7 @@ template prefix_ bool senf::GenericTLVParserBase::is() const { - return this->type().value() == Parser::TYPEID; + return this->type().value() == Parser::typeId; } template @@ -104,6 +107,17 @@ prefix_ void senf::GenericTLVParserBase::value( #endif + +/////////////////////////////////////////////////////////////////////////// +// senf::detail:GenericTLVParserRegistry_Entry + +template +prefix_ void senf::detail::GenericTLVParserRegistry_Entry::dump( + std::ostream & os, GenericTLVParserBase const & parser) +{ + (parser.template as()).dump(os); +} + ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/senf/Packets/GenericTLV.hh b/senf/Packets/GenericTLV.hh index 6f89e82..e8e1bb5 100644 --- a/senf/Packets/GenericTLV.hh +++ b/senf/Packets/GenericTLV.hh @@ -27,8 +27,10 @@ #define HH_SENF_Packets_GenericTLV_ 1 // Custom includes +#include #include #include +#include //#include "GenericTLV.hh.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -53,7 +55,7 @@ namespace senf { \endcode Your concrete TLV parsers will inherit from this base class and have to define a specific - value field and a \c TYPEID member: + value field and a \c typeId member: \code struct MyConcreteTLVParser : public MyTLVParserBase { @@ -63,10 +65,10 @@ namespace senf { SENF_PARSER_FINALIZE ( MyConcreteTLVParser ); SENF_PARSER_INIT() { - type() = TYPEID; + type() = typeId; length_() = 4; } - static const type_t::value_type TYPEID = 0x42; + static const type_t::value_type typeId = 0x42; }; \endcode @@ -89,7 +91,7 @@ namespace senf { typedef senf::GenericTLVParserBase MyGenericTLVParser; \endcode - This generiv tlv parser can now be used for example in a list: + This generic tlv parser can now be used for example in a list: \code class MyTestPacketParser : public senf::PacketParserBase { @@ -147,6 +149,8 @@ namespace senf { senf::PacketInterpreterBase::range value() const; + void dump(std::ostream & os) const; + #ifndef DOXYGEN template void value(ForwardReadableRange const & val, @@ -174,6 +178,41 @@ namespace senf { Base & self(); Base const & self() const; }; + + + namespace detail { + template + struct GenericTLVParserRegistry_EntryBase { + virtual void dump(std::ostream & os, GenericTLVParserBase const & parser) = 0; + }; + + template + struct GenericTLVParserRegistry_Entry + : GenericTLVParserRegistry_EntryBase + { + virtual void dump(std::ostream & os, GenericTLVParserBase const & parser); + }; + } + + template + class GenericTLVParserRegistry + : public senf::singleton > + { + typedef boost::ptr_map< + typename BaseParser::type_t::value_type, + detail::GenericTLVParserRegistry_EntryBase > Map; + Map map_; + + GenericTLVParserRegistry() {}; + public: + using senf::singleton >::instance; + friend class senf::singleton >; + + template + void registerParser(); + + void dump(std::ostream & os, GenericTLVParserBase const & parser); + }; } diff --git a/senf/Packets/GenericTLV.test.cc b/senf/Packets/GenericTLV.test.cc index 84be10c..d35523c 100644 --- a/senf/Packets/GenericTLV.test.cc +++ b/senf/Packets/GenericTLV.test.cc @@ -59,11 +59,20 @@ namespace { SENF_PARSER_FINALIZE ( MyConcreteTLVParser ); SENF_PARSER_INIT() { - type() = TYPEID; + type() = typeId; length_() = 4; - } - static const type_t::value_type TYPEID = 0x42; + } + static type_t::value_type const typeId; + + void dump(std::ostream & os) const { + boost::io::ios_all_saver ias(os); + os << "MyConcreteTLVParser\n" + << " type: " << senf::format::dumpint(type()) << "\n" + << " length: " << senf::format::dumpint(length()) << "\n" + << " value: " << senf::format::dumpint(myValue()) << "\n"; + } }; + MyConcreteTLVParser::type_t::value_type const MyConcreteTLVParser::typeId = 0x42; class MyTestPacketParser : public senf::PacketParserBase @@ -141,6 +150,29 @@ BOOST_AUTO_UNIT_TEST(GenericTLV_packet) } +BOOST_AUTO_UNIT_TEST(GenericTLV_registry) +{ + MyTestPacket p ( MyTestPacket::create()); + MyTestPacket::Parser::tlv_list_t::container tlvContainer (p->tlv_list() ); + MyConcreteTLVParser conreteTLVParser ( + tlvContainer.push_back_space().init()); + conreteTLVParser.myValue() << 0xffff; + p.finalizeThis(); + + typedef senf::GenericTLVParserRegistry MyTLVParserRegistry; + + std::stringstream ss; + MyTLVParserRegistry::instance().dump(ss, *tlvContainer.begin()); + BOOST_CHECK_EQUAL( ss.str().substr(0,56), "GenericTLVParser<(anonymous namespace)::MyTLVParserBase>" ); + + MyTLVParserRegistry::instance().registerParser(); + ss.str(""); ss.clear(); + + MyTLVParserRegistry::instance().dump(ss, *tlvContainer.begin()); + BOOST_CHECK_EQUAL( ss.str().substr(0,19), "MyConcreteTLVParser" ); +} + + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ diff --git a/senf/Packets/PacketParser.hh b/senf/Packets/PacketParser.hh index 3eb5d6a..ea2d64f 100644 --- a/senf/Packets/PacketParser.hh +++ b/senf/Packets/PacketParser.hh @@ -299,9 +299,6 @@ namespace senf { ParserProtector( PacketParserBase const * parser); ParserProtector(ParserProtector const & other_); ~ParserProtector(); - - template - void operator()(_ const &) const {} }; protected: ParserProtector protect() const; diff --git a/senf/Utils/Format.cti b/senf/Utils/Format.cti index 41b8ab4..7ce91f4 100644 --- a/senf/Utils/Format.cti +++ b/senf/Utils/Format.cti @@ -44,6 +44,20 @@ senf::format::dumpint(T const & v, typename boost::enable_if::digits); } +template +prefix_ std::string +senf::format::dumpint(T const & v, typename boost::enable_if >::type *) +{ + return detail::dumpintSigned(v.value(), std::numeric_limits::digits); +} + +template +prefix_ std::string +senf::format::dumpint(T const & v, typename boost::enable_if >::type *) +{ + return detail::dumpintUnsigned(v.value(), std::numeric_limits::digits); +} + ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/senf/Utils/Format.hh b/senf/Utils/Format.hh index 7e0b364..7c6e424 100644 --- a/senf/Utils/Format.hh +++ b/senf/Utils/Format.hh @@ -193,6 +193,14 @@ namespace format { template std::string dumpint(T const & v, typename boost::enable_if >::type * = 0); + + template + std::string dumpint(T const & v, + typename boost::enable_if >::type * = 0); + + template + std::string dumpint(T const & v, + typename boost::enable_if >::type * = 0); #endif