//#include "WLANPacket.ih"
// Custom includes
-#include <senf/Packets/Packets.hh>
#include <boost/io/ios_state.hpp>
#define prefix_
//#include "MIHPacket.ih"
// Custom includes
-#include <senf/Packets/Packets.hh>
#include <senf/Utils/hexdump.hh>
#include <boost/io/ios_state.hpp>
#include <senf/Packets/DefaultBundle/EthernetPacket.hh>
\note you must call mihfIdPacket.maxLengthValue( 253) *before*
setting longer MIHF_IDs values.
*/
- class MIHFId_TLVParser : public BaseTLVPacketParser
+ class MIHFId_TLVParser : public MIHBaseTLVParser
{
# include SENF_PARSER()
- SENF_PARSER_INHERIT ( BaseTLVPacketParser );
- SENF_PARSER_SKIP ( length(), 0 );
- SENF_PARSER_FINALIZE ( MIHFId_TLVParser );
+ SENF_PARSER_INHERIT ( MIHBaseTLVParser );
+ SENF_PARSER_SKIP ( length(), 0 );
+ SENF_PARSER_FINALIZE ( MIHFId_TLVParser );
public:
std::string asString() const;
struct MIHPayloadPacketParser : public PacketParserBase
{
# include SENF_PARSER()
- SENF_PARSER_LIST ( tlv_list, packetSize(), GenericTLVPacketParser );
+ SENF_PARSER_LIST ( tlv_list, packetSize(), MIHGenericTLVPacketParser );
SENF_PARSER_FINALIZE ( MIHPayloadPacketParser );
};
BOOST_CHECK_EQUAL( mihPayload->tlv_list().size(), 2u);
MIHPayloadPacketParser::tlv_list_t::container tlv_list_container (mihPayload->tlv_list());
- GenericTLVPacket::Parser tlv1 = *tlv_list_container.begin();
+ MIHGenericTLVPacket::Parser tlv1 = *tlv_list_container.begin();
BOOST_CHECK_EQUAL( tlv1.type(), 0x42);
BOOST_CHECK_EQUAL( tlv1.length(), 0x0au);
BOOST_CHECK_EQUAL( tlv1.value().size(), 0x0a);
- GenericTLVPacket::Parser tlv2 = *boost::next(tlv_list_container.begin());
+ MIHGenericTLVPacket::Parser tlv2 = *boost::next(tlv_list_container.begin());
BOOST_CHECK_EQUAL( tlv2.type(), 0x43);
BOOST_CHECK_EQUAL( tlv2.length(), 0x05u);
BOOST_CHECK_EQUAL( tlv2.value().size(), 0x05);
unsigned char tlv1_value[] = {
0x1a, 0x2b, 0x3c, 0x4d, 0x5e };
- GenericTLVPacket tlv2 = (GenericTLVPacket::create());
+ MIHGenericTLVPacket tlv2 = (MIHGenericTLVPacket::create());
tlv2->type() = 0x43;
tlv2->value( tlv1_value);
tlv2.finalizeThis();
unsigned char tlv2_value[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
- GenericTLVPacket tlv1 (GenericTLVPacket::create());
+ MIHGenericTLVPacket tlv1 (MIHGenericTLVPacket::create());
tlv1->type() = 0x42;
tlv1->value( tlv2_value);
tlv1.finalizeThis();
0x1a, 0x2b, 0x3c, 0x4d, 0x5e // value
};
- BOOST_CHECK(equal( mihPacket.data().begin(), mihPacket.data().end(), data ));
+ SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
+ mihPacket.data().begin(), mihPacket.data().end() );
}
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
-prefix_ senf::safe_data_iterator senf::BaseTLVPacketParser::resizeValueField(
- DynamicTLVLengthParser::value_type size)
+prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField(
+ MIHTLVLengthParser::value_type size)
{
- DynamicTLVLengthParser::value_type current_length ( length());
+ MIHTLVLengthParser::value_type current_length ( length());
length_() << size;
safe_data_iterator si (data(), boost::next(i(), 1 + length_().bytes() ));
}
-prefix_ senf::DynamicTLVLengthParser::value_type senf::DynamicTLVLengthParser::value() const
+prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const
{
switch (bytes() ) {
case 1:
case 5:
return parse<UInt32Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
default:
- throw(TLVLengthException());
+ throw( MIHTLVLengthException());
};
}
-prefix_ void senf::DynamicTLVLengthParser::value(value_type const & v)
+prefix_ void senf::MIHTLVLengthParser::value(value_type const & v)
{
switch (bytes() ) {
case 1:
- if (v > 128) throw( TLVLengthException());
+ if (v > 128) throw( MIHTLVLengthException());
length_field() = v;
return;
case 2:
- if (v > UInt8Parser::max_value + 128) throw( TLVLengthException());
+ if (v > UInt8Parser::max_value + 128) throw( MIHTLVLengthException());
parse<UInt8Parser>(1) = v - (v>128 ? 128 : 0);
break;
case 3:
- if (v > UInt16Parser::max_value + 128) throw( TLVLengthException());
+ if (v > UInt16Parser::max_value + 128) throw( MIHTLVLengthException());
parse<UInt16Parser>(1) = v - (v>128 ? 128 : 0);
break;;
case 4:
- if (v > UInt24Parser::max_value + 128) throw( TLVLengthException());
+ if (v > UInt24Parser::max_value + 128) throw( MIHTLVLengthException());
parse<UInt24Parser>(1) = v - (v>128 ? 128 : 0);
break;
case 5:
parse<UInt32Parser>(1) = v - (v>128 ? 128 : 0);
break;
default:
- throw( TLVLengthException());
+ throw( MIHTLVLengthException());
};
underflow_flag() = (v <= 128);
}
-prefix_ senf::DynamicTLVLengthParser::value_type senf::DynamicTLVLengthParser::maxValue()
+prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::maxValue()
const
{
switch (bytes() ) {
case 5:
return UInt32Parser::max_value;
default:
- throw( TLVLengthException());
+ throw( MIHTLVLengthException());
};
}
-prefix_ senf::DynamicTLVLengthParser const & senf::DynamicTLVLengthParser::operator= (value_type other)
+prefix_ senf::MIHTLVLengthParser const & senf::MIHTLVLengthParser::operator= (value_type other)
{
value(other);
return *this;
}
-prefix_ void senf::DynamicTLVLengthParser::init() const
+prefix_ void senf::MIHTLVLengthParser::init() const
{
defaultInit();
extended_length_flag() = false;
}
-prefix_ void senf::DynamicTLVLengthParser::finalize()
+prefix_ void senf::MIHTLVLengthParser::finalize()
{
value_type v = value();
size_type b = bytes();
}
-prefix_ void senf::DynamicTLVLengthParser:: maxValue(DynamicTLVLengthParser::value_type v)
+prefix_ void senf::MIHTLVLengthParser:: maxValue(MIHTLVLengthParser::value_type v)
{
if (v <= 128)
return;
}
-prefix_ void senf::DynamicTLVLengthParser::resize(size_type size)
+prefix_ void senf::MIHTLVLengthParser::resize(size_type size)
{
value_type v = value();
size_type current_size (bytes());
- SafePacketParserWrapper<DynamicTLVLengthParser> safeThis (*this);
+ SafePacketParserWrapper<MIHTLVLengthParser> safeThis (*this);
if (current_size > size)
data().erase( i(), boost::next(i(), current_size-size));
}
-prefix_ senf::PacketInterpreterBase::range senf::GenericTLVPacketParser::value()
- const
-{
- senf::PacketData::iterator begin (boost::next(data().begin(), 1 + length_().bytes() ));
- return PacketInterpreterBase::range(
- begin, boost::next( begin, length()) );
-}
+//prefix_ senf::PacketInterpreterBase::range senf::MIHGenericTLVPacketParser::value()
+// const
+//{
+// senf::PacketData::iterator begin (boost::next(data().begin(), 1 + length_().bytes() ));
+// return PacketInterpreterBase::range(
+// begin, boost::next( begin, length()) );
+//}
-prefix_ void senf::GenericTLVPacketType::dump(packet p, std::ostream & os)
+prefix_ void senf::MIHGenericTLVPacketType::dump(packet p, std::ostream & os)
{
boost::io::ios_all_saver ias(os);
- os << "GenericTLVPacket:\n"
+ os << "MIH GenericTLV Packet:\n"
<< std::dec
<< senf::fieldName("type") << unsigned( p->type()) << "\n"
<< senf::fieldName("length") << unsigned( p->length()) << "\n"
#define prefix_ inline
///////////////////////////////cci.p////////////////////////////////////////
-prefix_ senf::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::bytes() const
+prefix_ senf::MIHTLVLengthParser::size_type senf::MIHTLVLengthParser::bytes() const
{
return 1 + ( length_field()<=128 ? 0 : fixed_length_field());
}
-prefix_ void senf::GenericTLVPacketType::finalize(packet p)
+prefix_ void senf::MIHGenericTLVPacketType::finalize(packet p)
{
p->finalizeLength();
}
+++ /dev/null
-// $Id$
-//
-// Copyright (C) 2007
-// Fraunhofer Institute for Open Communication Systems (FOKUS)
-// Competence Center NETwork research (NET), St. Augustin, GERMANY
-// Thorsten Horstmann <tho@berlios.de>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the
-// Free Software Foundation, Inc.,
-// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-/** \file
- \brief TLVPacket non-inline template implementation */
-
-//#include "TLVPacket.ih"
-
-// Custom includes
-
-#define prefix_
-///////////////////////////////ct.p////////////////////////////////////////
-
-template <class ForwardReadableRange>
-prefix_ void senf::GenericTLVPacketParser::value(ForwardReadableRange const &range)
-{
- safe_data_iterator si = resizeValueField( boost::size(range) );
- std::copy( boost::begin(range), boost::end(range), si);
-}
-
-///////////////////////////////ct.e////////////////////////////////////////
-#undef prefix_
-
-\f
-// Local Variables:
-// mode: c++
-// fill-column: 100
-// c-file-style: "senf"
-// indent-tabs-mode: nil
-// ispell-local-dictionary: "american"
-// compile-command: "scons -u test"
-// comment-column: 40
-// End:
namespace senf {
- struct TLVLengthException : public senf::Exception
+ struct MIHTLVLengthException : public senf::Exception
{
- TLVLengthException()
- : senf::Exception("TLVLengthException") {}
+ MIHTLVLengthException()
+ : senf::Exception("MIHTLVLengthException") {}
};
- class DynamicTLVLengthParser
- : public detail::packet::IntParserOps<DynamicTLVLengthParser, boost::uint32_t>,
+ class MIHTLVLengthParser
+ : public detail::packet::IntParserOps<MIHTLVLengthParser, boost::uint32_t>,
public PacketParserBase
{
public:
- DynamicTLVLengthParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
+ MIHTLVLengthParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
typedef boost::uint32_t value_type;
static const size_type init_bytes = 1;
value_type value() const;
void value(value_type const & v);
- DynamicTLVLengthParser const & operator= (value_type other);
+ MIHTLVLengthParser const & operator= (value_type other);
size_type bytes() const;
void init() const;
/** \brief Base class for TLV-Packet-Parsers
- BaseTLVPacketParser is the abstract base class for TLV-Packet-Parsers. It defines the
+ MIHBaseTLVParser is the abstract base class for TLV-Packet-Parsers. It defines the
\ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a
- DynamicTLVLengthParser. The length field is read-only.
+ MIHTLVLengthParser. The length field is read-only.
- To create your own \c TLVParser you have to inherit from BaseTLVPacketParser (don't
+ To create your own \c TLVParser you have to inherit from MIHBaseTLVParser (don't
forget \ref SENF_PARSER_INHERIT) and define the \c value field. In the following example
the value is a vector of MacAddresses:
\code
- struct MacAddressesTLVParser : public BaseTLVPacketParser {
+ struct MacAddressesTLVParser : public MIHBaseTLVParser {
# include SENF_PARSER()
- SENF_PARSER_INHERIT ( BaseTLVPacketParser );
+ SENF_PARSER_INHERIT ( MIHBaseTLVParser );
SENF_PARSER_VECTOR ( value, bytes(length), senf::MACAddressParser );
SENF_PARSER_FINALIZE( MacAddressesTLVParser );
};
example adding more than 21 MACAddresses to the vector will throw a TLVLengthException
if you don't call \c macAddressesTLVPacket->maxLengthValue( \e some_value) before.
- \see DynamicTLVLengthParser \n
- GenericTLVPacketParser \n
+ \see MIHTLVLengthParser \n
+ MIHGenericTLVPacketParser \n
*/
- class BaseTLVPacketParser : public PacketParserBase
+ class MIHBaseTLVParser : public PacketParserBase
{
public:
# include SENF_PARSER()
- SENF_PARSER_FIELD ( type, UInt8Parser );
- SENF_PARSER_FIELD_RO ( length, DynamicTLVLengthParser );
- SENF_PARSER_FINALIZE ( BaseTLVPacketParser );
+ SENF_PARSER_FIELD ( type, UInt8Parser );
+ SENF_PARSER_FIELD_RO ( length, MIHTLVLengthParser );
+ SENF_PARSER_FINALIZE ( MIHBaseTLVParser );
/** \brief set maximum value of length field
The size of the length field will be increased if necessary.
\param v maximum value of length field
*/
- void maxLengthValue(DynamicTLVLengthParser::value_type v) const {
+ void maxLengthValue(MIHTLVLengthParser::value_type v) const {
length_().maxValue(v);
}
protected:
/// resize the packet after the length field to given size
- senf::safe_data_iterator resizeValueField(DynamicTLVLengthParser::value_type size);
+ senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size);
};
/** \brief Parser for a generic TLV packet
- \see GenericTLVPacketType
+ \see MIHGenericTLVPacketType
*/
- struct GenericTLVPacketParser : public BaseTLVPacketParser
+ struct MIHGenericTLVPacketParser
+ : public GenericTLVParserBase<MIHBaseTLVParser>
{
-# include SENF_PARSER()
- SENF_PARSER_INHERIT ( BaseTLVPacketParser );
- SENF_PARSER_SKIP ( length(), 0 );
- SENF_PARSER_FINALIZE ( GenericTLVPacketParser );
-
- SENF_PARSER_INIT() {
- maxLengthValue( DynamicTLVLengthParser::max_value);
- }
-
- senf::PacketInterpreterBase::range value() const;
-
- template <class ForwardReadableRange>
- void value(ForwardReadableRange const &range);
+ typedef senf::GenericTLVParserBase<MIHBaseTLVParser> base;
+ MIHGenericTLVPacketParser(data_iterator i, state_type s) : base(i,s) {}
+
+ void init() const {
+ defaultInit();
+ maxLengthValue( MIHTLVLengthParser::max_value);
+ }
};
/** \brief Generic TLV packet
\par Packet type (typedef):
- \ref GenericTLVPacket
+ \ref MIHGenericTLVPacket
\image html TLV.png
\ingroup protocolbundle_80221
*/
- struct GenericTLVPacketType
+ struct MIHGenericTLVPacketType
: public PacketTypeBase,
- public PacketTypeMixin<GenericTLVPacketType>
+ public PacketTypeMixin<MIHGenericTLVPacketType>
{
#ifndef DOXYGEN
- typedef PacketTypeMixin<GenericTLVPacketType> mixin;
+ typedef PacketTypeMixin<MIHGenericTLVPacketType> mixin;
#endif
- typedef ConcretePacket<GenericTLVPacketType> packet; ///< GenericTLV packet typedef
- typedef GenericTLVPacketParser parser; ///< typedef to the parser of GenericTLV packet
+ typedef ConcretePacket<MIHGenericTLVPacketType> packet; ///< GenericTLV packet typedef
+ typedef MIHGenericTLVPacketParser parser; ///< typedef to the parser of GenericTLV packet
using mixin::nextPacketRange;
using mixin::init;
using mixin::initSize;
- /** \brief Dump given GenericTLVPacket in readable form to given output stream */
+ /** \brief Dump given MIHGenericTLVPacket in readable form to given output stream */
static void dump(packet p, std::ostream & os);
static void finalize(packet p); ///< Finalize packet.
/**< shrink size of length field to minimum
- \see BaseTLVPacketParser::finalizeLength() */
-
+ \see MIHBaseTLVParser::finalizeLength() */
};
/** \brief GenericTLV packet typedef
\ingroup protocolbundle_80221
*/
- typedef ConcretePacket<GenericTLVPacketType> GenericTLVPacket;
+ typedef ConcretePacket<MIHGenericTLVPacketType> MIHGenericTLVPacket;
}
///////////////////////////////hh.e////////////////////////////////////////
#include "TLVPacket.cci"
-#include "TLVPacket.ct"
+//#include "TLVPacket.ct"
//#include "TLVPacket.cti"
#endif
}
-BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_simple_length)
+BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_parse_packet_with_simple_length)
{
unsigned char data[] = {
0x01, // type
0x0A, // first bit not set, length=10
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
};
- GenericTLVPacket tlvPacket (GenericTLVPacket::create(data));
+ MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create(data));
CHECK_TLVPacket( tlvPacket, 0x01, 0x0Au );
}
-BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_extended_length)
+BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_parse_packet_with_extended_length)
{
unsigned char data[] = {
0x01, // type
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81,
0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89
};
- GenericTLVPacket tlvPacket (GenericTLVPacket::create(data));
+ MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create(data));
CHECK_TLVPacket( tlvPacket, 0x01, 0x8au );
}
-BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_simple_length)
+BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_create_packet_with_simple_length)
{
unsigned char value[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
};
- GenericTLVPacket tlvPacket (GenericTLVPacket::create());
+ MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create());
tlvPacket->type() = 42u;
tlvPacket->value( value);
tlvPacket.finalizeThis();
}
-BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_extended_length)
+BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_create_packet_with_extended_length)
{
unsigned char value[255];
for (unsigned i=0; i<sizeof(value); i++)
value[i] = i;
- GenericTLVPacket tlvPacket (GenericTLVPacket::create());
- tlvPacket->maxLengthValue( DynamicTLVLengthParser::max_value);
+ MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create());
+ tlvPacket->maxLengthValue( MIHTLVLengthParser::max_value);
SENF_CHECK_NO_THROW( tlvPacket->type() = 42u);
SENF_CHECK_NO_THROW( tlvPacket->value( value));
SENF_CHECK_NO_THROW( tlvPacket.finalizeThis());
}
-BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_invalid_packet)
+BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_create_invalid_packet)
{
- GenericTLVPacket tlvPacket (GenericTLVPacket::create());
+ MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create());
tlvPacket->type() = 42u;
tlvPacket.finalizeThis();
for (unsigned i=0; i<sizeof(value); i++)
value[i] = i;
- BOOST_CHECK_THROW( tlvPacket->value( value), TLVLengthException);
+ BOOST_CHECK_THROW( tlvPacket->value( value), MIHTLVLengthException);
tlvPacket->maxLengthValue( sizeof(value));
tlvPacket->value( value);
tlvPacket.finalizeThis();
namespace {
- struct TestMacAddressTLVPacketParser : public BaseTLVPacketParser
+ struct TestMacAddressTLVPacketParser : public MIHBaseTLVParser
{
# include SENF_PARSER()
- SENF_PARSER_INHERIT ( BaseTLVPacketParser );
+ SENF_PARSER_INHERIT ( MIHBaseTLVParser );
SENF_PARSER_VECTOR ( value, bytes(length), senf::MACAddressParser );
SENF_PARSER_FINALIZE( TestMacAddressTLVPacketParser );
};
// Custom includes
#include <senf/Packets/Packets.hh>
-#include <senf/Packets/AuxParser.hh>
#include "IPv6ExtOptionType.hh"
#include "ListOptionTypeParser.hh"
#include "IPv6Packet.hh"
prefix_ senf::PacketInterpreterBase::range senf::GenericTLVParserBase<Base>::value()
const
{
- senf::PacketData::iterator begin (boost::next(this->i(), senf::init_bytes<Base>::value ));
+ senf::PacketData::iterator begin ( boost::next(this->i(), senf::bytes( self())) );
return PacketInterpreterBase::range(begin, boost::next( begin, this->length()) );
}
prefix_ void senf::GenericTLVParserBase<Base>::value_(ForwardReadableRange const &range)
{
unsigned int rangeSize = boost::size(range);
+ std::cerr << "GenericTLVParserBase<Base>::value_() rangeSize=" <<
+ unsigned( rangeSize) << " length()=" << unsigned( this->length()) << " bytes(self)=" <<
+ unsigned( senf::bytes(self())) << " bytes()=" << unsigned( senf::bytes(*this)) << std::endl;
if ( rangeSize != this->length() )
- resize( bytes(), rangeSize + senf::init_bytes<Base>::value );
+ resize( bytes(), rangeSize + senf::bytes(self()) );
std::copy( boost::begin(range), boost::end(range), boost::next(
- this->i(), senf::init_bytes<Base>::value));
+ this->i(), senf::bytes( self())) );
this->length_() = rangeSize;
}
-
-
///////////////////////////////ct.e////////////////////////////////////////
#undef prefix_
template <class Base>
prefix_ senf::PacketParserBase::size_type senf::GenericTLVParserBase<Base>::bytes()
{
- return senf::init_bytes<Base>::value + this->length();
+ return senf::bytes(self()) + this->length();
}
template <class Base>
return this->type().value() == Parser::TYPEID;
}
+template <class Base>
+prefix_ Base & senf::GenericTLVParserBase<Base>::self()
+{
+ return *static_cast<Base *>(this);
+}
+
+template <class Base>
+prefix_ Base const & senf::GenericTLVParserBase<Base>::self()
+ const
+{
+ return *static_cast<Base const *>(this);
+}
+
#ifndef DOXYGEN
template <class Base>
\endcode
\see
- IPv6GenericOptionTLVParser, \n
- WLANGenericInfoElementParser
+ IPv6GenericOptionTLVParser, WLANGenericInfoElementParser, MIHGenericTLVPacketParser
*/
template <class Base>
class GenericTLVParserBase : public Base
private:
template<class ForwardReadableRange>
void value_(ForwardReadableRange const &range);
+
+ Base & self();
+ Base const & self() const;
};
}