Skip to content
Snippets Groups Projects
Commit 3c5862fe authored by g0dil's avatar g0dil
Browse files

Packets: Implement basic AuxParser

Packets: Implement generic internel collection parser macro infrastructure
Packets: Update VectorParser to use the new AuxParser/collection infrastructure
parent 01951b12
No related branches found
No related tags found
No related merge requests found
// $Id$
//
// Copyright (C) 2008
// 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 template implementation */
//#include "AuxParser.ih"
// Custom includes
#define prefix_ inline
///////////////////////////////cti.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::detail::PrefixAuxParserPolicy<P>
template <class P>
prefix_ typename senf::detail::PrefixAuxParserPolicy<P>::ParserType
senf::detail::PrefixAuxParserPolicy<P>::aux(PacketParserBase::data_iterator i,
PacketParserBase::state_type s)
const
{
return ParserType(i, s);
}
template <class P>
prefix_ senf::PacketParserBase::data_iterator
senf::detail::PrefixAuxParserPolicy<P>::adjust(PacketParserBase::data_iterator i,
PacketParserBase::state_type s)
const
{
return i+ParserType::fixed_bytes;
}
///////////////////////////////////////////////////////////////////////////
// senf::detail::FixedAuxParserPolicy<P>
template <class P, unsigned Dist>
prefix_ typename senf::detail::FixedAuxParserPolicy<P,Dist>::ParserType
senf::detail::FixedAuxParserPolicy<P,Dist>::aux(PacketParserBase::data_iterator i,
PacketParserBase::state_type s)
const
{
return ParserType(i-Dist, s);
}
template <class P, unsigned Dist>
prefix_ senf::PacketParserBase::data_iterator
senf::detail::FixedAuxParserPolicy<P,Dist>::adjust(PacketParserBase::data_iterator i,
PacketParserBase::state_type s)
const
{
return i;
}
///////////////////////////////////////////////////////////////////////////
// senf::detail::DynamicAuxParserPolicy<P>
template <class P>
prefix_ senf::detail::DynamicAuxParserPolicy<P>::DynamicAuxParserPolicy(ParserType p)
: p_ (p)
{}
template <class P>
prefix_
senf::detail::DynamicAuxParserPolicy<P>::DynamicAuxParserPolicy(WrapperPolicy const & other)
: p_ (* other.p_)
{}
template <class P>
prefix_ typename senf::detail::DynamicAuxParserPolicy<P>::ParserType
senf::detail::DynamicAuxParserPolicy<P>::aux(PacketParserBase::data_iterator i,
PacketParserBase::state_type s)
const
{
return p_;
}
template <class P>
prefix_ senf::PacketParserBase::data_iterator
senf::detail::DynamicAuxParserPolicy<P>::adjust(PacketParserBase::data_iterator i,
PacketParserBase::state_type s)
const
{
return i;
}
///////////////////////////////////////////////////////////////////////////
// senf::detail::DynamicWrapperAuxParserPolicy<P>
template <class P>
prefix_ senf::detail::DynamicWrapperAuxParserPolicy<P>::
DynamicWrapperAuxParserPolicy(ParserPolicy const & other)
: p_ (other.p_)
{}
template <class P>
prefix_ typename senf::detail::DynamicWrapperAuxParserPolicy<P>::ParserType
senf::detail::DynamicWrapperAuxParserPolicy<P>::aux(PacketParserBase::data_iterator i,
PacketParserBase::state_type s)
const
{
return * p_;
}
template <class P>
prefix_ senf::PacketParserBase::data_iterator
senf::detail::DynamicWrapperAuxParserPolicy<P>::adjust(PacketParserBase::data_iterator i,
PacketParserBase::state_type s)
const
{
return i;
}
///////////////////////////////cti.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:
// $Id$
//
// Copyright (C) 2008
// 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 public header */
#ifndef HH_AuxParser_
#define HH_AuxParser_ 1
#ifndef HH_Packets_
#error "Don't include 'AuxParser.hh' directly, include 'Packets.hh'"
#endif
// Custom includes
#include "PacketParser.hh"
#include "SafeIterator.hh"
//#include "AuxParser.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
namespace detail {
template <class P>
struct PrefixAuxParserPolicy
{
typedef PrefixAuxParserPolicy WrapperPolicy;
typedef P ParserType;
static PacketParserBase::size_type const aux_bytes = ParserType::fixed_bytes;
ParserType aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
};
template <class P, unsigned Dist>
struct FixedAuxParserPolicy
{
typedef FixedAuxParserPolicy WrapperPolicy;
typedef P ParserType;
static PacketParserBase::size_type const aux_bytes = 0;
ParserType aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
};
template <class P> struct DynamicWrapperAuxParserPolicy;
template <class P>
struct DynamicAuxParserPolicy
{
typedef DynamicWrapperAuxParserPolicy<P> WrapperPolicy;
typedef P ParserType;
static PacketParserBase::size_type const aux_bytes = 0;
DynamicAuxParserPolicy(ParserType p);
DynamicAuxParserPolicy(WrapperPolicy const & other);
ParserType aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
ParserType p_;
};
template <class P>
struct DynamicWrapperAuxParserPolicy
{
typedef DynamicAuxParserPolicy<P> ParserPolicy;
typedef P ParserType;
static PacketParserBase::size_type const aux_bytes = 0;
DynamicWrapperAuxParserPolicy(ParserPolicy const & other);
ParserType aux(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
SafePacketParserWrapper<ParserType> p_;
};
}}
///////////////////////////////hh.e////////////////////////////////////////
#endif
#if !defined(HH_Packets__decls_) && !defined(HH_AuxParser_i_)
#define HH_AuxParser_i_
//#include "AuxParser.cci"
//#include "AuxParser.ct"
#include "AuxParser.cti"
#endif
// 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:
......@@ -42,6 +42,13 @@ prefix_ Parser senf::PacketParserBase::parse(data_iterator i)
return Parser(i,state());
}
template <class Parser, class Arg>
prefix_ Parser senf::PacketParserBase::parse(Arg const & arg, data_iterator i)
const
{
return Parser(arg, i, state());
}
template <class Parser>
prefix_ Parser senf::PacketParserBase::parse(size_type n)
const
......@@ -49,6 +56,13 @@ prefix_ Parser senf::PacketParserBase::parse(size_type n)
return Parser(boost::next(i(),n),state());
}
template <class Parser, class Arg>
prefix_ Parser senf::PacketParserBase::parse(Arg const & arg, size_type n)
const
{
return Parser(arg, boost::next(i(),n), state());
}
///////////////////////////////////////////////////////////////////////////
// namespace members
......
......@@ -328,11 +328,22 @@ namespace senf {
beginning at \a i. Automatically passes \a state() to
the new parser. */
template <class Parser, class Arg> Parser parse(Arg const & arg, data_iterator i) const;
///< Create sub-parser
/**< This is like parse(data_iterator), however it passes
the extra argument \a arg to the \a Parser
constructor. */
template <class Parser> Parser parse(size_type n) const; ///< Create sub-parser
/**< Creates a new instance of \a Parser to parse data
* beginning at i()<tt> + </tt>\a n. Automatically passes \a
state() to the new parser. */
template <class Parser, class Arg> Parser parse(Arg const & arg, size_type n) const;
///< Create sub-parser
/**< This is like parse(size_type), however it passes the
extra argument \a arg to the \a Parser constructor. */
void defaultInit() const; ///< Default implementation
/**< This is just an empty default
implementation. Re-implement this member in your own
......@@ -370,6 +381,7 @@ namespace senf {
PacketParserBase::size_type bytes(Parser p);
namespace detail { template <class Parser> class ParserInitBytes; }
namespace detail { template <class Parser> class ParserIsFixed; }
/** \brief Return number of bytes to allocate to new object of given type
......@@ -390,6 +402,10 @@ namespace senf {
struct init_bytes : public detail::ParserInitBytes<Parser>
{};
template <class Parser>
struct is_fixed : public detail::ParserIsFixed<Parser>
{};
# ifndef DOXYGEN
template <class Parser>
typename boost::enable_if<
......
......@@ -84,6 +84,18 @@ namespace detail {
struct ParserInitBytes
: public ParserInitBytes_Choose<Parser,SENF_MPL_RV(ParserInitBytes_Choose_<Parser>(0))> {};
template <class Parser, unsigned _>
struct ParserIsFixed_Choose
: public boost::false_type {};
template <class Parser>
struct ParserIsFixed_Choose<Parser, 1>
: public boost::true_type {};
template <class Parser>
struct ParserIsFixed
: public ParserIsFixed_Choose<Parser,SENF_MPL_RV(ParserInitBytes_Choose_<Parser>(0))> {};
# endif
}}
......
......@@ -38,6 +38,7 @@
#include "PacketParser.hh"
#include "SafeIterator.hh"
#include "ArrayParser.hh"
#include "AuxParser.hh"
#include "ListParser.hh"
#include "ListBParser.hh"
#include "ListNParser.hh"
......@@ -59,6 +60,7 @@
#include "SafeIterator.hh"
#include "ArrayParser.hh"
#include "IntParser.hh"
#include "AuxParser.hh"
#include "ListParser.hh"
#include "ListBParser.hh"
#include "ListNParser.hh"
......
......@@ -50,6 +50,7 @@
SENF_MPL_SLOT_DEF_ZERO(init_bytes); \
SENF_MPL_SLOT_DEF_ZERO(bit); \
SENF_MPL_SLOT_DEF_ZERO(bitfield_size); \
SENF_MPL_SLOT_DEF_ZERO(group); \
void init_chain(senf::mpl::rv<0>*) const {} \
size_type field_offset_(senf::mpl::rv<0>*) const { return 0; } \
public:
......@@ -94,6 +95,11 @@
#
# define SENF_PARSER_FIELD_I(name, type, ofstype, rwtype, access) \
access: \
SENF_PARSER_FIELD_SETUP_I(name, type, ofstype, rwtype, access) \
BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access) \
public:
#
# define SENF_PARSER_FIELD_SETUP_I(name, type, ofstype, rwtype, access) \
SENF_PARSER_I_BITFIELD_RESET() \
SENF_PARSER_I_FIELD_INTRO(name, type, access) \
BOOST_PP_CAT(SENF_PARSER_I_FIELD_INIT_, rwtype) (name, type, access) \
......@@ -102,9 +108,8 @@
name, type, \
BOOST_PP_CAT(SENF_PARSER_I_SIZE_, ofstype) (name, type), \
BOOST_PP_CAT(SENF_PARSER_I_INITBYTES_, ofstype) (name, type), \
access ) \
BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access) \
public:
BOOST_PP_CAT(SENF_PARSER_I_ISVAR_, ofstype) (name, type), \
access )
#
# ////////////////////////////////////////
# // SENF_PARSER_I_FIELD_INTRO
......@@ -149,14 +154,16 @@
# ////////////////////////////////////////
# // SENF_PARSER_I_ADVANCE_OFS_*
#
# // Can't call 'name()' here if 'name' is an ro field ...
# define SENF_PARSER_I_SIZE_var(name, type) senf::bytes(parse<type>(BOOST_PP_CAT(name,_offset)()))
# define SENF_PARSER_I_SIZE_var(name, type) senf::bytes(BOOST_PP_CAT(name, _)())
# define SENF_PARSER_I_INITBYTES_var(name, type) senf::init_bytes<type>::value
#
# define SENF_PARSER_I_SIZE_fix(name, type) type::fixed_bytes
# define SENF_PARSER_I_INITBYTES_fix(name, type) void
#
# define SENF_PARSER_I_ADVANCE_OFS_var(name, type, size, isize, access) \
# define SENF_PARSER_I_ISVAR_fix(name, type) 0
# define SENF_PARSER_I_ISVAR_var(name, type) (senf::is_fixed<type>::value?0:1)
#
# define SENF_PARSER_I_ADVANCE_OFS_var(name, type, size, isize, isvar, access) \
size_type BOOST_PP_CAT(name, _next_offset)() const { \
return BOOST_PP_CAT(name,_offset)() + size; \
} \
......@@ -167,9 +174,11 @@
return BOOST_PP_CAT(name, _next_offset)(); \
} \
SENF_MPL_SLOT_SET(init_bytes, BOOST_PP_CAT(name,_next_init_bytes)); \
static size_type const BOOST_PP_CAT(name, _group) = SENF_MPL_SLOT_GET(group) + isvar; \
SENF_MPL_SLOT_SET(group, BOOST_PP_CAT(name, _group)); \
access:
#
# define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize, access) \
# define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize, isvar, access) \
static size_type const BOOST_PP_CAT(name, _next_offset) = \
BOOST_PP_CAT(name, _offset) + size; \
private: \
......@@ -180,8 +189,13 @@
# // SENF_PARSER_I_FIELD_VAL_*
#
# define SENF_PARSER_I_FIELD_VAL_rw(name, type, access) \
BOOST_PP_CAT(name, _t) name() const { \
private: \
BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const { \
return parse<type>( SENF_PARSER_OFFSET(name) ); \
} \
access: \
BOOST_PP_CAT(name, _t) name() const { \
return BOOST_PP_CAT(name,_)(); \
}
#
# define SENF_PARSER_I_FIELD_VAL_ro(name, type, access) \
......@@ -207,7 +221,7 @@
SENF_PARSER_I_FIELD_INTRO(name, type, public) \
SENF_PARSER_I_FIELD_INIT_ro(name, type, public) \
BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, public) \
BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize, public) \
BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize, 1, public) \
BOOST_PP_CAT(name, _t) name() const
#
# ///////////////////////////////////////////////////////////////////////////
......@@ -253,6 +267,7 @@
BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) ( \
name, type, \
BOOST_PP_CAT(name, _t)::fixed_bytes, BOOST_PP_CAT(name, _t)::fixed_bytes, \
0, \
access) \
private: \
SENF_MPL_SLOT_SET(bitfield_size, BOOST_PP_CAT(name, _t)::fixed_bytes); \
......@@ -297,7 +312,8 @@
SENF_PARSER_I_FIELD_INTRO(name, void, private) \
SENF_PARSER_I_FIELD_INIT_ro(name, void, private) \
BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access) \
BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, bytes, ibytes, private) \
BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, bytes, ibytes, 1, \
private) \
public:
#
# ///////////////////////////////////////////////////////////////////////////
......@@ -359,7 +375,7 @@
SENF_PARSER_I_FIELD_INTRO(name, void, access) \
SENF_PARSER_I_FIELD_INIT_ro(name, void, access) \
BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access) \
BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, 0, 0,access) \
BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, 0, 0, 0, access) \
public:
#
# ///////////////////////////////////////////////////////////////////////////
......@@ -375,7 +391,7 @@
# define SENF_PARSER_FIXED_OFFSET_var(name) BOOST_PP_CAT(name, _init_bytes)
#
# ///////////////////////////////////////////////////////////////////////////
# // SENF_PARSER_FIXED_OFFSET_*
# // SENF_PARSER_CURRENT_FIXED_OFFSET_*
#
# define SENF_PARSER_CURRENT_FIXED_OFFSET_fix() SENF_MPL_SLOT_GET(offset)
# define SENF_PARSER_CURRENT_FIXED_OFFSET_var() SENF_MPL_SLOT_GET(init_bytes)
......@@ -404,6 +420,91 @@
public: \
void init() const { init(0); }
#
# ///////////////////////////////////////////////////////////////////////////
# // SENF_PARSER_REQUIRE_VAR
#
# define SENF_PARSER_REQUIRE_VAR(description) \
BOOST_PP_CAT(SENF_PARSER_REQUIRE_VAR_, SENF_PARSER_TYPE)(description)
#
# define SENF_PARSER_REQUIRE_VAR_var(description)
#
# define SENF_PARSER_REQUIRE_VAR_fix(description) \
typedef BOOST_PP_CAT( PARSER_ERROR__, \
BOOST_PP_CAT(description, _not_allowed_in_fixed_parser) ) \
BOOST_PP_CAT(errsym_, __LINE__);
#
# ///////////////////////////////////////////////////////////////////////////
# // SENF_PARSER_COLLECTION_I
#
namespace senf { namespace detail { namespace auxtag { struct none {}; } } }
#
# define SENF_PARSER_COLLECTION_I(access, name, aux, 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); \
typedef traits::parser< \
BOOST_PP_CAT(name,_aux_policy), \
senf::detail::auxtag::none \
>::type BOOST_PP_CAT(name, _collection_t); \
access: \
SENF_PARSER_FIELD_SETUP_I( name, \
BOOST_PP_CAT(name, _collection_t), \
SENF_PARSER_TYPE, \
rw, \
access ) \
BOOST_PP_CAT(SENF_PARSER_COLLECTION_VAL_, SENF_PARSER_TYPE)(name, aux, access) \
public:
#
# 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);
#
# define SENF_PARSER_COLLECTION_AUXTYPE_fix(name, aux)
#
namespace senf { namespace detail {
template <class Parser> struct DynamicAuxParserPolicy;
template <class Parser, unsigned offset> struct FixedAuxParserPolicy;
template <class Parser, unsigned fixedOffset, bool fixedDelta>
struct ParserAuxPolicySelect
{ typedef senf::detail::DynamicAuxParserPolicy<Parser> type; };
template <class Parser, unsigned fixedOffset>
struct ParserAuxPolicySelect<Parser, fixedOffset, true>
{ typedef senf::detail::FixedAuxParserPolicy<Parser, fixedOffset> type; };
}};
#
# define SENF_PARSER_COLLECTION_AUX_I_var(name, aux) \
senf::detail::ParserAuxPolicySelect< BOOST_PP_CAT(aux, _t), \
SENF_PARSER_CURRENT_FIXED_OFFSET() \
- SENF_PARSER_FIXED_OFFSET(aux), \
BOOST_PP_CAT(name, _aux_fixed) >::type
#
# define SENF_PARSER_COLLECTION_AUX_I_fix(name, aux) \
senf::detail::FixedAuxParserPolicy< BOOST_PP_CAT(aux, _t), \
SENF_PARSER_CURRENT_FIXED_OFFSET() \
- SENF_PARSER_FIXED_OFFSET(aux) >
#
# define SENF_PARSER_COLLECTION_VAL_var(name,aux,access) \
private: \
template <class T> T BOOST_PP_CAT(name, _dispatch)(boost::true_type) const \
{ return parse<T>( SENF_PARSER_OFFSET(name) ); } \
template <class T> T BOOST_PP_CAT(name, _dispatch)(boost::false_type) const \
{ return parse<T>( BOOST_PP_CAT(name, _aux_policy)(aux()), SENF_PARSER_OFFSET(name) ); } \
BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const \
{ return BOOST_PP_CAT(name, _dispatch) <BOOST_PP_CAT(name, _t)>( \
boost::integral_constant<bool, BOOST_PP_CAT(name, _aux_fixed)>()); } \
access: \
BOOST_PP_CAT(name, _t) name() const \
{ return BOOST_PP_CAT(name, _)(); }
#
# define SENF_PARSER_COLLECTION_VAL_fix(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
#
......
......@@ -37,7 +37,7 @@ template <class ElementParser, class Sizer>
prefix_ void senf::VectorParser<ElementParser,Sizer>::init()
const
{
sizer_.init(i(),state());
aux(i(), state()) = 0;
iterator i (begin());
iterator const e (end());
for (; i!=e; ++i)
......
......@@ -33,77 +33,77 @@
///////////////////////////////////////////////////////////////////////////
// senf::VectorParser<ElementParser,Sizer>
template <class ElementParser, class Sizer>
prefix_ senf::VectorParser<ElementParser,Sizer>::VectorParser(data_iterator i, state_type s)
: PacketParserBase(i,s), sizer_()
template <class ElementParser, class AuxPolicy>
prefix_ senf::VectorParser<ElementParser,AuxPolicy>::VectorParser(data_iterator i, state_type s)
: PacketParserBase(i,s), AuxPolicy()
{}
template <class ElementParser, class Sizer>
prefix_ senf::VectorParser<ElementParser,Sizer>::VectorParser(Sizer sizer, data_iterator i,
state_type s)
: PacketParserBase(i,s), sizer_(sizer)
template <class ElementParser, class AuxPolicy>
prefix_ senf::VectorParser<ElementParser,AuxPolicy>::VectorParser(AuxPolicy policy,
data_iterator i, state_type s)
: PacketParserBase(i,s), AuxPolicy(policy)
{}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser<ElementParser,Sizer>::size_type
senf::VectorParser<ElementParser,Sizer>::bytes()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::size_type
senf::VectorParser<ElementParser,AuxPolicy>::bytes()
const
{
return size()*ElementParser::fixed_bytes + sizer_.bytes(i(),state());
return size()*ElementParser::fixed_bytes + AuxPolicy::aux_bytes;
}
// Container interface
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser<ElementParser,Sizer>::size_type
senf::VectorParser<ElementParser,Sizer>::size()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::size_type
senf::VectorParser<ElementParser,AuxPolicy>::size()
const
{
return sizer_.size(i(),state());
return aux(i(),state());
}
template <class ElementParser, class Sizer>
prefix_ bool senf::VectorParser<ElementParser,Sizer>::empty()
template <class ElementParser, class AuxPolicy>
prefix_ bool senf::VectorParser<ElementParser,AuxPolicy>::empty()
const
{
return size()==0;
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser<ElementParser,Sizer>::iterator
senf::VectorParser<ElementParser,Sizer>::begin()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::iterator
senf::VectorParser<ElementParser,AuxPolicy>::begin()
const
{
return iterator(sizer_.begin(i(),state()),state());
return iterator(adjust(i(),state()),state());
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser<ElementParser,Sizer>::iterator
senf::VectorParser<ElementParser,Sizer>::end()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::iterator
senf::VectorParser<ElementParser,AuxPolicy>::end()
const
{
return boost::next(begin(),size());
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser<ElementParser,Sizer>::value_type
senf::VectorParser<ElementParser,Sizer>::operator[](difference_type i)
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::value_type
senf::VectorParser<ElementParser,AuxPolicy>::operator[](difference_type i)
const
{
return begin()[i];
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser<ElementParser,Sizer>::value_type
senf::VectorParser<ElementParser,Sizer>::front()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::value_type
senf::VectorParser<ElementParser,AuxPolicy>::front()
const
{
return begin()[0];
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser<ElementParser,Sizer>::value_type
senf::VectorParser<ElementParser,Sizer>::back()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser<ElementParser,AuxPolicy>::value_type
senf::VectorParser<ElementParser,AuxPolicy>::back()
const
{
return begin()[size()-1];
......@@ -111,99 +111,57 @@ senf::VectorParser<ElementParser,Sizer>::back()
// Mutators
template <class ElementParser, class Sizer>
template <class ElementParser, class AuxPolicy>
template <class Value>
prefix_ void senf::VectorParser<ElementParser,Sizer>::push_back(Value value, size_type n)
prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::push_back(Value value, size_type n)
const
{
container c (*this);
c.push_back(value,n);
}
template <class ElementParser, class Sizer>
prefix_ void senf::VectorParser<ElementParser,Sizer>::push_back_space(size_type n)
template <class ElementParser, class AuxPolicy>
prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::push_back_space(size_type n)
const
{
container c (*this);
c.push_back_space(n);
}
template <class ElementParser, class Sizer>
template <class ElementParser, class AuxPolicy>
template <class Value>
prefix_ void senf::VectorParser<ElementParser,Sizer>::push_front(Value value, size_type n)
prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::push_front(Value value, size_type n)
const
{
container c (*this);
c.push_front(value,n);
}
template <class ElementParser, class Sizer>
prefix_ void senf::VectorParser<ElementParser,Sizer>::push_front_space(size_type n)
template <class ElementParser, class AuxPolicy>
prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::push_front_space(size_type n)
const
{
container c (*this);
c.push_front_space(n);
}
template <class ElementParser, class Sizer>
prefix_ void senf::VectorParser<ElementParser,Sizer>::resize(size_type n)
template <class ElementParser, class AuxPolicy>
prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::resize(size_type n)
const
{
container c (*this);
c.resize(n);
}
template <class ElementParser, class Sizer>
template <class ElementParser, class AuxPolicy>
template <class Value>
prefix_ void senf::VectorParser<ElementParser,Sizer>::resize(size_type n, Value value)
prefix_ void senf::VectorParser<ElementParser,AuxPolicy>::resize(size_type n, Value value)
const
{
container c (*this);
c.resize(n,value);
}
///////////////////////////////////////////////////////////////////////////
// senf::SimpleSizeParser<SizeParser,offset>
template <class SizeParser, unsigned Distance>
prefix_ typename senf::detail::VectorNParser_Sizer<SizeParser,Distance>::size_type
senf::detail::VectorNParser_Sizer<SizeParser,Distance>::size(iterator i, state_type s)
const
{
return SizeParser(boost::prior(i, Distance), s).value();
}
template <class SizeParser, unsigned Distance>
prefix_ void senf::detail::VectorNParser_Sizer<SizeParser,Distance>::size(iterator i,
state_type s,
size_type v)
const
{
SizeParser(boost::prior(i, Distance), s).value(v);
}
template <class SizeParser, unsigned Distance>
prefix_ typename senf::detail::VectorNParser_Sizer<SizeParser,Distance>::iterator
senf::detail::VectorNParser_Sizer<SizeParser,Distance>::begin(iterator i, state_type s)
const
{
return i;
}
template <class SizeParser, unsigned Distance>
prefix_ typename senf::detail::VectorNParser_Sizer<SizeParser,Distance>::size_type
senf::detail::VectorNParser_Sizer<SizeParser,Distance>::bytes(iterator i, state_type s)
const
{
return 0;
}
template <class SizeParser, unsigned Distance>
prefix_ void senf::detail::VectorNParser_Sizer<SizeParser,Distance>::init(iterator i,
state_type s)
const
{}
///////////////////////////////////////////////////////////////////////////
// senf::VectorParser_wrapper<Parser,SizeParser,Container>
......@@ -212,65 +170,65 @@ prefix_ void senf::detail::VectorNParser_Sizer<SizeParser,Distance>::init(iterat
// hm ... be careful here ! the data() member is called in an incompletely intitialized
// instance. However, data() only depends on state_ which is initialized before the call. YOU MUST
// NOT CHANGE THE ORDERING OF THE DATA MEMBERS
template <class ElementParser, class Sizer>
prefix_ senf::VectorParser_Container<ElementParser,Sizer>::
template <class ElementParser, class AuxPolicy>
prefix_ senf::VectorParser_Container<ElementParser,AuxPolicy>::
VectorParser_Container(parser_type const & vector)
: sizer_ (vector.sizer_), state_ (vector.state()),
: AuxPolicy(vector), state_ (vector.state()),
i_ (std::distance(data().begin(),vector.i()))
{}
// accessors
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::size_type
senf::VectorParser_Container<ElementParser,Sizer>::size()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::size_type
senf::VectorParser_Container<ElementParser,AuxPolicy>::size()
const
{
return sizer_.size(i(),state());
return aux(i(),state());
}
template <class ElementParser, class Sizer>
prefix_ bool senf::VectorParser_Container<ElementParser,Sizer>::empty()
template <class ElementParser, class AuxPolicy>
prefix_ bool senf::VectorParser_Container<ElementParser,AuxPolicy>::empty()
const
{
return size() == 0;
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::iterator
senf::VectorParser_Container<ElementParser,Sizer>::begin()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::iterator
senf::VectorParser_Container<ElementParser,AuxPolicy>::begin()
const
{
return iterator(sizer_.begin(i(),state()),state());
return iterator(adjust(i(),state()),state());
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::iterator
senf::VectorParser_Container<ElementParser,Sizer>::end()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::iterator
senf::VectorParser_Container<ElementParser,AuxPolicy>::end()
const
{
return boost::next(begin(),size());
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::value_type
senf::VectorParser_Container<ElementParser,Sizer>::operator[](difference_type i)
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::value_type
senf::VectorParser_Container<ElementParser,AuxPolicy>::operator[](difference_type i)
const
{
return begin()[i];
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::value_type
senf::VectorParser_Container<ElementParser,Sizer>::front()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::value_type
senf::VectorParser_Container<ElementParser,AuxPolicy>::front()
const
{
return begin()[0];
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::value_type
senf::VectorParser_Container<ElementParser,Sizer>::back()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::value_type
senf::VectorParser_Container<ElementParser,AuxPolicy>::back()
const
{
return begin()[size()-1];
......@@ -278,109 +236,109 @@ senf::VectorParser_Container<ElementParser,Sizer>::back()
// Mutators
template <class ElementParser, class Sizer>
template <class ElementParser, class AuxPolicy>
template <class Value>
prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::insert(iterator pos,
prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::insert(iterator pos,
Value const & t)
{
*shift(pos) << t;
}
template <class ElementParser, class Sizer>
prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::erase(iterator pos, size_type n)
template <class ElementParser, class AuxPolicy>
prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::erase(iterator pos, size_type n)
{
data().erase(pos.raw(),boost::next(pos.raw(),n*ElementParser::fixed_bytes));
setSize(size()-n);
}
template <class ElementParser, class Sizer>
prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::erase(iterator f, iterator l)
template <class ElementParser, class AuxPolicy>
prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::erase(iterator f, iterator l)
{
erase(f,std::distance(f,l));
}
template <class ElementParser, class Sizer>
prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::clear()
template <class ElementParser, class AuxPolicy>
prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::clear()
{
erase(begin(),end());
}
template <class ElementParser, class Sizer>
template <class ElementParser, class AuxPolicy>
template <class Value>
prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::push_back(Value value,
prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::push_back(Value value,
size_type n)
{
insert(end(),n,value);
}
template <class ElementParser, class Sizer>
prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::push_back_space(size_type n)
template <class ElementParser, class AuxPolicy>
prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::push_back_space(size_type n)
{
shift(end(),n);
}
template <class ElementParser, class Sizer>
template <class ElementParser, class AuxPolicy>
template <class Value>
prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::push_front(Value value,
prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::push_front(Value value,
size_type n)
{
insert(begin(),n,value);
}
template <class ElementParser, class Sizer>
prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::push_front_space(size_type n)
template <class ElementParser, class AuxPolicy>
prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::push_front_space(size_type n)
{
shift(begin(),n);
}
// Parser interface
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::parser_type
senf::VectorParser_Container<ElementParser,Sizer>::parser()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::parser_type
senf::VectorParser_Container<ElementParser,AuxPolicy>::parser()
const
{
return parser_type(i(),state());
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::data_iterator
senf::VectorParser_Container<ElementParser,Sizer>::i()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::data_iterator
senf::VectorParser_Container<ElementParser,AuxPolicy>::i()
const
{
return boost::next(data().begin(),i_);
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::state_type
senf::VectorParser_Container<ElementParser,Sizer>::state()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::state_type
senf::VectorParser_Container<ElementParser,AuxPolicy>::state()
const
{
return state_;
}
template <class ElementParser, class Sizer>
template <class ElementParser, class AuxPolicy>
prefix_ senf::PacketData &
senf::VectorParser_Container<ElementParser,Sizer>::data()
senf::VectorParser_Container<ElementParser,AuxPolicy>::data()
const
{
return *state_;
}
template <class ElementParser, class Sizer>
prefix_ typename senf::VectorParser_Container<ElementParser,Sizer>::size_type
senf::VectorParser_Container<ElementParser,Sizer>::bytes()
template <class ElementParser, class AuxPolicy>
prefix_ typename senf::VectorParser_Container<ElementParser,AuxPolicy>::size_type
senf::VectorParser_Container<ElementParser,AuxPolicy>::bytes()
const
{
return size()*ElementParser::fixed_bytes + sizer_.bytes(i(),state());
return size()*ElementParser::fixed_bytes + AuxPolicy::aux_bytes;
}
// private members
template <class ElementParser, class Sizer>
prefix_ void senf::VectorParser_Container<ElementParser,Sizer>::setSize(size_type value)
template <class ElementParser, class AuxPolicy>
prefix_ void senf::VectorParser_Container<ElementParser,AuxPolicy>::setSize(size_type value)
{
sizer_.size(i(),state(),value);
aux(i(),state()).value(value);
}
/////////////////////////////cti.e///////////////////////////////////////
......
......@@ -33,9 +33,9 @@
#include <boost/type_traits.hpp>
#include "PacketParser.hh"
#include "ArrayParser.hh" // for ArrayParser_iterator
#include "AuxParser.hh" // for the AuxPolicies
//#include "VectorParser.mpp"
#include "VectorParser.ih"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
......@@ -61,11 +61,13 @@ namespace senf {
\see ExampleVectorPolicy
\ingroup parsecollection
*/
template <class ElementParser, class Sizer>
struct VectorParser : public PacketParserBase
template <class ElementParser, class AuxPolicy>
struct VectorParser
: public PacketParserBase,
private AuxPolicy
{
VectorParser(data_iterator i, state_type s);
VectorParser(Sizer sizer, data_iterator i, state_type s);
VectorParser(AuxPolicy policy, data_iterator i, state_type s);
///< Additional sizer specific constructor
/**< This constructor may be used, if the sizer needs
additional parameters. */
......@@ -73,7 +75,7 @@ namespace senf {
size_type bytes() const;
void init() const;
static const size_type init_bytes = Sizer::init_bytes;
static const size_type init_bytes = AuxPolicy::aux_bytes;
///////////////////////////////////////////////////////////////////////////
// Container interface
......@@ -81,7 +83,7 @@ namespace senf {
typedef ElementParser value_type;
typedef detail::ArrayParser_iterator<value_type> iterator;
typedef iterator const_iterator;
typedef VectorParser_Container<ElementParser,Sizer> container;
typedef VectorParser_Container<ElementParser,AuxPolicy> container;
size_type size() const;
bool empty() const;
......@@ -107,33 +109,8 @@ namespace senf {
template <class Value> void resize (size_type n, Value value) const;
private:
Sizer sizer_;
friend class VectorParser_Container<ElementParser,Sizer>;
};
/** \brief Vector with prefix sizing
This is a 'template typedef'. It defines a vector with a <em>directly preceding</em> size
field holding the number of vector elements. The size field is considered part of the
vector.
\code
// Define MyVector as a vector of 16bit unsigned elements with a directly preceding
// 8bit unsigned size field
typedef senf::VectorNParser<senf::UInt16Parser, senf::UInt8Parser>::parser MyVector;
\endcode
\param ElementParser \e fixed-size parser for parsing the vector elements
\param SizeParser parser for parsing the vector size (number of elements)
\see VectorParser
\ingroup parsecollection
*/
template <class ElementParser, class SizeParser, unsigned Distance>
struct VectorNParser
{
typedef VectorParser< ElementParser,
detail::VectorNParser_Sizer<SizeParser, Distance> > parser;
friend class VectorParser_Container<ElementParser,AuxPolicy>;
};
/** \brief Define VectorNParser field
......@@ -145,7 +122,7 @@ namespace senf {
// The size field should be declared private (size is accessible via the vector)
SENF_PARSER_PRIVATE_FIELD ( vec_size_, senf::UInt16Parser );
// Define the vector, here it has 32bit unsigned integer elements
SENF_PARSER_VEC_N ( vec, _vec_size, senf::UInt32Parser );
SENF_PARSER_VEC_N ( vec, vec_size_, senf::UInt32Parser );
\endcode
\param[in] name field name
......@@ -166,6 +143,14 @@ namespace senf {
# define SENF_PARSER_PRIVATE_VEC_N(name, size, elt_type) \
SENF_PARSER_VEC_N_I(SENF_PARSER_PRIVATE_FIELD, name, size, elt_type)
# define SENF_PARSER_VECTOR(name, size, elt_type) \
SENF_PARSER_VECTOR_I(public, name, size, elt_type)
# define SENF_PARSER_PRIVATE_VECTOR(name, size, elt_type) \
SENF_PARSER_VECTOR_I(private, name, size, elt_type)
/** \brief VectorParser container wrapper
This is the container wrapper used for vector parsers. The container wrapper will stay valid
......@@ -184,14 +169,15 @@ namespace senf {
\see VectorParser
*/
template <class ElementParser, class Sizer>
template <class ElementParser, class AuxPolicy>
class VectorParser_Container
: private AuxPolicy
{
public:
///////////////////////////////////////////////////////////////////////////
// Types
typedef VectorParser<ElementParser,Sizer> parser_type;
typedef VectorParser<ElementParser,AuxPolicy> parser_type;
typedef PacketParserBase::data_iterator data_iterator;
typedef PacketParserBase::size_type size_type;
typedef PacketParserBase::difference_type difference_type;
......@@ -276,7 +262,6 @@ namespace senf {
private:
void setSize(size_type value);
Sizer sizer_;
state_type state_;
size_type i_;
};
......
......@@ -33,38 +33,34 @@
namespace senf {
namespace detail {
/** \brief Internal: Sizer implementing prefix sizing
\internal
# define SENF_PARSER_VEC_N_I(field, name, size, elt_type) \
typedef senf::VectorParser< \
elt_type, \
senf::detail::FixedAuxParserPolicy< BOOST_PP_CAT(size, _t), \
SENF_PARSER_CURRENT_FIXED_OFFSET() \
- SENF_PARSER_FIXED_OFFSET(size) > \
> BOOST_PP_CAT(name, _vec_t); \
field( name, BOOST_PP_CAT(name, _vec_t) )
This is the sizer policy used by VectorNParser
*/
template <class SizeParser, unsigned Distance>
struct VectorNParser_Sizer
template <class ElementParser>
struct VectorParserTraits
{
typedef PacketParserBase::size_type size_type;
typedef PacketParserBase::data_iterator iterator;
typedef PacketParserBase::state_type state_type;
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;
iterator begin (iterator i, state_type s) const;
size_type bytes (iterator i, state_type s) const;
void init (iterator i, state_type s) const;
template <class AuxPolicy, class AuxTag>
struct parser {
typedef senf::VectorParser<ElementParser, AuxPolicy> type;
};
};
# define SENF_PARSER_VEC_N_I(field, name, size, elt_type) \
typedef senf::VectorNParser< 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) )
}}
# define SENF_PARSER_VECTOR_I(access, name, size, elt_type) \
SENF_PARSER_REQUIRE_VAR(vector) \
SENF_PARSER_COLLECTION_I( access, \
name, \
size, \
senf::detail::VectorParserTraits<elt_type> )
}}
///////////////////////////////ih.e////////////////////////////////////////
#endif
......
......@@ -48,7 +48,7 @@ BOOST_AUTO_UNIT_TEST(VectorParser)
senf::PacketInterpreterBase::ptr p (senf::PacketInterpreter<VoidPacket>::create(data));
typedef senf::VectorParser<
senf::UInt16Parser,
senf::detail::VectorNParser_Sizer<senf::UInt8Parser, 1u>
senf::detail::FixedAuxParserPolicy<senf::UInt8Parser, 1u>
> UInt16VectorParser;
{
......@@ -123,7 +123,7 @@ BOOST_AUTO_UNIT_TEST(VectorParser_wrapper)
senf::PacketInterpreterBase::ptr p (senf::PacketInterpreter<VoidPacket>::create(data));
typedef senf::VectorParser<
senf::UInt16Parser,
senf::detail::VectorNParser_Sizer<senf::UInt8Parser, 1u>
senf::detail::FixedAuxParserPolicy<senf::UInt8Parser, 1u>
> UInt16VectorParser;
UInt16VectorParser v (boost::next(p->data().begin(),1), &p->data());
UInt16VectorParser::container w (v);
......@@ -172,6 +172,74 @@ BOOST_AUTO_UNIT_TEST(VectorParser_wrapper)
BOOST_CHECK_EQUAL( w.parser().size(), 0u );
}
BOOST_AUTO_UNIT_TEST(dynamicPolicyVector)
{
unsigned char data[] = { 0x03, // size
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, // data
0x20, 0x21, 0x22, 0x23, 0x24, 0x25 };
senf::PacketInterpreterBase::ptr p (senf::PacketInterpreter<VoidPacket>::create(data));
typedef senf::VectorParser<
senf::UInt16Parser,
senf::detail::DynamicAuxParserPolicy<senf::UInt8Parser>
> UInt16VectorParser;
UInt16VectorParser v (senf::UInt8Parser(p->data().begin(), &p->data()),
boost::next(p->data().begin(),1), &p->data());
UInt16VectorParser::container w (v);
BOOST_CHECK_EQUAL( v.size(), 3u );
BOOST_CHECK_EQUAL( w.size(), 3u );
BOOST_CHECK_EQUAL( v[0], 0x1011 );
BOOST_CHECK_EQUAL( v[2], 0x1415 );
BOOST_CHECK_EQUAL( w[0], 0x1011 );
BOOST_CHECK_EQUAL( w[2], 0x1415 );
}
namespace {
struct TestVectorParser
: public senf::PacketParserBase
{
# include SENF_PARSER()
SENF_PARSER_PRIVATE_FIELD ( size1 , senf::UInt8Parser );
SENF_PARSER_PRIVATE_FIELD ( size2 , senf::UInt8Parser );
SENF_PARSER_FIELD ( dummy , senf::UInt32Parser );
SENF_PARSER_VECTOR ( vec1 , size1, senf::UInt16Parser );
SENF_PARSER_VECTOR ( vec2 , size2, senf::UInt16Parser );
SENF_PARSER_FINALIZE( TestVectorParser );
};
}
BOOST_AUTO_UNIT_TEST(vectorMacro)
{
unsigned char data[] = { 0x03, // size1
0x02, // size2
0x01, 0x02, 0x03, 0x04, // dummy
0x05, 0x06, // vec1[0]
0x07, 0x08, // vec1[1]
0x09, 0x0A, // vec1[2]
0x0B, 0x0C, // vec2[0]
0x0D, 0x0E }; // vec2[1]
senf::DataPacket p (senf::DataPacket::create(data));
TestVectorParser parser (p.data().begin(), &p.data());
BOOST_CHECK_EQUAL( parser.vec1().size(), 3u );
BOOST_CHECK_EQUAL( parser.vec2().size(), 2u );
BOOST_CHECK_EQUAL( parser.dummy(), 0x01020304u );
BOOST_CHECK_EQUAL( parser.vec1()[0], 0x0506u );
BOOST_CHECK_EQUAL( parser.vec1()[1], 0x0708u );
BOOST_CHECK_EQUAL( parser.vec1()[2], 0x090Au );
BOOST_CHECK_EQUAL( parser.vec2()[0], 0x0B0Cu );
BOOST_CHECK_EQUAL( parser.vec2()[1], 0x0D0Eu );
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment