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
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
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;
};
}
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>());
senf::WLANPowerConstraintInfoElementParser ie ( i->as<senf::WLANPowerConstraintInfoElementParser>());
BOOST_CHECK_EQUAL( ie.value(), 0x42);
//#include "GenericTLV.ih"
// Custom includes
+#include <boost/io/ios_state.hpp>
+#include <senf/Utils/hexdump.hh>
+#include <senf/Utils/TypeInfo.hh>
+#include <senf/Utils/Format.hh>
#define prefix_
///////////////////////////////ct.p////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+// senf::GenericTLVParserBase<Base>
+
template <class Base>
template <class Parser>
prefix_ Parser senf::GenericTLVParserBase<Base>::init()
}
template <class Base>
+prefix_ void senf::GenericTLVParserBase<Base>::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 <class Base>
template <class ForwardReadableRange>
prefix_ void senf::GenericTLVParserBase<Base>::value_(ForwardReadableRange const &range)
{
this->length_() = rangeSize;
}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::GenericTLVParserRegistry<BaseParser>
+
+template <class BaseParser>
+template <typename Parser>
+prefix_ void senf::GenericTLVParserRegistry<BaseParser>::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<BaseParser, Parser>() );
+ }
+}
+
+template <class BaseParser>
+prefix_ void senf::GenericTLVParserRegistry<BaseParser>::dump(
+ std::ostream & os, GenericTLVParserBase<BaseParser> 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_
#define prefix_ inline
///////////////////////////////cti.p///////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+// senf::GenericTLVParserBase<Base>
+
template <class Base>
prefix_ senf::PacketParserBase::size_type senf::GenericTLVParserBase<Base>::bytes()
{
prefix_ bool senf::GenericTLVParserBase<Base>::is()
const
{
- return this->type().value() == Parser::TYPEID;
+ return this->type().value() == Parser::typeId;
}
template <class Base>
#endif
+
+///////////////////////////////////////////////////////////////////////////
+// senf::detail:GenericTLVParserRegistry_Entry<BaseParser, Parser>
+
+template <class BaseParser, class Parser>
+prefix_ void senf::detail::GenericTLVParserRegistry_Entry<BaseParser, Parser>::dump(
+ std::ostream & os, GenericTLVParserBase<BaseParser> const & parser)
+{
+ (parser.template as<Parser>()).dump(os);
+}
+
///////////////////////////////cti.e///////////////////////////////////////
#undef prefix_
#define HH_SENF_Packets_GenericTLV_ 1
// Custom includes
+#include <boost/ptr_container/ptr_map.hpp>
#include <senf/Packets/Packets.hh>
#include <senf/Utils/type_traits.hh>
+#include <senf/Utils/singleton.hh>
//#include "GenericTLV.hh.mpp"
///////////////////////////////hh.p////////////////////////////////////////
\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
{
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
typedef senf::GenericTLVParserBase<MyTLVParserBase> 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
{
senf::PacketInterpreterBase::range value() const;
+ void dump(std::ostream & os) const;
+
#ifndef DOXYGEN
template<class ForwardReadableRange>
void value(ForwardReadableRange const & val,
Base & self();
Base const & self() const;
};
+
+
+ namespace detail {
+ template <class BaseParser>
+ struct GenericTLVParserRegistry_EntryBase {
+ virtual void dump(std::ostream & os, GenericTLVParserBase<BaseParser> const & parser) = 0;
+ };
+
+ template <class BaseParser, class Parser>
+ struct GenericTLVParserRegistry_Entry
+ : GenericTLVParserRegistry_EntryBase<BaseParser>
+ {
+ virtual void dump(std::ostream & os, GenericTLVParserBase<BaseParser> const & parser);
+ };
+ }
+
+ template <class BaseParser>
+ class GenericTLVParserRegistry
+ : public senf::singleton<GenericTLVParserRegistry<BaseParser> >
+ {
+ typedef boost::ptr_map<
+ typename BaseParser::type_t::value_type,
+ detail::GenericTLVParserRegistry_EntryBase<BaseParser> > Map;
+ Map map_;
+
+ GenericTLVParserRegistry() {};
+ public:
+ using senf::singleton<GenericTLVParserRegistry<BaseParser> >::instance;
+ friend class senf::singleton<GenericTLVParserRegistry<BaseParser> >;
+
+ template <typename Parser>
+ void registerParser();
+
+ void dump(std::ostream & os, GenericTLVParserBase<BaseParser> const & parser);
+ };
}
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
}
+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<MyConcreteTLVParser>());
+ conreteTLVParser.myValue() << 0xffff;
+ p.finalizeThis();
+
+ typedef senf::GenericTLVParserRegistry<MyTLVParserBase> 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<MyConcreteTLVParser>();
+ ss.str(""); ss.clear();
+
+ MyTLVParserRegistry::instance().dump(ss, *tlvContainer.begin());
+ BOOST_CHECK_EQUAL( ss.str().substr(0,19), "MyConcreteTLVParser" );
+}
+
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
ParserProtector( PacketParserBase const * parser);
ParserProtector(ParserProtector const & other_);
~ParserProtector();
-
- template <class _>
- void operator()(_ const &) const {}
};
protected:
ParserProtector protect() const;
return detail::dumpintUnsigned(v, std::numeric_limits<T>::digits);
}
+template <class T>
+prefix_ std::string
+senf::format::dumpint(T const & v, typename boost::enable_if<boost::is_signed<typename T::value_type> >::type *)
+{
+ return detail::dumpintSigned(v.value(), std::numeric_limits<typename T::value_type>::digits);
+}
+
+template <class T>
+prefix_ std::string
+senf::format::dumpint(T const & v, typename boost::enable_if<boost::is_unsigned<typename T::value_type> >::type *)
+{
+ return detail::dumpintUnsigned(v.value(), std::numeric_limits<typename T::value_type>::digits);
+}
+
///////////////////////////////cti.e///////////////////////////////////////
#undef prefix_
template <class T>
std::string dumpint(T const & v,
typename boost::enable_if<boost::is_unsigned<T> >::type * = 0);
+
+ template <class T>
+ std::string dumpint(T const & v,
+ typename boost::enable_if<boost::is_signed<typename T::value_type> >::type * = 0);
+
+ template <class T>
+ std::string dumpint(T const & v,
+ typename boost::enable_if<boost::is_unsigned<typename T::value_type> >::type * = 0);
#endif