\see ListParser
\ingroup parsecollection
*/
- template <class ElementParser, class BytesParser>
- struct ListBParser {
- typedef ListParser<
- detail::ListBParser_Policy< ElementParser,
- detail::PrefixAuxParserPolicy<BytesParser> > > parser;
- };
/** \brief Define ListBParser field
\hideinitializer
\ingroup packetparsermacros
*/
-# define SENF_PARSER_LIST_B(name, elt_type, size_type) \
- typedef senf::ListBParser<elt_type, size_type>::parser BOOST_PP_CAT(name, _list_t); \
- SENF_PARSER_FIELD( name, BOOST_PP_CAT(name, _list_t) )
}
///////////////////////////////hh.e////////////////////////////////////////
# include SENF_PARSER()
SENF_PARSER_PRIVATE_FIELD( size, senf::UInt8Parser );
- SENF_PARSER_VEC_N( vec, size, senf::UInt16Parser );
+ SENF_PARSER_VECTOR( vec, size, senf::UInt16Parser );
SENF_PARSER_FINALIZE(VectorParser);
};
- typedef senf::ListBParser<VectorParser,senf::UInt16Parser>::parser MyListBParser;
+ typedef senf::ListParser<
+ senf::detail::ListBParser_Policy<
+ VectorParser,
+ senf::detail::PrefixAuxParserPolicy<senf::UInt16Parser> > > MyListBParser;
}
BOOST_AUTO_UNIT_TEST(ListBParser)
\see ListParser
\ingroup parsecollection
*/
- template <class ElementParser, class SizeParser>
- struct ListNParser {
- typedef ListParser< detail::ListNParser_Policy<
- ElementParser,
- detail::PrefixAuxParserPolicy<SizeParser> > > parser;
- };
/** \brief Define ListNParser field
\hideinitializer
\ingroup packetparsermacros
*/
-# define SENF_PARSER_LIST_N(name, elt_type, size_type) \
- typedef senf::ListNParser<elt_type, size_type>::parser BOOST_PP_CAT(name, _list_t); \
- SENF_PARSER_FIELD( name, BOOST_PP_CAT(name, _list_t) )
}
///////////////////////////////hh.e////////////////////////////////////////
# include SENF_PARSER()
SENF_PARSER_PRIVATE_FIELD( size, senf::UInt8Parser );
- SENF_PARSER_VEC_N( vec, size, senf::UInt16Parser );
+ SENF_PARSER_VECTOR( vec, size, senf::UInt16Parser );
SENF_PARSER_FINALIZE(MyVec);
};
+
+ typedef senf::ListParser<
+ senf::detail::ListNParser_Policy<
+ MyVec,
+ senf::detail::PrefixAuxParserPolicy<
+ senf::UInt16Parser> > > MyListNParser;
}
BOOST_AUTO_UNIT_TEST(ListNParser_container)
{
- typedef senf::ListNParser<MyVec,senf::UInt16Parser>::parser MyListNParser;
-
VoidPacket vp (VoidPacket::create(MyListNParser::init_bytes));
MyListNParser(vp.data().begin(),&vp.data()).init();
BOOST_AUTO_UNIT_TEST(ListNParser)
{
- typedef senf::ListNParser<MyVec,senf::UInt16Parser>::parser MyListNParser;
-
VoidPacket vp (VoidPacket::create(MyListNParser::init_bytes));
{
# include SENF_PARSER()
SENF_PARSER_PRIVATE_FIELD ( num_of_fbips, UInt8Parser );
SENF_PARSER_PRIVATE_FIELD ( reserved , UInt8Parser ); //must be zero
- SENF_PARSER_VEC_N ( fbiplist, num_of_fbips, INet4AddressParser );
+ SENF_PARSER_VECTOR ( fbiplist, num_of_fbips, INet4AddressParser );
SENF_PARSER_FINALIZE(DTCPIPv4AddressListParser);
};
# include SENF_PARSER()
SENF_PARSER_PRIVATE_FIELD ( num_of_fbips, UInt8Parser );
SENF_PARSER_PRIVATE_FIELD ( reserved, UInt8Parser ); //must be zero
- SENF_PARSER_VEC_N ( fbiplist, num_of_fbips, INet6AddressParser );
+ SENF_PARSER_VECTOR ( fbiplist, num_of_fbips, INet6AddressParser );
SENF_PARSER_FINALIZE(DTCPIPv6AddressListParser);
};
*/
struct ip_version_translator {
- static unsigned fromChooser(ip_version_t::value_type in) {
+ typedef unsigned value_type;
+ static unsigned get(ip_version_t::value_type in) {
switch (in) {
case 4: return 0;
case 6: return 1;
}
return 1; //default. should rather throw an exception
}
- static ip_version_t::value_type toChooser(unsigned in) {
+ static ip_version_t::value_type set(unsigned in) {
switch (in) {
case 0: return 4;
case 1: return 6;
}
};
- SENF_PARSER_VARIANT_TRANS ( fbiplist, ip_version, ip_version_translator,
+ SENF_PARSER_VARIANT ( fbiplist, transform(ip_version_translator, ip_version),
(senf::DTCPIPv4AddressListParser) //IPv4
(senf::DTCPIPv6AddressListParser) ); //IPv6
DTCPIPv4AddressListParser getIpv4AddressList () const { return fbiplist().get<0>(); } // this is the absolute index
DTCPIPv6AddressListParser getIpv6AddressList () const { return fbiplist().get<1>(); }
+
void setIpVersion4() const { fbiplist().init<0>(); }
void setIpVersion6() const { fbiplist().init<1>(); }
#define prefix_
///////////////////////////////ct.p////////////////////////////////////////
-template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
+template <class AuxPolicy, class Parsers>
template <unsigned N>
-prefix_ void senf::VariantParser<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::init()
+prefix_ void senf::VariantParser<AuxPolicy,Parsers>::init()
{
unsigned oldSize( bytes() );
typedef typename boost::mpl::at<parsers, boost::mpl::int_<N> >::type NewParser;
std::fill(i(), j, 0u);
safe_data_iterator safe_i (*this);
data().insert(j, senf::init_bytes<NewParser>::value - oldSize, 0u);
- VariantPolicy::variant(N, safe_i, state());
- NewParser( VariantPolicy::begin(safe_i, state()), state() ).init();
+ AuxPolicy::aux(N, safe_i, state());
+ NewParser( AuxPolicy::adjust(safe_i, state()), state() ).init();
} else {
data_iterator j (i());
std::advance(j, senf::init_bytes<NewParser>::value);
data().erase(j, boost::next(i(), oldSize));
std::fill(i(), j, 0u);
- VariantPolicy::variant(N, i(), state());
- NewParser(VariantPolicy::begin(i(), state()), state()).init();
+ AuxPolicy::aux(N, i(), state());
+ NewParser(AuxPolicy::adjust(i(), state()), state()).init();
}
}
///////////////////////////////cti.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-// senf::VariantParser<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>
+// senf::VariantParser<AuxPolicy,Parsers>
-template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
-prefix_ senf::VariantParser<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::
+template <class AuxPolicy, class Parsers>
+prefix_ senf::VariantParser<AuxPolicy,Parsers>::
VariantParser(data_iterator i, state_type s)
: PacketParserBase(i,s)
{}
-template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
-prefix_ senf::VariantParser<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::
-VariantParser(VariantPolicy policy, data_iterator i, state_type s)
- : PacketParserBase(i,s), VariantPolicy(policy)
+template <class AuxPolicy, class Parsers>
+prefix_ senf::VariantParser<AuxPolicy,Parsers>::
+VariantParser(AuxPolicy policy, data_iterator i, state_type s)
+ : PacketParserBase(i,s), AuxPolicy(policy)
{}
-template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
+template <class AuxPolicy, class Parsers>
prefix_ senf::PacketParserBase::size_type
-senf::VariantParser<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::bytes()
+senf::VariantParser<AuxPolicy,Parsers>::bytes()
const
{
return detail::VariantBytes< VariantParser, boost::mpl::size<parsers>::value - 1 >
- ::bytes(*this, variant()) + VariantPolicy::bytes(i(),state());
+ ::bytes(*this, variant()) + AuxPolicy::aux_bytes;
}
-template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
+template <class AuxPolicy, class Parsers>
prefix_ void
-senf::VariantParser<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::init()
+senf::VariantParser<AuxPolicy,Parsers>::init()
{
- VariantPolicy::variant(0,i(),state());
+ AuxPolicy::aux(0,i(),state());
get<0>().init();
}
-template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
-prefix_ unsigned senf::VariantParser<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::variant()
+template <class AuxPolicy, class Parsers>
+prefix_ unsigned senf::VariantParser<AuxPolicy,Parsers>::variant()
const
{
- return VariantPolicy::variant(i(),state());
+ return AuxPolicy::aux(i(),state());
}
-template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
+template <class AuxPolicy, class Parsers>
template <unsigned N>
prefix_ typename boost::mpl::at<
- typename senf::VariantParser<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::parsers,
+ typename senf::VariantParser<AuxPolicy,Parsers>::parsers,
boost::mpl::int_<N> >::type
-senf::VariantParser<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::get()
+senf::VariantParser<AuxPolicy,Parsers>::get()
const
{
SENF_ASSERT( variant() == N );
return typename boost::mpl::at<parsers, boost::mpl::int_<N> >::type(
- VariantPolicy::begin(i(), state()), state() );
+ AuxPolicy::adjust(i(), state()), state() );
}
/////////////////////////////////////////////////////////////////////////
#include "PacketParser.hh"
//#include "VariantParser.mpp"
-#include "VariantParser.ih"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
packet change depending on some condition.
\code
typedef senf::VariantParser<
- MyVariantPolicy,
+ MyAuxPolicy,
senf::VoidPacketParser, TypeAParser, TypeBParser> MyVariantParser;
\endcode
This typedef defines a variant parser choosing one of three sub
initialized to the first sub-parser.
\see
- ExampleVariantPolicy on how to implement the \a VariantPolicy \n
+ ExampleAuxPolicy on how to implement the \a AuxPolicy \n
\ref SENF_PARSER_VARIANT() on how to integrate the parser into another parser
\ingroup parsecollection
*/
- template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
+ template <class AuxPolicy, class Parsers>
class VariantParser
- : public PacketParserBase, private VariantPolicy
+ : public PacketParserBase, private AuxPolicy
{
- typedef boost::mpl::vector< SENF_PARSE_VARIANT_TPL_ARGS(P) > parsers;
+ typedef Parsers parsers;
public:
///\name Parser interface
///\{
VariantParser(data_iterator i, state_type s);
- VariantParser(VariantPolicy policy, data_iterator i, state_type s);
+ VariantParser(AuxPolicy policy, data_iterator i, state_type s);
size_type bytes() const;
void init();
- static const size_type init_bytes =
- senf::init_bytes<P0>::value + VariantPolicy::init_bytes;
+ static const size_type init_bytes = senf::init_bytes<
+ typename boost::mpl::at<parsers, boost::mpl::int_<0> >::type>::value
+ + AuxPolicy::aux_bytes;
///\}
///////////////////////////////////////////////////////////////////////////
\post variant() == \a N */
};
- /** \brief Variant with direct, fixed distance type field
-
- This struct is a template typedef defining a senf::Parser_Variant instantiation. It defines
- a variant parser which interprets the value returned by some other parser directly as index
- into the list of sub parsers (the numeric template argument to senf::VariantParser::get()
- and senf::Parser_Variant::init()).
-
- \code
- // Define a variant choosing between FooParser and BarParser depending on the directly
- // preceding 1-byte 8bit uint value
- typedef senf::DirectVariantParser< senf::UInt8Parser, 1u,
- FooParser, BarParser >::parser MyVariant;
- \endcode
-
- \a ChooserType defines the type of the field used to choose the sub parser. This must be a
- fixed-size value parser. \a Distance gives the \e fixed distance of this field \e before the
- currently defined field.
-
- It is best to define a field of this type using \ref SENF_PARSER_VARIANT() or \ref
- SENF_PARSER_PRIVATE_VARIANT().
-
- \param[in] ChooserType type of chooser field (a value parser)
- \param[in] Distance fixed distance of the chooser field before the current field
- \param[in] P any number of sub parsers
-
- \see senf::Parser_Variant
- \ingroup parsecollection
- */
- template <class ChooserType, unsigned Distance, class Translator,
- SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
- struct DirectVariantParser
- {
- typedef VariantParser< detail::DirectVariantParser<ChooserType, Distance, Translator>,
- SENF_PARSE_VARIANT_TPL_ARGS(P) > parser;
- };
-
/** \brief Define DirectVariantParser field
This macro is a special helper to define a senf::DirectVariantParser type field. This is a
\hideinitializer
\ingroup packetparsermacros
*/
-# define SENF_PARSER_VARIANT(name, chooser, types) \
- SENF_PARSER_VARIANT_I(SENF_PARSER_FIELD, \
- name, \
- chooser, \
- senf::detail::VariantParser_IdentityTranslator, \
- types)
+# define SENF_PARSER_VARIANT(name, chooser, types) \
+ SENF_PARSER_VARIANT_I(public, name, chooser, types)
/** \brief Define DirectVariantParser field (private)
\hideinitializer
\ingroup packetparsermacros
*/
-# define SENF_PARSER_PRIVATE_VARIANT(name, chooser, types) \
- SENF_PARSER_VARIANT_I(SENF_PARSER_PRIVATE_FIELD, \
- name, \
- chooser, \
- senf::detail::VariantParser_IdentityTranslator, \
- types)
+# define SENF_PARSER_PRIVATE_VARIANT(name, chooser, types) \
+ SENF_PARSER_VARIANT_I(private, name, chooser, types)
/** \brief Define DirectVariantParser field with translator
\hideinitializer
\ingroup packetparsermacros
*/
-# define SENF_PARSER_VARIANT_TRANS(name, chooser, translator, types) \
- SENF_PARSER_VARIANT_I(SENF_PARSER_FIELD, \
- name, \
- chooser, \
- translator, \
- types)
-
- /** \brief Define DirectVariantParser field with translator (private)
-
- \see \ref SENF_PARSER_VARIANT_TRANS()
- \hideinitializer
- \ingroup packetparsermacros
- */
-# define SENF_PARSER_PRIVATE_VARIANT_TRANS(name, chooser, types) \
- SENF_PARSER_VARIANT_I(SENF_PARSER_PRIVATE_FIELD, \
- name, \
- chooser, \
- translator, \
- types)
+
}
// Custom includes
#include "PacketParser.hh"
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/seq/enum.hpp>
///////////////////////////////ih.p////////////////////////////////////////
namespace senf {
namespace detail {
-# define SENF_PARSE_VARIANT_TPL_ARGS_DFL(n) \
- BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SENF_LIMIT_PARSE_VARIANT, \
- n, \
- boost::mpl::na )
-
-# define SENF_PARSE_VARIANT_TPL_ARGS(n) BOOST_PP_ENUM_PARAMS( SENF_LIMIT_PARSE_VARIANT, n )
-
# ifndef DOXYGEN
template <class Variant, unsigned N>
# endif
- /** \brief Internal: Variant Policy used by senf::DirectVariantParser */
- template <class ChooserType, unsigned Distance, class Translator>
- struct DirectVariantParser
+ template <class AuxPolicy, class AuxTag>
+ struct VariantParserPolicy {};
+
+ template <class AuxPolicy>
+ struct VariantParserPolicy<AuxPolicy, senf::detail::auxtag::none>
{
- typedef PacketParserBase::data_iterator data_iterator;
- typedef PacketParserBase::state_type state_type;
- typedef PacketParserBase::size_type size_type;
-
- static size_type const init_bytes = 0;
- size_type bytes(data_iterator i, state_type s) const { return 0; }
- data_iterator begin(data_iterator i, state_type s) const { return i; }
-
- ChooserType chooser(data_iterator i, state_type s) const {
- return ChooserType(boost::prior(i, Distance),s);
- }
-
- unsigned variant(data_iterator i, state_type s) const {
- return Translator::fromChooser(chooser(i,s).value());
- }
-
- void variant(unsigned v, data_iterator i, state_type s) {
- chooser(i,s).value(Translator::toChooser(v));
- }
+ typedef AuxPolicy type;
};
- /** \brief Internal: Identity chooser translator */
- struct VariantParser_IdentityTranslator {
- static unsigned fromChooser(unsigned value) { return value; }
- static unsigned toChooser(unsigned value) { return value; }
- };
-# define SENF_PARSER_VARIANT_(r, data, elem) ,elem
+ template <class AuxPolicy, class Transform>
+ struct VariantParserPolicy<AuxPolicy,
+ senf::detail::auxtag::transform<Transform,
+ senf::detail::auxtag::none> >
+ {
+ typedef TransformAuxParserPolicy<AuxPolicy, Transform> type;
+ };
-# define SENF_PARSER_VARIANT_I(field, name, chooser, translator, types) \
- typedef senf::DirectVariantParser< \
- BOOST_PP_CAT(chooser, _t), \
- SENF_PARSER_CURRENT_FIXED_OFFSET() - SENF_PARSER_FIXED_OFFSET(chooser), \
- translator \
- BOOST_PP_SEQ_FOR_EACH( SENF_PARSER_VARIANT_, _, types ) \
- >::parser BOOST_PP_CAT(name, _variant_t); \
- field( name, BOOST_PP_CAT(name, _variant_t) )
+ template <class Parsers>
+ struct VariantParserTraits
+ {
+ template <class AuxPolicy, class AuxTag>
+ struct parser {
+ typedef senf::VariantParser<
+ typename VariantParserPolicy<AuxPolicy, AuxTag>::type,
+ Parsers> type;
+ };
+ };
+
+# define SENF_PARSER_VARIANT_I(access, name, chooser, types) \
+ typedef boost::mpl::vector< BOOST_PP_SEQ_ENUM(types) > BOOST_PP_CAT(name, _parsers); \
+ SENF_PARSER_REQUIRE_VAR(variant) \
+ SENF_PARSER_COLLECTION_I( \
+ access, \
+ name, \
+ chooser, \
+ senf::detail::VariantParserTraits< BOOST_PP_CAT(name, _parsers) > )
}}
BOOST_AUTO_UNIT_TEST(VariantParser)
{
typedef senf::ArrayParser<10, senf::UInt8Parser> Array10;
- typedef senf::DirectVariantParser< senf::UInt8Parser, 1, senf::detail::VariantParser_IdentityTranslator,
- senf::VoidPacketParser,
- Array10,
- senf:: UInt32Parser
- >::parser Variant;
+ typedef senf::VariantParser< senf::detail::FixedAuxParserPolicy<senf::UInt8Parser, 1>,
+ boost::mpl::vector<senf::VoidPacketParser, Array10, senf:: UInt32Parser> > Variant;
unsigned char data[] = { 0x01, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0x1A, 0x1B };
struct TestParser : public senf::PacketParserBase
{
# include SENF_PARSER()
+
+ struct TestTransform {
+ typedef unsigned value_type;
+ static unsigned get(unsigned v) { return v/2; }
+ static unsigned set(unsigned v) { return 2*v; }
+ };
SENF_PARSER_SKIP_BITS( 4 );
- SENF_PARSER_PRIVATE_BITFIELD( type_, 4, unsigned );
- SENF_PARSER_PRIVATE_VARIANT( content_, type_, (senf::VoidPacketParser)(SubParser) );
+ SENF_PARSER_BITFIELD_RO( type, 4, unsigned );
+ SENF_PARSER_PRIVATE_VARIANT( content_, transform(TestTransform, type),
+ (senf::VoidPacketParser)(SubParser) );
bool hasContent() const { return content_().variant() == 1; }
void hasContent(bool v) const { if (v) content_().init<1>(); else content_().init<0>(); }
{
TestParser v (p.data().begin(), & p.data());
-
BOOST_CHECK( ! v.hasContent() );
BOOST_CHECK_EQUAL( senf::bytes(v), 1u );
+ BOOST_CHECK_EQUAL( v.type(), 0u );
v.hasContent(true);
// Parser invalidated
}
BOOST_CHECK( v.hasContent() );
BOOST_CHECK_EQUAL( senf::bytes(v), 7u );
BOOST_CHECK_EQUAL( v.content().foo(), 0u );
+ BOOST_CHECK_EQUAL( v.type(), 2u );
}
}
\hideinitializer
\ingroup packetparsermacros
*/
-# define SENF_PARSER_VEC_N(name, size, elt_type) \
- SENF_PARSER_VEC_N_I(SENF_PARSER_FIELD, name, size, elt_type)
/** \brief Define VectorNParser field
\hideinitializer
\ingroup packetparsermacros
*/
-# define SENF_PARSER_PRIVATE_VEC_N(name, size, elt_type) \
- SENF_PARSER_VEC_N_I(SENF_PARSER_PRIVATE_FIELD, name, size, elt_type)
# define SENF_PARSER_VECTOR(name, size, elt_type) \
SENF_PARSER_VECTOR_I(public, name, size, elt_type)
namespace senf {
namespace detail {
-# define SENF_PARSER_VEC_N_I(field, name, size, elt_type) \
- typedef senf::VectorParser< \
- elt_type, \
- senf::detail::FixedAuxParserPolicy< BOOST_PP_CAT(size, _t), \
- SENF_PARSER_CURRENT_FIXED_OFFSET() \
- - SENF_PARSER_FIXED_OFFSET(size) > \
- > BOOST_PP_CAT(name, _vec_t); \
- field( name, BOOST_PP_CAT(name, _vec_t) )
-
template <class ElementParser, class AuxPolicy, class AuxTag>
struct VectorParserPolicy
{};