diff --git a/Packets/AuxParser.cci b/Packets/AuxParser.cci new file mode 100644 index 0000000000000000000000000000000000000000..b3542140541c1c31c3bc04e45c241086f03ca2f6 --- /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 <g0dil@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 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 412bb2d769adfb415974aa454ff5877775d3910b..cdba7038b543822330f6528ff4968aec66595347 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 0000000000000000000000000000000000000000..af26822c61780e913c049e79c2d50c6390ac972f --- /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 <g0dil@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 AuxParser.test unit tests */ + +//#include "AuxParser.test.hh" +//#include "AuxParser.test.ih" + +// Custom includes +#include "Packets.hh" + +#include "../Utils/auto_unit_test.hh" +#include <boost/test/test_tools.hpp> + +#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<senf::UInt16Parser::fixed_bytes> > + > 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 82b6dd353c855da60cd413c976b472c43f0a2acd..585f1761fe0319be9d8d2e8187406dfbd48e1d04 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 817ba4827777607bfbf4a9431edb6b0feebf9e80..1b0a4f6b6c6654ba60579b0771c8efc0d82e18e3 100644 --- a/Packets/ListParser.hh +++ b/Packets/ListParser.hh @@ -244,6 +244,9 @@ namespace senf { <tr><td>\c bytes(\a size)</td><td>\a size gives the size of the list in bytes not the number of contained elements</td></tr> + <tr><td>\c packetSize()</td><td>Use the size of the packet to get the list size. The + list will occupy all space up to the end of the packet.</td></tr> + <tr><td>\c transform(\a transform, \a size)</td><td>The \a transform is applied to the \a size value, the value is not used directly</td> diff --git a/Packets/ParseHelpers.ih b/Packets/ParseHelpers.ih index f279f35bbc854d4e9eb279daaeec1e76797099da..a4d1cd90142430797ecd954505e4008fe7401ab6 100644 --- a/Packets/ParseHelpers.ih +++ b/Packets/ParseHelpers.ih @@ -459,21 +459,34 @@ namespace senf { namespace detail { namespace auxtag { template <class Transform, class Tag> struct transform {}; } } } + namespace senf { namespace detail { namespace auxtag { + struct packetSize {}; } } } # # endif # +# // Each tag is implemented by defining the following macros. If the Tag is <name>(<args>): +# // SENF_PARSER_COLLECTION_TAG_GOBBLE__<name>(<args>) +# // gobble the tag, that is expand to nothing +# // SENF_PARSER_COLLECTION_TAG__<name>(<args>) +# // 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__<tag>(<tag args>) +# // expand to the real tag type +# // SENF_PARSER_COLLECTION_TAG_GETAUX__<name>(<args>) +# // return the real aux field. More specifically, this is the aux argument to the aux expand +# // macro +# // SENF_PARSER_COLLECTION_TAG_AUXTYPE__<name>(<args>) +# // return an identifier selecting the aux type macro to use. If the expansion of this macro +# // is <auxtag>, the macro will be called SENF_PARSER_COLLECTION_TAG_AUXDEF__<auxtag> +# // SENF_PARSER_COLLECTION_TAG_AUXDEF__<auxtag>(<name>,<auxarg>) +# // this command must declare the typedef <fieldname>_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 <class T> 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<BOOST_PP_CAT(name, _t)>( 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 3ac2e448f59afeed74e362a416a673528ca03ae7..623e18f567fec095468c36d8d3bfd46e9a200048 100644 --- a/Packets/VectorParser.hh +++ b/Packets/VectorParser.hh @@ -246,6 +246,9 @@ namespace senf { <table class="senf fixedcolumn"> <tr><td>\c bytes(\a size)</td><td>\a size gives the size of the vector in bytes not the number of contained elements</td></tr> + + <tr><td>\c packetSize()</td><td>Use the size of the packet to get the vector size. The + vector will occupy all space up to the end of the packet.</td></tr> <tr><td>\c transform(\a transform, \a size)</td><td>The \a transform is applied to the \a size value, the value is not used directly</td> @@ -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 c00b541a811ab77e88151f0a9106a97c8160a698..f720df05a938b07dfd5772b3754cd88756774c28 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_