\hideinitializer
*/
-#define SENF_PARSER_INIT() void init(int)
+#define SENF_PARSER_INIT() void init(int) const
#ifdef DOXYGEN
SENF_MPL_SLOT_DEF_ZERO(offset); \
SENF_MPL_SLOT_DEF_ZERO(bit); \
SENF_MPL_SLOT_DEF_ZERO(bitfield_size); \
- void init_chain(senf::mpl::rv<0>*) {} \
+ void init_chain(senf::mpl::rv<0>*) const {} \
public:
#
# define SENF_PARSER_INITIALIZE_var() \
SENF_MPL_SLOT_DEF_ZERO(init_bytes); \
SENF_MPL_SLOT_DEF_ZERO(bit); \
SENF_MPL_SLOT_DEF_ZERO(bitfield_size); \
- void init_chain(senf::mpl::rv<0>*) {} \
+ void init_chain(senf::mpl::rv<0>*) const {} \
size_type field_offset_(senf::mpl::rv<0>*) const { return 0; } \
public:
#
size_type field_offset_(senf::mpl::rv<1>*) const { \
return senf::bytes( *static_cast<name const*>(this) ); \
} \
- void init_chain(senf::mpl::rv<1>*) { \
+ void init_chain(senf::mpl::rv<1>*) const { \
name::init(); \
} \
public:
private: \
SENF_MPL_SLOT_SET(offset, name::fixed_bytes); \
SENF_MPL_SLOT_SET(index, 1); \
- void init_chain(senf::mpl::rv<1>*) { \
+ void init_chain(senf::mpl::rv<1>*) const { \
name::init(); \
} \
public:
#
# define SENF_PARSER_I_FIELD_INIT_rw(name, type, access) \
private: \
- void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) { \
+ void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const { \
init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0)); \
name().init(); \
} \
#
# define SENF_PARSER_I_FIELD_INIT_ro(name, type, access) \
private: \
- void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) { \
+ void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const { \
init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0)); \
} \
access:
static size_type const fixed_bytes = SENF_MPL_SLOT_GET(offset);
#
# define SENF_PARSER_FINALIZE_GENERIC(name) \
- void defaultInit() { \
+ void defaultInit() const { \
init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0)); \
} \
name(data_iterator i, state_type s) : parser_base_type(i,s) {} \
private: \
- template <class T> void init(T) { defaultInit(); } \
+ template <class T> void init(T) const { defaultInit(); } \
public: \
- void init() { init(0); }
+ void init() const { init(0); }
#
# ////////////////////////////////ih.e///////////////////////////////////////
# endif
struct VoidPacket : public senf::PacketTypeBase
{};
- typedef senf::Parse_VectorN<senf::Parse_UInt16,senf::Parse_UInt8>::parser ParseVec;
+ struct ParseVec : public senf::PacketParserBase
+ {
+# include SENF_PARSER()
+
+ SENF_PARSER_PRIVATE_FIELD( size, senf::Parse_UInt8 );
+ SENF_PARSER_VEC_N( vec, size, senf::Parse_UInt16 );
+
+ SENF_PARSER_FINALIZE(ParseVec);
+ };
+
typedef senf::Parse_ListB<ParseVec,senf::Parse_UInt16>::parser ParseList;
}
BOOST_CHECK_EQUAL( c.size(), 1u );
BOOST_CHECK_EQUAL( c.bytes(), 3u );
- BOOST_CHECK_EQUAL( c.front().size(), 0u );
- c.front().push_back(0x1234u);
+ BOOST_CHECK_EQUAL( c.front().vec().size(), 0u );
+ c.front().vec().push_back(0x1234u);
BOOST_CHECK_EQUAL( c.bytes(), 5u );
{
ParseList::container c2 (ParseList(pi2->data().begin(),&pi2->data()));
c2.push_back_space();
{
- ParseVec::container c2v (c2.front());
+ ParseVec::vec_t::container c2v (c2.front().vec());
c2v.push_back(0x2345u);
c2v.push_back(0x3456u);
}
c.insert(c.end(),c2.back());
BOOST_CHECK_EQUAL( c.size(), 2u );
BOOST_CHECK_EQUAL( c.bytes(), 10u );
- BOOST_CHECK_EQUAL( c.back()[0], 0x2345u );
+ BOOST_CHECK_EQUAL( c.back().vec()[0], 0x2345u );
BOOST_CHECK_EQUAL( c.back().bytes(), c2.back().bytes() );
- c2.back()[0] << 0x1357u;
+ c2.back().vec()[0] << 0x1357u;
c.insert(boost::next(c.begin()), 2u, c2.back());
BOOST_CHECK_EQUAL( c.size(), 4u );
BOOST_CHECK_EQUAL( c.bytes(), 20u );
- BOOST_CHECK_EQUAL( (*boost::next(c.begin()))[0], 0x1357u );
- BOOST_CHECK_EQUAL( (*boost::next(c.begin(),2))[0], 0x1357u );
+ BOOST_CHECK_EQUAL( (*boost::next(c.begin())).vec()[0], 0x1357u );
+ BOOST_CHECK_EQUAL( (*boost::next(c.begin(),2)).vec()[0], 0x1357u );
- c2.back()[0] << 0x2468u;
+ c2.back().vec()[0] << 0x2468u;
c.insert(c.begin(),c2.begin(),c2.end());
BOOST_CHECK_EQUAL( c.size(), 5u );
BOOST_CHECK_EQUAL( c.bytes(), 25u );
- BOOST_CHECK_EQUAL( c.front()[0], 0x2468u );
+ BOOST_CHECK_EQUAL( c.front().vec()[0], 0x2468u );
c.erase(c.begin(),2);
BOOST_CHECK_EQUAL( c.size(), 3u );
BOOST_CHECK_EQUAL( c.bytes(), 17u );
- BOOST_CHECK_EQUAL( c.front()[0],0x1357u );
- BOOST_CHECK_EQUAL( c.back()[0], 0x2345u );
+ BOOST_CHECK_EQUAL( c.front().vec()[0],0x1357u );
+ BOOST_CHECK_EQUAL( c.back().vec()[0], 0x2345u );
c.erase((boost::next(c.begin(),2)),c.end());
BOOST_CHECK_EQUAL( c.size(), 2u );
BOOST_CHECK_EQUAL( c.bytes(), 12u );
- BOOST_CHECK_EQUAL( c.front()[0],0x1357u );
- BOOST_CHECK_EQUAL( c.back()[0], 0x1357u );
+ BOOST_CHECK_EQUAL( c.front().vec()[0],0x1357u );
+ BOOST_CHECK_EQUAL( c.back().vec()[0], 0x1357u );
c.clear();
BOOST_CHECK_EQUAL( c.size(), 0u );
struct VoidPacket_Type : public senf::PacketTypeBase
{};
typedef senf::ConcretePacket<VoidPacket_Type> VoidPacket;
+
+ struct MyVec : public senf::PacketParserBase
+ {
+# include SENF_PARSER()
+
+ SENF_PARSER_PRIVATE_FIELD( size, senf::Parse_UInt8 );
+ SENF_PARSER_VEC_N( vec, size, senf::Parse_UInt16 );
+
+ SENF_PARSER_FINALIZE(MyVec);
+ };
}
BOOST_AUTO_UNIT_TEST(parseListN)
{
- typedef senf::Parse_VectorN<senf::Parse_UInt16,senf::Parse_UInt8>::parser ParseVec;
- typedef senf::Parse_ListN<ParseVec,senf::Parse_UInt16>::parser ParseList;
+ typedef senf::Parse_ListN<MyVec,senf::Parse_UInt16>::parser ParseList;
VoidPacket vp (VoidPacket::create(ParseList::init_bytes));
BOOST_CHECK_EQUAL( p.bytes(), 3u );
BOOST_CHECK_EQUAL( p.size(), 1u );
BOOST_CHECK_EQUAL( p.front().bytes(), 1u );
- BOOST_CHECK_EQUAL( p.front().size(), 0u );
+ BOOST_CHECK_EQUAL( p.front().vec().size(), 0u );
BOOST_CHECK_EQUAL( vp.data()[1], 0x01u );
- p.front().push_back(0x1234u);
- BOOST_CHECK_EQUAL( p.front().size(), 1u );
+ p.front().vec().push_back(0x1234u);
+ BOOST_CHECK_EQUAL( p.front().vec().size(), 1u );
BOOST_CHECK_EQUAL( p.front().bytes(), 3u );
- BOOST_CHECK_EQUAL( p.front()[0], 0x1234u );
+ BOOST_CHECK_EQUAL( p.front().vec()[0], 0x1234u );
BOOST_CHECK_EQUAL( p.size(), 1u );
BOOST_CHECK_EQUAL( p.bytes(), 5u );
- p.front().push_back(0x2345u);
- BOOST_CHECK_EQUAL( p.front().back(), 0x2345u );
+ p.front().vec().push_back(0x2345u);
+ BOOST_CHECK_EQUAL( p.front().vec().back(), 0x2345u );
BOOST_CHECK_EQUAL( p.bytes(), 7u );
p.push_back_space();
BOOST_CHECK_EQUAL( p.size(), 2u );
BOOST_CHECK_EQUAL( p.bytes(), 8u );
- p.back().push_front(0x0123u);
- BOOST_CHECK_EQUAL( p.front().size(), 2u );
- BOOST_CHECK_EQUAL( p.back().size(), 1u );
+ p.back().vec().push_front(0x0123u);
+ BOOST_CHECK_EQUAL( p.front().vec().size(), 2u );
+ BOOST_CHECK_EQUAL( p.back().vec().size(), 1u );
p.push_front_space(2u);
BOOST_CHECK_EQUAL( p.size(), 4u );
- BOOST_CHECK_EQUAL( p.front().size(), 0u);
+ BOOST_CHECK_EQUAL( p.front().vec().size(), 0u);
p.resize(3u);
BOOST_CHECK_EQUAL( p.size(), 3u );
- BOOST_CHECK_EQUAL( p.back()[0], 0x1234u );
+ BOOST_CHECK_EQUAL( p.back().vec()[0], 0x1234u );
BOOST_CHECK_EQUAL( p.bytes(), 9u );
# undef p
BOOST_AUTO_UNIT_TEST(parseListN_container)
{
- typedef senf::Parse_VectorN<senf::Parse_UInt16,senf::Parse_UInt8>::parser ParseVec;
- typedef senf::Parse_ListN<ParseVec,senf::Parse_UInt16>::parser ParseList;
+ typedef senf::Parse_ListN<MyVec,senf::Parse_UInt16>::parser ParseList;
VoidPacket vp (VoidPacket::create(ParseList::init_bytes));
///////////////////////////////////////////////////////////////////////////
// senf::SimpleSizeParser<SizeParser,offset>
-template <class SizeParser>
-prefix_ typename senf::detail::Parse_VectorN_Sizer<SizeParser>::size_type
-senf::detail::Parse_VectorN_Sizer<SizeParser>::size(iterator i, state_type s)
+template <class SizeParser, unsigned Distance>
+prefix_ typename senf::detail::Parse_VectorN_Sizer<SizeParser,Distance>::size_type
+senf::detail::Parse_VectorN_Sizer<SizeParser,Distance>::size(iterator i, state_type s)
const
{
- return SizeParser(i,s).value();
+ return SizeParser(boost::prior(i, Distance), s).value();
}
-template <class SizeParser>
-prefix_ void senf::detail::Parse_VectorN_Sizer<SizeParser>::size(iterator i, state_type s,
- size_type v)
+template <class SizeParser, unsigned Distance>
+prefix_ void senf::detail::Parse_VectorN_Sizer<SizeParser,Distance>::size(iterator i,
+ state_type s,
+ size_type v)
const
{
- SizeParser(i,s).value(v);
+ SizeParser(boost::prior(i, Distance), s).value(v);
}
-template <class SizeParser>
-prefix_ typename senf::detail::Parse_VectorN_Sizer<SizeParser>::iterator
-senf::detail::Parse_VectorN_Sizer<SizeParser>::begin(iterator i, state_type s)
+template <class SizeParser, unsigned Distance>
+prefix_ typename senf::detail::Parse_VectorN_Sizer<SizeParser,Distance>::iterator
+senf::detail::Parse_VectorN_Sizer<SizeParser,Distance>::begin(iterator i, state_type s)
const
{
- return boost::next(i,SizeParser::fixed_bytes);
+ return i;
}
-template <class SizeParser>
-prefix_ typename senf::detail::Parse_VectorN_Sizer<SizeParser>::size_type
-senf::detail::Parse_VectorN_Sizer<SizeParser>::bytes(iterator i, state_type s)
+template <class SizeParser, unsigned Distance>
+prefix_ typename senf::detail::Parse_VectorN_Sizer<SizeParser,Distance>::size_type
+senf::detail::Parse_VectorN_Sizer<SizeParser,Distance>::bytes(iterator i, state_type s)
const
{
- return SizeParser::fixed_bytes;
+ return 0;
}
-template <class SizeParser>
-prefix_ void senf::detail::Parse_VectorN_Sizer<SizeParser>::init(iterator i, state_type s)
+template <class SizeParser, unsigned Distance>
+prefix_ void senf::detail::Parse_VectorN_Sizer<SizeParser,Distance>::init(iterator i,
+ state_type s)
const
{}
#include "ParseArray.hh" // for Parse_Array_iterator
//#include "ParseVec.mpp"
+#include "ParseVec.ih"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
friend class Parse_Vector_Container<ElementParser,Sizer>;
};
- namespace detail { template <class SizeParser> class Parse_VectorN_Sizer; }
-
/** \brief Vector with prefix sizing
This is a 'template typedef'. It defines a vector with a <em>directly preceding</em> size
\see Parse_Vector
\ingroup parsecollection
*/
- template <class ElementParser, class SizeParser>
+ template <class ElementParser, class SizeParser, unsigned Distance>
struct Parse_VectorN
{
typedef Parse_Vector< ElementParser,
- detail::Parse_VectorN_Sizer<SizeParser> > parser;
+ detail::Parse_VectorN_Sizer<SizeParser, Distance> > parser;
};
/** \brief Define Parse_VectorN field
This macro is a special helper to define a senf::Parse_VectorN type field, a vector of
- elements of type \a elt_type (a parser) directly preceded by a numeric size field of type \a
- size_type (another parser).
+ elements of type \a elt_type (a parser) which size is given by the \a size field.
+
+ \code
+ // The size field should be declared private (size is accessible via the vector)
+ SENF_PARSER_PRIVATE_FIELD ( vec_size_, senf::Parse_UInt16 );
+ // Define the vector, here it has 32bit unsigned integer elements
+ SENF_PARSER_VEC_N ( vec, _vec_size, senf::Parse_UInt32 );
+ \endcode
\param[in] name field name
+ \param[in] size name of field giving the vector size
\param[in] elt_type vector element type
- \param[in] size_type size type
\hideinitializer
\ingroup packetparsermacros
*/
-# define SENF_PARSER_VEC_N(name, elt_type, size_type) \
- typedef senf::Parse_VectorN<elt_type, size_type>::parser BOOST_PP_CAT(name, _vec_t); \
- SENF_PARSER_FIELD( name, BOOST_PP_CAT(name, _vec_t) )
+# define SENF_PARSER_VEC_N(name, size, elt_type) \
+ SENF_PARSER_VEC_N_I(SENF_PARSER_FIELD, name, size, elt_type)
+
+ /** \brief Define Parse_VectorN field
+
+ \see \ref SENF_PARSER_VEC_N()
+ \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)
/** \brief Parse_Vector container wrapper
This is the sizer policy used by Parse_VectorN
*/
- template <class SizeParser>
+ template <class SizeParser, unsigned Distance>
struct Parse_VectorN_Sizer
{
typedef PacketParserBase::size_type size_type;
typedef PacketParserBase::data_iterator iterator;
typedef PacketParserBase::state_type state_type;
- static const size_type init_bytes = SizeParser::fixed_bytes;
+ static const size_type init_bytes = 0;
size_type size (iterator i, state_type s) const;
void size (iterator i, state_type s, size_type v) const;
void init (iterator i, state_type s) const;
};
+# define SENF_PARSER_VEC_N_I(field, name, size, elt_type) \
+ typedef senf::Parse_VectorN< elt_type, \
+ BOOST_PP_CAT(size, _t), \
+ SENF_PARSER_CURRENT_FIXED_OFFSET() \
+ - SENF_PARSER_FIXED_OFFSET(size) \
+ >::parser BOOST_PP_CAT(name, _vec_t); \
+ field( name, BOOST_PP_CAT(name, _vec_t) )
+
}}
///////////////////////////////ih.e////////////////////////////////////////
senf::PacketInterpreterBase::ptr p (senf::PacketInterpreter<VoidPacket>::create(data));
typedef senf::Parse_Vector<
senf::Parse_UInt16,
- senf::detail::Parse_VectorN_Sizer<senf::Parse_UInt8>
+ senf::detail::Parse_VectorN_Sizer<senf::Parse_UInt8, 1u>
> Parse_UInt16Vec;
{
- Parse_UInt16Vec v (p->data().begin(), &p->data());
+ Parse_UInt16Vec v (boost::next(p->data().begin(), 1), &p->data());
BOOST_CHECK_EQUAL( v[0], 0x1011 );
BOOST_CHECK_EQUAL( v[2], 0x1415 );
BOOST_CHECK_EQUAL( v.size(), 3u );
- BOOST_CHECK_EQUAL( v.bytes(), 7u );
+ BOOST_CHECK_EQUAL( v.bytes(), 6u );
BOOST_CHECK( ! v.empty() );
p->data()[0] = 0x06;
BOOST_CHECK_EQUAL( v.size(), 6u );
- BOOST_CHECK_EQUAL( v.bytes(), 13u );
+ BOOST_CHECK_EQUAL( v.bytes(), 12u );
Parse_UInt16Vec::iterator b (v.begin());
Parse_UInt16Vec::iterator e (v.end());
// we don't need to check them again below ...
{
-# define v Parse_UInt16Vec(p->data().begin(),&p->data())
+# define v Parse_UInt16Vec(boost::next(p->data().begin(),1),&p->data())
v.push_back(0xf0f1u,2);
BOOST_CHECK_EQUAL( v.size(), 8u );
senf::PacketInterpreterBase::ptr p (senf::PacketInterpreter<VoidPacket>::create(data));
typedef senf::Parse_Vector<
senf::Parse_UInt16,
- senf::detail::Parse_VectorN_Sizer<senf::Parse_UInt8>
+ senf::detail::Parse_VectorN_Sizer<senf::Parse_UInt8, 1u>
> Parse_UInt16Vec;
- Parse_UInt16Vec v (p->data().begin(), &p->data());
+ Parse_UInt16Vec v (boost::next(p->data().begin(),1), &p->data());
Parse_UInt16Vec::container w (v);
BOOST_CHECK_EQUAL( w[0], 0x1011 );