--- /dev/null
+// $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_
+
+\f
+// 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:
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
--- /dev/null
+// $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_
+
+\f
+// 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:
}
+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_
<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>
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) \
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
#
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) )
#
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) \
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);
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 \
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
#
<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>
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
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_