unsigned char tlv2_value[] = {
0x1a, 0x2b, 0x3c, 0x4d };
MIHGenericTLVParser tlv2 ( tlvListContainer.push_back_space());
- tlv2.type() = 0x0c;
+ tlv2.type() = 0x43;
tlv2.value( tlv2_value);
mihPacket.finalizeAll();
0x0a, // first bit not set, length=10
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, // value
// second test tlv
- 0x0c, // type
+ 0x43, // type
0x04, // first bit not set, length=4
0x1a, 0x2b, 0x3c, 0x4d // value
};
prefix_ void senf::GenericTLVParserRegistry<BaseParser,Keytype>::registerParser()
{
Keytype key (Parser::typeId+0);
+ std::cout << "GenericTLVParserRegistry::registerParser " << unsigned(key) << std::endl;
typename Map::iterator i (map_.find( key ));
if (i == map_.end() )
map_.insert(key, new detail::GenericTLVParserRegistry_Entry<BaseParser, Parser>() );
template <class BaseParser, class Keytype>
prefix_ void senf::GenericTLVParserRegistry<BaseParser,Keytype>::dump(
- GenericTLVParserBase<BaseParser> const & parser, std::ostream & os)
+ GenericTLVParser const & parser, std::ostream & os)
const
{
typename Map::const_iterator i (map_.find( parser.type()));
template <class BaseParser, class Keytype>
prefix_ void senf::GenericTLVParserRegistry<BaseParser,Keytype>::dump(
- GenericTLVParserBase<BaseParser> const & parser, Keytype const & key, std::ostream & os)
+ GenericTLVParser const & parser, Keytype const & key, std::ostream & os)
const
{
typename Map::const_iterator i (map_.find( key));
(i->second)->dump(parser, os);
}
+template <class BaseParser, class Keytype>
+prefix_ senf::PacketParserBase::size_type senf::GenericTLVParserRegistry<BaseParser,Keytype>::bytes(
+ GenericTLVParser const & parser)
+ const
+{
+ typename Map::const_iterator i (map_.find( parser.type()));
+ if (i != map_.end())
+ return (i->second)->bytes(parser);
+ else
+ throw TLVParserNotRegisteredException();
+}
+
+
+
///////////////////////////////ct.e////////////////////////////////////////
#undef prefix_
template <class Base>
prefix_ senf::PacketParserBase::size_type senf::GenericTLVParserBase<Base>::bytes()
{
- return senf::bytes(self()) + this->length();
+ if (Base::Registry::instance().isRegistered( *this))
+ return Base::Registry::instance().bytes( *this);
+ else
+ return senf::bytes(self()) + this->length();
}
template <class Base>
(parser.template as<Parser>()).dump(os);
}
+template <class BaseParser, class Parser>
+prefix_ senf::PacketParserBase::size_type
+senf::detail::GenericTLVParserRegistry_Entry<BaseParser, Parser>::bytes(
+ GenericTLVParserBase<BaseParser> const & parser)
+ const
+{
+ return senf::bytes( parser.template as<Parser>());
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::GenericTLVParserRegistry<BaseParser,Keytype>
template <class BaseParser, class Keytype>
prefix_ bool senf::GenericTLVParserRegistry<BaseParser,Keytype>::isRegistered(
- GenericTLVParserBase<BaseParser> const & parser)
+ GenericTLVParser const & parser)
const
{
typename Map::const_iterator i (map_.find( parser.type()));
bool is() const;
senf::PacketInterpreterBase::range value() const;
-
+
void dump(std::ostream & os) const;
#ifndef DOXYGEN
template <class BaseParser>
struct GenericTLVParserRegistry_EntryBase {
virtual void dump(GenericTLVParserBase<BaseParser> const & parser, std::ostream & os) const = 0;
+ virtual PacketParserBase::size_type bytes(GenericTLVParserBase<BaseParser> const & parser) const = 0;
};
template <class BaseParser, class Parser>
: GenericTLVParserRegistry_EntryBase<BaseParser>
{
virtual void dump(GenericTLVParserBase<BaseParser> const & parser, std::ostream & os) const;
+ virtual PacketParserBase::size_type bytes(GenericTLVParserBase<BaseParser> const & parser) const;
};
//Helper Functor for STL-compatible predicate (E.g. find_if, for_each ...)
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. Otherwise the generic TLV parser will be dumped in a generic way
- (hexdump of the value).
+ will be called.
\see
GenericTLVParserBase for the general TLV class structure \n
template <typename Parser>
void registerParser();
+ typedef GenericTLVParserBase<BaseParser> GenericTLVParser;
+
bool isRegistered(GenericTLVParserBase<BaseParser> const & parser) const;
bool isRegistered(Keytype const & key) const;
- void dump(GenericTLVParserBase<BaseParser> const & parser, std::ostream & os) const;
- void dump(GenericTLVParserBase<BaseParser> const & parser, Keytype const & key, std::ostream & os) 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") {}
+ };
+
+
/** \brief Statically add an entry to a TLV parser registry
This macro will declare an anonymous global variable in such a way, that constructing
SENF_AUTO_UNIT_TEST(GenericTLV_registry)
{
+ typedef senf::GenericTLVParserRegistry<MyTLVParserBase> MyTLVParserRegistry;
MyTestPacket p ( MyTestPacket::create());
MyTestPacket::Parser::tlv_list_t::container tlvContainer (p->tlv_list() );
MyConcreteTLVParser conreteTLVParser (
p.finalizeThis();
std::stringstream ss;
- (*tlvContainer.begin()).dump( ss);
+ tlvContainer.begin()->dump( ss);
BOOST_CHECK_EQUAL( ss.str().substr(0,58),
" GenericTLVParser<(anonymous namespace)::MyTLVParserBase>" );
+ BOOST_CHECK( ! MyTLVParserRegistry::instance().isRegistered( tlvContainer.begin()->type()));
+
+ MyTLVParserRegistry::instance().registerParser<MyConcreteTLVParser>();
+ BOOST_CHECK( MyTLVParserRegistry::instance().isRegistered( tlvContainer.begin()->type()));
+ BOOST_CHECK_EQUAL(
+ MyTLVParserRegistry::instance().bytes( *tlvContainer.begin()),
+ senf::bytes( *tlvContainer.begin()) );
- senf::GenericTLVParserRegistry<MyTLVParserBase>::instance()
- .registerParser<MyConcreteTLVParser>();
ss.str(""); ss.clear();
- (*tlvContainer.begin()).dump( ss);
+ tlvContainer.begin()->dump( ss);
BOOST_CHECK_EQUAL( ss.str().substr(0,21), " MyConcreteTLVParser" );
}