From: g0dil Date: Thu, 22 Nov 2007 15:39:50 +0000 (+0000) Subject: Packets: Change Parse_VectorN sizer to to allow explicitly specifying the size field... X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=ebf9f1adf49a577805c1f2f930a01ed8aeacd2fe;p=senf.git Packets: Change Parse_VectorN sizer to to allow explicitly specifying the size field offset git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@525 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Packets/ParseHelpers.hh b/Packets/ParseHelpers.hh index c3e2ab4..a5d761e 100644 --- a/Packets/ParseHelpers.hh +++ b/Packets/ParseHelpers.hh @@ -338,7 +338,7 @@ \hideinitializer */ -#define SENF_PARSER_INIT() void init(int) +#define SENF_PARSER_INIT() void init(int) const #ifdef DOXYGEN diff --git a/Packets/ParseHelpers.ih b/Packets/ParseHelpers.ih index b55c9a4..38595ed 100644 --- a/Packets/ParseHelpers.ih +++ b/Packets/ParseHelpers.ih @@ -41,7 +41,7 @@ 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() \ @@ -50,7 +50,7 @@ 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: # @@ -65,7 +65,7 @@ size_type field_offset_(senf::mpl::rv<1>*) const { \ return senf::bytes( *static_cast(this) ); \ } \ - void init_chain(senf::mpl::rv<1>*) { \ + void init_chain(senf::mpl::rv<1>*) const { \ name::init(); \ } \ public: @@ -75,7 +75,7 @@ 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: @@ -123,7 +123,7 @@ # # define SENF_PARSER_I_FIELD_INIT_rw(name, type, access) \ private: \ - void init_chain(senf::mpl::rv*) { \ + void init_chain(senf::mpl::rv*) const { \ init_chain(static_cast*>(0)); \ name().init(); \ } \ @@ -131,7 +131,7 @@ # # define SENF_PARSER_I_FIELD_INIT_ro(name, type, access) \ private: \ - void init_chain(senf::mpl::rv*) { \ + void init_chain(senf::mpl::rv*) const { \ init_chain(static_cast*>(0)); \ } \ access: @@ -394,14 +394,14 @@ 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*>(0)); \ } \ name(data_iterator i, state_type s) : parser_base_type(i,s) {} \ private: \ - template void init(T) { defaultInit(); } \ + template void init(T) const { defaultInit(); } \ public: \ - void init() { init(0); } + void init() const { init(0); } # # ////////////////////////////////ih.e/////////////////////////////////////// # endif diff --git a/Packets/ParseListB.test.cc b/Packets/ParseListB.test.cc index a3d5fc1..464717a 100644 --- a/Packets/ParseListB.test.cc +++ b/Packets/ParseListB.test.cc @@ -37,7 +37,16 @@ namespace { struct VoidPacket : public senf::PacketTypeBase {}; - typedef senf::Parse_VectorN::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::parser ParseList; } @@ -80,8 +89,8 @@ BOOST_AUTO_UNIT_TEST(parseListB_container) 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 ); { @@ -90,7 +99,7 @@ BOOST_AUTO_UNIT_TEST(parseListB_container) 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); } @@ -101,33 +110,33 @@ BOOST_AUTO_UNIT_TEST(parseListB_container) 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 ); diff --git a/Packets/ParseListN.test.cc b/Packets/ParseListN.test.cc index 1e8c56f..7decaa3 100644 --- a/Packets/ParseListN.test.cc +++ b/Packets/ParseListN.test.cc @@ -37,12 +37,21 @@ namespace { struct VoidPacket_Type : public senf::PacketTypeBase {}; typedef senf::ConcretePacket 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::parser ParseVec; - typedef senf::Parse_ListN::parser ParseList; + typedef senf::Parse_ListN::parser ParseList; VoidPacket vp (VoidPacket::create(ParseList::init_bytes)); @@ -62,35 +71,35 @@ BOOST_AUTO_UNIT_TEST(parseListN) 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 @@ -99,8 +108,7 @@ BOOST_AUTO_UNIT_TEST(parseListN) BOOST_AUTO_UNIT_TEST(parseListN_container) { - typedef senf::Parse_VectorN::parser ParseVec; - typedef senf::Parse_ListN::parser ParseList; + typedef senf::Parse_ListN::parser ParseList; VoidPacket vp (VoidPacket::create(ParseList::init_bytes)); diff --git a/Packets/ParseVec.cti b/Packets/ParseVec.cti index 14ac2d6..962ded0 100644 --- a/Packets/ParseVec.cti +++ b/Packets/ParseVec.cti @@ -165,40 +165,42 @@ prefix_ void senf::Parse_Vector::resize(size_type n, Value /////////////////////////////////////////////////////////////////////////// // senf::SimpleSizeParser -template -prefix_ typename senf::detail::Parse_VectorN_Sizer::size_type -senf::detail::Parse_VectorN_Sizer::size(iterator i, state_type s) +template +prefix_ typename senf::detail::Parse_VectorN_Sizer::size_type +senf::detail::Parse_VectorN_Sizer::size(iterator i, state_type s) const { - return SizeParser(i,s).value(); + return SizeParser(boost::prior(i, Distance), s).value(); } -template -prefix_ void senf::detail::Parse_VectorN_Sizer::size(iterator i, state_type s, - size_type v) +template +prefix_ void senf::detail::Parse_VectorN_Sizer::size(iterator i, + state_type s, + size_type v) const { - SizeParser(i,s).value(v); + SizeParser(boost::prior(i, Distance), s).value(v); } -template -prefix_ typename senf::detail::Parse_VectorN_Sizer::iterator -senf::detail::Parse_VectorN_Sizer::begin(iterator i, state_type s) +template +prefix_ typename senf::detail::Parse_VectorN_Sizer::iterator +senf::detail::Parse_VectorN_Sizer::begin(iterator i, state_type s) const { - return boost::next(i,SizeParser::fixed_bytes); + return i; } -template -prefix_ typename senf::detail::Parse_VectorN_Sizer::size_type -senf::detail::Parse_VectorN_Sizer::bytes(iterator i, state_type s) +template +prefix_ typename senf::detail::Parse_VectorN_Sizer::size_type +senf::detail::Parse_VectorN_Sizer::bytes(iterator i, state_type s) const { - return SizeParser::fixed_bytes; + return 0; } -template -prefix_ void senf::detail::Parse_VectorN_Sizer::init(iterator i, state_type s) +template +prefix_ void senf::detail::Parse_VectorN_Sizer::init(iterator i, + state_type s) const {} diff --git a/Packets/ParseVec.hh b/Packets/ParseVec.hh index beb953f..5d8d180 100644 --- a/Packets/ParseVec.hh +++ b/Packets/ParseVec.hh @@ -35,6 +35,7 @@ #include "ParseArray.hh" // for Parse_Array_iterator //#include "ParseVec.mpp" +#include "ParseVec.ih" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { @@ -111,8 +112,6 @@ namespace senf { friend class Parse_Vector_Container; }; - namespace detail { template class Parse_VectorN_Sizer; } - /** \brief Vector with prefix sizing This is a 'template typedef'. It defines a vector with a directly preceding size @@ -130,28 +129,42 @@ namespace senf { \see Parse_Vector \ingroup parsecollection */ - template + template struct Parse_VectorN { typedef Parse_Vector< ElementParser, - detail::Parse_VectorN_Sizer > parser; + detail::Parse_VectorN_Sizer > 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::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 diff --git a/Packets/ParseVec.ih b/Packets/ParseVec.ih index 339b8f4..2937351 100644 --- a/Packets/ParseVec.ih +++ b/Packets/ParseVec.ih @@ -37,14 +37,14 @@ namespace detail { This is the sizer policy used by Parse_VectorN */ - template + template 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; @@ -53,6 +53,14 @@ namespace detail { 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//////////////////////////////////////// diff --git a/Packets/ParseVec.test.cc b/Packets/ParseVec.test.cc index daa30d1..74e028f 100644 --- a/Packets/ParseVec.test.cc +++ b/Packets/ParseVec.test.cc @@ -48,20 +48,20 @@ BOOST_AUTO_UNIT_TEST(parseVec) senf::PacketInterpreterBase::ptr p (senf::PacketInterpreter::create(data)); typedef senf::Parse_Vector< senf::Parse_UInt16, - senf::detail::Parse_VectorN_Sizer + senf::detail::Parse_VectorN_Sizer > 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()); @@ -75,7 +75,7 @@ BOOST_AUTO_UNIT_TEST(parseVec) // 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 ); @@ -123,9 +123,9 @@ BOOST_AUTO_UNIT_TEST(parseVec_wrapper) senf::PacketInterpreterBase::ptr p (senf::PacketInterpreter::create(data)); typedef senf::Parse_Vector< senf::Parse_UInt16, - senf::detail::Parse_VectorN_Sizer + senf::detail::Parse_VectorN_Sizer > 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 );