From: g0dil Date: Fri, 23 Jan 2009 09:47:07 +0000 (+0000) Subject: Packets: Implement packet size aux parser policy and packetSize() collection macro... X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=d3cc92544f3efc741d14c36e4cd89e311a6867fa;p=senf.git Packets: Implement packet size aux parser policy and packetSize() collection macro size tag git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1074 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Packets/AuxParser.cci b/Packets/AuxParser.cci new file mode 100644 index 0000000..b354214 --- /dev/null +++ b/Packets/AuxParser.cci @@ -0,0 +1,70 @@ +// $Id$ +// +// Copyright (C) 2009 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// 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 AuxParser inline non-template implementation */ + +//#include "AuxParser.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cci.p/////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////// +// senf::detail::PacketSizeAuxParserPolicy + +prefix_ senf::PacketParserBase::size_type +senf::detail::PacketSizeAuxParserPolicy::aux(PacketParserBase::data_iterator i, + PacketParserBase::state_type s) + const +{ + return std::distance(i, s->end()); +} + +prefix_ void senf::detail::PacketSizeAuxParserPolicy::aux(unsigned v, + PacketParserBase::data_iterator i, + PacketParserBase::state_type s) + const +{} + +prefix_ senf::PacketParserBase::data_iterator +senf::detail::PacketSizeAuxParserPolicy::adjust(PacketParserBase::data_iterator i, + PacketParserBase::state_type s) + const +{ + return i; +} + +///////////////////////////////cci.e/////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/Packets/AuxParser.hh b/Packets/AuxParser.hh index 412bb2d..cdba703 100644 --- a/Packets/AuxParser.hh +++ b/Packets/AuxParser.hh @@ -147,13 +147,25 @@ namespace detail { typename Transform::value_type aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const; void aux(typename Transform::value_type const & v, PacketParserBase::data_iterator i, PacketParserBase::state_type s) const; }; + + struct PacketSizeAuxParserPolicy + { + typedef PacketSizeAuxParserPolicy WrapperPolicy; + typedef PacketSizeAuxParserPolicy ParserPolicy; + + static PacketParserBase::size_type const aux_bytes = 0; + + PacketParserBase::size_type aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const; + void aux(unsigned v, PacketParserBase::data_iterator i, PacketParserBase::state_type s) const; + PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const; + }; }} ///////////////////////////////hh.e//////////////////////////////////////// #endif #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_AuxParser_i_) #define HH_SENF_Packets_AuxParser_i_ -//#include "AuxParser.cci" +#include "AuxParser.cci" //#include "AuxParser.ct" #include "AuxParser.cti" #endif diff --git a/Packets/AuxParser.test.cc b/Packets/AuxParser.test.cc new file mode 100644 index 0000000..af26822 --- /dev/null +++ b/Packets/AuxParser.test.cc @@ -0,0 +1,177 @@ +// $Id$ +// +// Copyright (C) 2009 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// 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 AuxParser.test unit tests */ + +//#include "AuxParser.test.hh" +//#include "AuxParser.test.ih" + +// Custom includes +#include "Packets.hh" + +#include "../Utils/auto_unit_test.hh" +#include + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +// The other aux policies are tested with the corresponding container classes + +BOOST_AUTO_UNIT_TEST(vectorPacketSizeAuxPolicy) +{ + unsigned char data[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25 }; + senf::Packet p (senf::DataPacket::create(data)); + + typedef senf::VectorParser< + senf::UInt8Parser, + senf::detail::PacketSizeAuxParserPolicy + > UInt8VectorParser; + + { + UInt8VectorParser v (p.data().begin(), &p.data()); + + BOOST_CHECK_EQUAL( v.size(), p.data().size() ); + BOOST_CHECK_EQUAL_COLLECTIONS( v.begin(), v.end(), data, data+sizeof(data) ); + } + + { + UInt8VectorParser v (p.data().begin(), &p.data()); + UInt8VectorParser::container w (v); + + BOOST_CHECK_EQUAL_COLLECTIONS( w.begin(), w.end(), data, data+sizeof(data) ); + + w.shift(w.begin()+1); + BOOST_CHECK_EQUAL( w.size(), p.data().size() ); + + w.erase(w.begin()+3, w.begin()+5); + BOOST_CHECK_EQUAL( w.size(), p.data().size() ); + + unsigned char data2[] = { 0x10, 0x00, 0x11, 0x14, 0x15, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25 }; + + BOOST_CHECK_EQUAL_COLLECTIONS( w.begin(), w.end(), data2, data2+sizeof(data2) ); + } +} + +BOOST_AUTO_UNIT_TEST(vectorPacketSizeAuxPolicy_transformed) +{ + unsigned char data[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25 }; + senf::Packet p (senf::DataPacket::create(data)); + + typedef senf::VectorParser< + senf::UInt16Parser, + senf::detail::TransformAuxParserPolicy< + senf::detail::PacketSizeAuxParserPolicy, + senf::detail::VectorParserBytesTransform > + > UInt16VectorParser; + + { + UInt16VectorParser v (p.data().begin(), &p.data()); + + BOOST_REQUIRE_EQUAL( v.size(), p.data().size()/2 ); + BOOST_CHECK_EQUAL( v[0], 0x1011u ); + BOOST_CHECK_EQUAL( v[1], 0x1213u ); + BOOST_CHECK_EQUAL( v[5], 0x2425u ); + } + + { + UInt16VectorParser v (p.data().begin(), &p.data()); + UInt16VectorParser::container w (v); + + BOOST_REQUIRE_EQUAL( w.size(), p.data().size()/2 ); + BOOST_CHECK_EQUAL( w[0], 0x1011u ); + BOOST_CHECK_EQUAL( w[1], 0x1213u ); + BOOST_CHECK_EQUAL( w[5], 0x2425u ); + + w.shift(w.begin()+1); + BOOST_CHECK_EQUAL( w.size(), p.data().size()/2 ); + + w.erase(w.begin()+3, w.begin()+5); + BOOST_CHECK_EQUAL( w.size(), p.data().size()/2 ); + + senf::UInt16Parser::value_type data2[] = + { 0x1011u, 0x0000u, 0x1213u, 0x2223u, 0x2425u }; + + BOOST_CHECK_EQUAL_COLLECTIONS( w.begin(), w.end(), + data2, data2+sizeof(data2)/sizeof(data2[0]) ); + } +} + +BOOST_AUTO_UNIT_TEST(listPacketSizeAuxPolicy) +{ + unsigned char data[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25 }; + senf::Packet p (senf::DataPacket::create(data)); + + typedef senf::ListParser< + senf::detail::ListBParser_Policy< + senf::UInt16Parser, + senf::detail::PacketSizeAuxParserPolicy> + > ListParser; + + { + ListParser l (p.data().begin(), &p.data()); + + BOOST_REQUIRE_EQUAL( l.size(), p.data().size()/2 ); + BOOST_CHECK_EQUAL( l.front(), 0x1011u ); + BOOST_CHECK_EQUAL( l.back(), 0x2425u ); + } + + { + ListParser l (p.data().begin(), &p.data()); + ListParser::container w (l); + + BOOST_REQUIRE_EQUAL( w.size(), p.data().size()/2 ); + BOOST_CHECK_EQUAL( *w.begin(), 0x1011u ); + BOOST_CHECK_EQUAL( *boost::next(w.begin()), 0x1213u ); + BOOST_CHECK_EQUAL( *boost::next(w.begin(),5), 0x2425u ); + + w.shift(boost::next(w.begin())); + BOOST_CHECK_EQUAL( w.size(), p.data().size()/2 ); + + w.erase(boost::next(w.begin(),3), boost::next(w.begin(),5)); + BOOST_CHECK_EQUAL( w.size(), p.data().size()/2 ); + + senf::UInt16Parser::value_type data2[] = + { 0x1011u, 0x0000u, 0x1213u, 0x2223u, 0x2425u }; + + BOOST_CHECK_EQUAL_COLLECTIONS( w.begin(), w.end(), + data2, data2+sizeof(data2)/sizeof(data2[0]) ); + } +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/Packets/ListBParser.test.cc b/Packets/ListBParser.test.cc index 82b6dd3..585f176 100644 --- a/Packets/ListBParser.test.cc +++ b/Packets/ListBParser.test.cc @@ -239,6 +239,108 @@ BOOST_AUTO_UNIT_TEST(listBytesMacro) } +namespace { + + struct TestPacketSizeList + : public senf::PacketParserBase + { +# include SENF_PARSER() + + SENF_PARSER_LIST ( list, packetSize(), VectorParser ); + + SENF_PARSER_FINALIZE(TestPacketSizeList); + }; + + +} + +BOOST_AUTO_UNIT_TEST(listBytesParser_packetSize) +{ + unsigned char data[] = { 0x01, // list()[0].vec().size() + 0x05, 0x06, // list()[0].vec()[0] + 0x02, // list()[1].vec().size() + 0x07, 0x08, // list()[1].vec()[0] + 0x09, 0x0A, // list()[1].vec()[1] + 0x00, // list()[2].vec().size() + 0x02, // list()[3].vec().size() + 0x0B, 0x0C, // list()[3].vec()[0] + 0x0D, 0x0E, // list()[3].vec()[1] + 0x01, // list()[4].vec().size() + 0x0F, 0x10 }; // list()[4].vec()[0] + + senf::DataPacket p (senf::DataPacket::create(data)); + + { + TestPacketSizeList l (p.data().begin(), &p.data()); + BOOST_CHECK_EQUAL( l.list().size(), 5u ); + + TestPacketSizeList::list_t::container c (l.list()); + TestPacketSizeList::list_t::container::iterator i (c.begin()); + + senf::UInt16Parser::value_type vec0[] = { 0x0506 }; + senf::UInt16Parser::value_type vec1[] = { 0x0708, 0x090A }; + senf::UInt16Parser::value_type vec2[] = {}; + senf::UInt16Parser::value_type vec3[] = { 0x0B0C, 0x0D0E }; + senf::UInt16Parser::value_type vec4[] = { 0x0F10 }; + + BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(), + vec0, vec0+sizeof(vec0)/sizeof(vec0[0]) ); + ++ i; + BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(), + vec1, vec1+sizeof(vec1)/sizeof(vec1[0]) ); + ++ i; + BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(), + vec2, vec2+sizeof(vec2)/sizeof(vec2[0]) ); + ++ i; + BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(), + vec3, vec3+sizeof(vec3)/sizeof(vec3[0]) ); + + ++ i; + BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(), + vec4, vec4+sizeof(vec4)/sizeof(vec4[0]) ); + + ++ i; + BOOST_CHECK( i == c.end() ); + + i = c.begin(); + ++i; + TestPacketSizeList::list_t::value_type::vec_t::container v (i->vec()); + v.push_back(0xFEFF); + } + + { + TestPacketSizeList l (p.data().begin(), &p.data()); + BOOST_CHECK_EQUAL( l.list().size(), 5u ); + BOOST_CHECK_EQUAL( l.list().bytes(), p.data().size() ); + + TestPacketSizeList::list_t::container c (l.list()); + TestPacketSizeList::list_t::container::iterator i (c.begin()); + + senf::UInt16Parser::value_type vec0[] = { 0x0506 }; + senf::UInt16Parser::value_type vec1[] = { 0x0708, 0x090A, 0xFEFF }; + senf::UInt16Parser::value_type vec2[] = {}; + senf::UInt16Parser::value_type vec3[] = { 0x0B0C, 0x0D0E }; + senf::UInt16Parser::value_type vec4[] = { 0x0F10 }; + + BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(), + vec0, vec0+sizeof(vec0)/sizeof(vec0[0]) ); + ++ i; + BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(), + vec1, vec1+sizeof(vec1)/sizeof(vec1[0]) ); + ++ i; + BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(), + vec2, vec2+sizeof(vec2)/sizeof(vec2[0]) ); + ++ i; + BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(), + vec3, vec3+sizeof(vec3)/sizeof(vec3[0]) ); + + ++ i; + BOOST_CHECK_EQUAL_COLLECTIONS( i->vec().begin(), i->vec().end(), + vec4, vec4+sizeof(vec4)/sizeof(vec4[0]) ); + ++ i; + BOOST_CHECK( i == c.end() ); + } +} ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ diff --git a/Packets/ListParser.hh b/Packets/ListParser.hh index 817ba48..1b0a4f6 100644 --- a/Packets/ListParser.hh +++ b/Packets/ListParser.hh @@ -244,6 +244,9 @@ namespace senf { \c bytes(\a size)\a size gives the size of the list in bytes not the number of contained elements + \c packetSize()Use the size of the packet to get the list size. The + list will occupy all space up to the end of the packet. + \c transform(\a transform, \a size)The \a transform is applied to the \a size value, the value is not used directly diff --git a/Packets/ParseHelpers.ih b/Packets/ParseHelpers.ih index f279f35..a4d1cd9 100644 --- a/Packets/ParseHelpers.ih +++ b/Packets/ParseHelpers.ih @@ -459,21 +459,34 @@ namespace senf { namespace detail { namespace auxtag { template struct transform {}; } } } + namespace senf { namespace detail { namespace auxtag { + struct packetSize {}; } } } # # endif # +# // Each tag is implemented by defining the following macros. If the Tag is (): +# // SENF_PARSER_COLLECTION_TAG_GOBBLE__() +# // gobble the tag, that is expand to nothing +# // SENF_PARSER_COLLECTION_TAG__() +# // return an intermediate tag. This tag will be used with the next macro to get the aux tag +# // this indirection is needed since the tag may include templates with more than one +# // argument which cannot be passed through macros ... Ugh ... +# // SENF_PARSER_COLLECTION_TAG_EXPAND__() +# // expand to the real tag type +# // SENF_PARSER_COLLECTION_TAG_GETAUX__() +# // return the real aux field. More specifically, this is the aux argument to the aux expand +# // macro +# // SENF_PARSER_COLLECTION_TAG_AUXTYPE__() +# // return an identifier selecting the aux type macro to use. If the expansion of this macro +# // is , the macro will be called SENF_PARSER_COLLECTION_TAG_AUXDEF__ +# // SENF_PARSER_COLLECTION_TAG_AUXDEF__(,) +# // this command must declare the typedef _aux_type to the base aux policy +# # define SENF_PARSER_COLLECTION_TAG_GOBBLE__bytes(x) # define SENF_PARSER_COLLECTION_TAG__bytes(x) bytes() # define SENF_PARSER_COLLECTION_TAG_EXPAND__bytes() senf::detail::auxtag::bytes # define SENF_PARSER_COLLECTION_TAG_GETAUX__bytes(x) x -# -# // No recursive call so we need some more of theese ... ARGH !!! -# define SENF_CAT_RECURS1(a, b) SENF_CAT_RECURS1_I(a,b) -# define SENF_CAT_RECURS1_I(a, b) a ## b -# define SENF_CAT_RECURS2(a, b) SENF_CAT_RECURS2_I(a,b) -# define SENF_CAT_RECURS2_I(a, b) a ## b -# define SENF_CAT_RECURS3(a, b) SENF_CAT_RECURS3_I(a,b) -# define SENF_CAT_RECURS3_I(a, b) a ## b +# define SENF_PARSER_COLLECTION_TAG_AUXTYPE__bytes(x) auxField # # define SENF_PARSER_COLLECTION_TAG_GOBBLE__transform(x,y) # define SENF_PARSER_COLLECTION_TAG__transform(x,y) \ @@ -484,6 +497,22 @@ SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_EXPAND__, y)> # define SENF_PARSER_COLLECTION_TAG_GETAUX__transform(x,y) \ SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(y) +# define SENF_PARSER_COLLECTION_TAG_AUXTYPE__transform(x,y) \ + SENF_PARSER_COLLECTION_TAG_AUXTYPE_RECURS1(y) +# +# define SENF_PARSER_COLLECTION_TAG_GOBBLE__packetSize() +# define SENF_PARSER_COLLECTION_TAG__packetSize() packetSize() +# define SENF_PARSER_COLLECTION_TAG_EXPAND__packetSize() senf::detail::auxtag::bytes +# define SENF_PARSER_COLLECTION_TAG_GETAUX__packetSize() _ +# define SENF_PARSER_COLLECTION_TAG_AUXTYPE__packetSize() packetSize +# +# // No recursive call so we need some more of theese ... ARGH !!! +# define SENF_CAT_RECURS1(a, b) SENF_CAT_RECURS1_I(a,b) +# define SENF_CAT_RECURS1_I(a, b) a ## b +# define SENF_CAT_RECURS2(a, b) SENF_CAT_RECURS2_I(a,b) +# define SENF_CAT_RECURS2_I(a, b) a ## b +# define SENF_CAT_RECURS3(a, b) SENF_CAT_RECURS3_I(a,b) +# define SENF_CAT_RECURS3_I(a, b) a ## b # # define SENF_PARSER_COLLECTION_TAG_EXPAND__none() senf::detail::auxtag::none # @@ -499,6 +528,12 @@ BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux), \ aux) # +# define SENF_PARSER_COLLECTION_TAG_AUXTYPE_RECURS1(aux) \ + BOOST_PP_IF( \ + SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \ + BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_AUXTYPE__, aux), \ + auxField) +# # define SENF_PARSER_COLLECTION_HAS_KEYWORD(x) \ BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_GOBBLE__, x) ) # @@ -514,20 +549,20 @@ SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \ ( access, \ name, \ + SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_AUXTYPE__, aux), \ SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux), \ SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG__, aux), \ traits ), \ ( access, \ name, \ + auxField, \ aux, \ none(), \ traits ) )) # -# define SENF_PARSER_COLLECTION_II(access, name, aux, tag, traits) \ +# define SENF_PARSER_COLLECTION_II(access, name, auxtype, aux, tag, traits) \ private: \ - BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUXTYPE_, SENF_PARSER_TYPE)(name, aux) \ - typedef BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUX_I_, SENF_PARSER_TYPE)(name, aux) \ - BOOST_PP_CAT(name,_aux_policy); \ + BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_AUXDEF__, auxtype)(name, aux) \ typedef traits::parser< \ BOOST_PP_CAT(name,_aux_policy), \ BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_EXPAND__, tag) \ @@ -538,9 +573,14 @@ SENF_PARSER_TYPE, \ rw, \ access ) \ - BOOST_PP_CAT(SENF_PARSER_COLLECTION_VAL_, SENF_PARSER_TYPE)(name, aux, access) \ + BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_VAL__, auxtype)(name, aux, access) \ public: # +# define SENF_PARSER_COLLECTION_TAG_AUXDEF__auxField(name, aux) \ + BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUXTYPE_, SENF_PARSER_TYPE)(name, aux) \ + typedef BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUX_I_, SENF_PARSER_TYPE)(name, aux) \ + BOOST_PP_CAT(name,_aux_policy); +# # define SENF_PARSER_COLLECTION_AUXTYPE_var(name, aux) \ static bool const BOOST_PP_CAT(name, _aux_fixed) = \ (SENF_MPL_SLOT_GET(group) - BOOST_PP_CAT(aux, _group) == 0); @@ -573,6 +613,12 @@ SENF_PARSER_CURRENT_FIXED_OFFSET() \ - SENF_PARSER_FIXED_OFFSET(aux) > # +# define SENF_PARSER_COLLECTION_TAG_AUXDEF__packetSize(name, aux) \ + typedef senf::detail::PacketSizeAuxParserPolicy BOOST_PP_CAT(name, _aux_policy); +# +# define SENF_PARSER_COLLECTION_TAG_VAL__auxField(name, aux, access) \ + BOOST_PP_CAT(SENF_PARSER_COLLECTION_VAL_, SENF_PARSER_TYPE)(name, aux, access) +# # define SENF_PARSER_COLLECTION_VAL_var(name,aux,access) \ private: \ template T BOOST_PP_CAT(name, _dispatch)(boost::true_type) const \ @@ -594,6 +640,14 @@ BOOST_PP_CAT(name, _t) name() const \ { return BOOST_PP_CAT(name, _)(); } # +# define SENF_PARSER_COLLECTION_TAG_VAL__packetSize(name, aux, access) \ + private: \ + BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const \ + { return parse( SENF_PARSER_OFFSET(name) ); } \ + access: \ + BOOST_PP_CAT(name, _t) name() const \ + { return BOOST_PP_CAT(name, _)(); } +# # ////////////////////////////////ih.e/////////////////////////////////////// # endif # diff --git a/Packets/VectorParser.hh b/Packets/VectorParser.hh index 3ac2e44..623e18f 100644 --- a/Packets/VectorParser.hh +++ b/Packets/VectorParser.hh @@ -246,6 +246,9 @@ namespace senf { + + @@ -266,6 +269,7 @@ namespace senf { The tags are applied to the \a size parameter: \code SENF_PARSER_VECTOR ( vec, transform(MyTransform, vec_size_), senf::UInt32Parser ); + SENF_PARSER_VECTOR ( vec, packetSize(), senf::UInt32Parser ); \endcode \param[in] name field name diff --git a/Packets/VectorParser.test.cc b/Packets/VectorParser.test.cc index c00b541..f720df0 100644 --- a/Packets/VectorParser.test.cc +++ b/Packets/VectorParser.test.cc @@ -337,6 +337,38 @@ BOOST_AUTO_UNIT_TEST(vectorMacro_inherit) BOOST_CHECK_EQUAL( parser.vec2()[1], 0x0D0Eu ); } +namespace { + + struct TestPacketSizeVectorParser + : public senf::PacketParserBase + { +# include SENF_PARSER() + + SENF_PARSER_VECTOR ( vec , packetSize() , senf::UInt16Parser ); + + SENF_PARSER_FINALIZE( TestPacketSizeVectorParser ); + }; + +} + +BOOST_AUTO_UNIT_TEST(vectorMacro_packetSize) +{ + unsigned char data[] = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26 }; + + senf::DataPacket p (senf::DataPacket::create(data)); + TestPacketSizeVectorParser parser (p.data().begin(), &p.data()); + + { + BOOST_CHECK_EQUAL( parser.vec().size(), 6u ); + BOOST_CHECK_EQUAL( parser.vec()[0], 0x1112u ); + BOOST_CHECK_EQUAL( parser.vec()[1], 0x1314u ); + BOOST_CHECK_EQUAL( parser.vec()[5], 0x2526u ); + } + + // The real functionality is already tested in AuxPolixy.test.cc ... +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_
\c bytes(\a size)\a size gives the size of the vector in bytes not the number of contained elements
\c packetSize()Use the size of the packet to get the vector size. The + vector will occupy all space up to the end of the packet.
\c transform(\a transform, \a size)The \a transform is applied to the \a size value, the value is not used directly