diff --git a/Packets/AuxParser.cti b/Packets/AuxParser.cti new file mode 100644 index 0000000000000000000000000000000000000000..205d88dc0e0c326e466c14f26f462117d9719817 --- /dev/null +++ b/Packets/AuxParser.cti @@ -0,0 +1,146 @@ +// $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: diff --git a/Packets/AuxParser.hh b/Packets/AuxParser.hh new file mode 100644 index 0000000000000000000000000000000000000000..162657e15ef37bd4a44c4144c51254e1b7f48a92 --- /dev/null +++ b/Packets/AuxParser.hh @@ -0,0 +1,121 @@ +// $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: diff --git a/Packets/PacketParser.cti b/Packets/PacketParser.cti index 9cb4968601cada25f03adc2075781601a35b5af8..098908f71235a210d2c79dd9a3c7f749a693b678 100644 --- a/Packets/PacketParser.cti +++ b/Packets/PacketParser.cti @@ -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 diff --git a/Packets/PacketParser.hh b/Packets/PacketParser.hh index c85ff2ff99b9398309b91e12d1f579a8010b8121..1e389da790b1499f51a0e40f9fe06589a8b6a3dc 100644 --- a/Packets/PacketParser.hh +++ b/Packets/PacketParser.hh @@ -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< diff --git a/Packets/PacketParser.ih b/Packets/PacketParser.ih index 450bc031c8a60a3a45b3198257b6dc39088cf1e5..4596ea8e35c106f963fcb5ae37c9aea924bef767 100644 --- a/Packets/PacketParser.ih +++ b/Packets/PacketParser.ih @@ -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 }} diff --git a/Packets/Packets.hh b/Packets/Packets.hh index 6cd562629ce973ed5e9df9030012c734560154bf..90036c0026c9c9f0c702ab6021556d53c657bd68 100644 --- a/Packets/Packets.hh +++ b/Packets/Packets.hh @@ -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" diff --git a/Packets/ParseHelpers.ih b/Packets/ParseHelpers.ih index 7e672824ca64f7cf2ac44ee04ccbaf4f5dfa8d72..d93609743abb9b7d1e7ce2a8bccc3b73ea7ca1ec 100644 --- a/Packets/ParseHelpers.ih +++ b/Packets/ParseHelpers.ih @@ -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 # diff --git a/Packets/VectorParser.ct b/Packets/VectorParser.ct index 7d15db4dc2a750f56ca2cc6ec1c4313d45d7d687..fb8918744736614b37eda7a494b22194e5c44119 100644 --- a/Packets/VectorParser.ct +++ b/Packets/VectorParser.ct @@ -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) diff --git a/Packets/VectorParser.cti b/Packets/VectorParser.cti index 4ecf3bbb1657c6646d6830f74d4d7a5c16386404..430427fe8d3361b3489ee5c48c6a6b255a8ba78a 100644 --- a/Packets/VectorParser.cti +++ b/Packets/VectorParser.cti @@ -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/////////////////////////////////////// diff --git a/Packets/VectorParser.hh b/Packets/VectorParser.hh index b135cd8f310afe2f4c1479c22e11b54c0bd7884d..ac7a15a875435765f27fefeaa136580219f19640 100644 --- a/Packets/VectorParser.hh +++ b/Packets/VectorParser.hh @@ -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_; }; diff --git a/Packets/VectorParser.ih b/Packets/VectorParser.ih index c7b4340042c7d844819625d9a2d1e193b1e6381e..6da8f4901df0714f192505238225f271c6278cca 100644 --- a/Packets/VectorParser.ih +++ b/Packets/VectorParser.ih @@ -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 diff --git a/Packets/VectorParser.test.cc b/Packets/VectorParser.test.cc index ef7cffe748cf77775aba3105ebd9e3611bab364a..b51b392b6f23eaca9532e51a2eb14777be1dea52 100644 --- a/Packets/VectorParser.test.cc +++ b/Packets/VectorParser.test.cc @@ -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_