Packets: Add container helper macros
g0dil [Mon, 22 Oct 2007 23:26:11 +0000 (23:26 +0000)]
Packets: Move example policies into .dox files
Packets: Implement variant parser

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@473 270642c3-0616-0410-b53a-bc976706d245

17 files changed:
Packets/MPEGDVBBundle/SConscript
Packets/MPEGDVBBundle/TLV.dia
Packets/ParseArray.hh
Packets/ParseHelpers.hh
Packets/ParseHelpers.ih
Packets/ParseList.dox [new file with mode: 0644]
Packets/ParseList.hh
Packets/ParseListB.hh
Packets/ParseListN.hh
Packets/ParseVariant.ct [new file with mode: 0644]
Packets/ParseVariant.cti [new file with mode: 0644]
Packets/ParseVariant.dox [new file with mode: 0644]
Packets/ParseVariant.hh [new file with mode: 0644]
Packets/ParseVariant.ih [new file with mode: 0644]
Packets/ParseVariant.test.cc [new file with mode: 0644]
Packets/ParseVec.dox [new file with mode: 0644]
Packets/ParseVec.hh

index 8155acd..8529e7b 100644 (file)
@@ -15,5 +15,5 @@ SENFSCons.Lib(env, library = 'Packets_MPEGDVBBundle', sources = sources[0],
               LIBS = ['Packets', 'Socket', 'Utils'], no_includes = 1)
 
 SENFSCons.Doxygen(env, extra_sources = [
-    env.Dia2Png("TLV.dia", DIA2PNGMAXWIDTH = 600)
+    env.Dia2Png("TLV.dia")
 ])
index d3bdc7c..77dc6eb 100644 (file)
Binary files a/Packets/MPEGDVBBundle/TLV.dia and b/Packets/MPEGDVBBundle/TLV.dia differ
index a42f406..b7e40bd 100644 (file)
@@ -95,6 +95,21 @@ namespace senf {
         value_type operator[](difference_type i) const;
     };
 
+    /** \brief Define array field
+
+        This macro is a special helper to define a senf::Parse_Array type field, a fixed size
+        collection of fixed size elements.
+        
+        \param[in] name field name
+        \param[in] elt_type array element type
+        \param[in] size constant number of elements
+        \hideinitializer
+        \ingroup packetparsermacros
+     */
+#   define SENF_PARSER_ARRAY(name, elt_type, size)                                                \
+        typedef senf::Parse_Array<size,elt_type> BOOST_PP_CAT(name, _array_t);                    \
+        SENF_PARSER_FIELD( name, BOOST_PP_CAT(name, _array_t) )
+
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
index bc22591..6561dbf 100644 (file)
     See the documentation of each of these macros for a detailed description of the macro arguments
     and usage. Bit-fields are handled in the following section.
 
+    There also some supplementary macros for defining fields of more complex composite types
+    (e.g. vectors). See the list of 'Defines' further down this page.
+
     \subsection parsermacrosbitfields Bit-fields
 
     \par "" 
     This command will skip the given number of bits within a bitfield group. This command does \e
     only affect bitfield commands. Therefore, a SENF_PARSER_SKIP_BITS command which is not followed
     by a bitfield command will be ignored.
+
+    \hideinitializer
  */
 #define SENF_PARSER_SKIP_BITS(bits)
 
     group covers multiple bytes before the bit field \a name.
 
     \param[in] name field or label to jump to
+    \hideinitializer
  */
 #define SENF_PARSER_GOTO(name)
 
 
     \param[in] offset Depending on the parser type, either single \a bytes value or two arguments \a
         bytes and \a init_size.
+    \hideinitializer
  */
 #define SENF_PARSER_GOTO_OFFSET(offset)
 
     labeled with \ref SENF_PARSER_LABEL()
 
     \param[in] name label name
+    \hideinitializer
  */
 #define SENF_PARSER_LABEL(name)
 
     while defining the parser, normally while defining inline functions.
 
     This macro will return the correct value when defining fixed or dynamically sized parsers.
+
+    \param[in] name field or label name
+    \returns offset of the field from parsers start
+    \hideinitializer
  */
 #define SENF_PARSER_OFFSET(name)
 
+/** \brief Get fixed field offset, if possible
+
+    This macro will return the fixed offset to the field \a name, a compile-time constant
+    expression. This is identical to \ref SENF_PARSER_OFFSET() when defining a fixed size parser.
+
+    Even in dynamically sized parsers this macro will work, if the field \a name is preceded by
+    fixed size fields only. This macro does \e not validate this condition, it will return an
+    arbitrary incorrect value otherwise.
+
+    \pre Field \a name preceded by fixed size fields only
+    \param[in] field or label name
+    \returns compile-time constant offset of the field from parsers start
+    \hideinitializer
+ */
+#define SENF_PARSER_FIXED_OFFSET(name)
+
 ///@}
 
 #else
 #define SENF_PARSER_LABEL        BOOST_PP_CAT(SENF_PARSER_LABEL_,       SENF_PARSER_TYPE)
 
 #define SENF_PARSER_OFFSET       BOOST_PP_CAT(SENF_PARSER_OFFSET_,      SENF_PARSER_TYPE)
+#define SENF_PARSER_FIXED_OFFSET BOOST_PP_CAT(SENF_PARSER_FIXED_OFFSET_,SENF_PARSER_TYPE)
+#define SENF_PARSER_CURRENT_FIXED_OFFSET BOOST_PP_CAT(SENF_PARSER_CURRENT_FIXED_OFFSET_, SENF_PARSER_TYPE)
 
 #define SENF_PARSER_FINALIZE     BOOST_PP_CAT(SENF_PARSER_FINALIZE_,    SENF_PARSER_TYPE)
 
index aca1f14..b55c9a4 100644 (file)
 # define SENF_PARSER_OFFSET_var(name) BOOST_PP_CAT(name, _offset)()
 #
 # ///////////////////////////////////////////////////////////////////////////
+# // SENF_PARSER_FIXED_OFFSET_*
+#
+# define SENF_PARSER_FIXED_OFFSET_fix(name) BOOST_PP_CAT(name, _offset)
+# define SENF_PARSER_FIXED_OFFSET_var(name) BOOST_PP_CAT(name, _init_bytes)
+#
+# ///////////////////////////////////////////////////////////////////////////
+# // SENF_PARSER_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)
+#
+# ///////////////////////////////////////////////////////////////////////////
 # // SENF_PARSER_FINALIZE_*
 #
 # define SENF_PARSER_FINALIZE_var(name)                                                           \
diff --git a/Packets/ParseList.dox b/Packets/ParseList.dox
new file mode 100644 (file)
index 0000000..3cad044
--- /dev/null
@@ -0,0 +1,192 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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.
+
+namespace senf {
+
+    /** \brief Example of a list policy. ONLY FOR EXPOSITION.
+        
+        This class shows the interface which must be implemented by a list policy. It is not a list
+        policy only a declaration of the interface:
+        \code
+        struct ExampleListPolicy
+        {
+            // optional typedefs used to simplify all other declarations
+            typedef PacketParserBase::data_iterator data_iterator;
+            typedef PacketParserBase::state_type state_type;
+            typedef PacketParserBase::size_type size_type;
+
+            // mandatory typedefs in the parser and container policy
+            typedef ElementParser element_type;
+            typedef Parse_List< ExampleListPolicy > parser_type;
+            typedef Parse_List_Container< ExampleListPolicy > container_type;
+
+            // mandatory constant in parser and container policy
+            static const size_type init_bytes = 0;
+
+            // Members needed in the parser and the container policy
+            size_type bytes  (data_iterator i, state_type s) const;
+            size_type size   (data_iterator i, state_type s) const;
+            void      init   (data_iterator i, state_type s) const;
+        
+            // Members needed only in the container policy
+            void      erase  (data_iterator i, state_type s, iterator p) const;
+            void      insert (data_iterator i, state_type s, iterator p) const;
+
+            struct iterator_policy
+            {
+                iterator setBegin        (data_iterator i, state_type s);
+                iterator setEnd          (data_iterator i, state_type s);
+                void     setFromPosition (data_iterator i, state_type s, iterator p);
+                iterator next            (data_iterator i, state_type s);
+                iterator raw             (data_iterator i, state_type s) const;
+            };
+        };
+        \endcode
+
+        The list policy must be either default constructible or copy constructible. The policy may
+        contain arbitrary additional data members. However, their number and size should be kept at
+        an absolute minimum, since they will increase the size of the list parser.
+
+        If necessary, you may use a different policy in the container_type. The ListPolicy must
+        define the elements bytes(), size() and init(), the container policy needs all these and
+        additionally needs erase() and insert(). The container policy will also need the
+        element_type, parser_type and container_type typedefs.
+        
+        \see \ref Parse_List
+     */
+    struct ExampleListPolicy
+    {
+        typedef PacketParserBase::data_iterator iterator;
+        typedef PacketParserBase::state_type state_type;
+        typedef PacketParserBase::size_type size_type;
+
+        typedef void element_type;      ///< Type of list elements
+                                        /**< This is the parser used to parse the list elements. */
+        typedef void parser_type;       ///< List parser type
+                                        /**< parser_type is the list parser used to parse a list of
+                                             this type,
+                                             e.g. <tt>senf::Parse_List<ExampleListPolicy></tt>. */
+        typedef void container_type;    ///< Type of container wrapper
+                                        /**< This is the container wrapper of the list, e.g.
+                                             <tt>Parse_List_Container<ExampleListPolicy></tt>. The
+                                             container may however use a \e different policy, as
+                                             long as that policy is constructible from the parser
+                                             policy. */
+
+        static const size_type init_bytes = 0; ///< Size of a new list of this type
+                                        /**< Initial size which needs to be allocated to this type
+                                             of list */
+
+        size_type bytes(iterator i, state_type s) const; ///< Size of list in bytes
+                                        /**< Return the complete size of the list in
+                                             bytes. Depending on the type of list, this call may
+                                             need to completely traverse the list ... */
+
+        size_type size(iterator i, state_type s) const; ///< Number of elements in list
+                                        /**< Return the number of elements in the list. This
+                                             operation may be quite inefficient for some lists (the
+                                             list must be traversed to find that number. */
+
+        void init(iterator i, state_type s) const; ///< Initialize new list
+                                        /**< Called after init_size bytes have been allocated to
+                                             initialize the list. After init() is called, the list
+                                             is traversed to initialize any members (probably
+                                             none) */
+
+        void erase(iterator i, state_type s, iterator p) const; ///< Erase element from list
+                                        /**< Delete the list element at p from the List (i,s). When
+                                             this operation is called, the element is still part of
+                                             the list. This call must update the meta-data as
+                                             needed. The data will be removed after this call
+                                             returns. */
+
+        void insert(iterator i, state_type s, iterator p) const; ///< Insert element into list
+                                        /**< This is called after an element has been inserted at p
+                                             into the List (i,s) to update the meta-data. */
+
+        /** \brief Example of a list iterator policy. ONLY FOR EXPOSITION.
+
+            \see \ref ExampleListPolicy \n
+                \ref Parse_List
+         */
+        struct iterator_policy 
+        {
+            iterator setBegin(iterator i, state_type s); ///< Initialize iterator to begin()
+                                        /**< Initialize the policy from the given List (i,s). Set
+                                             the iterator to the beginning iterator. Return
+                                             data_iterator to the first element.
+
+                                             \warning if the list is empty, the returned iterator
+                                             \e must be the same as the one returned by setEnd. */
+
+            iterator setEnd(iterator i, state_type s); ///< Initialize iterator to end()
+                                        /**< Initialize the policy from the given List (i,s). Set
+                                             the iterator to the end iterator. Return data_iterator
+                                             used to mark the end of the range. This may be a
+                                             special sentinel value (e.g. data().end()) if
+                                             needed. */
+
+            void setFromPosition(iterator i, state_type s, iterator p); 
+                                        ///< Initialize iterator from the given raw position
+                                        /**< Set the iterator to the Element at raw position p. This
+                                             operation can potentially be very inefficient if the
+                                             list needs to be traversed from the beginning until the
+                                             iterator is found. */
+            
+            iterator next(iterator i, state_type s); ///< Advance to next element
+                                        /**< given an iterator to an element, go to the next
+                                             element. */
+
+            iterator raw(iterator i, state_type s); ///< Return raw position of element
+                                        /**< Given the iterator state (i,s), return the raw iterator
+                                             to the datum. This will be i in almost all cases EXCEPT
+                                             if a special sentinel value is used as end() value. In
+                                             this case, this member must return the real position
+                                             after the last element. */
+        };
+
+        /** \brief Example of a list container policy. ONLY FOR EXPOSITION
+            
+            \see \ref ExampleListPolicy \n
+                \ref Parse_List
+         */
+        struct container_policy
+        {
+            void init(iterator i, state_type s); ///< Initialize new container
+            void update(iterator i, state_type s); ///< Called before every container access
+        };
+    };
+
+}
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// mode: flyspell
+// mode: auto-fill
+// End:
index dc757bf..8eb9592 100644 (file)
@@ -103,156 +103,6 @@ namespace senf {
         template <class Policy> friend class Parse_List_Container;
     };
 
-    /** \brief Example of a list policy. ONLY FOR EXPOSITION.
-        
-        This class shows the interface which must be implemented by a list policy. It is not a list
-        policy only a declaration of the interface:
-        \code
-        struct ExampleListPolicy
-        {
-            // optional typedefs used to simplify all other declarations
-            typedef PacketParserBase::data_iterator data_iterator;
-            typedef PacketParserBase::state_type state_type;
-            typedef PacketParserBase::size_type size_type;
-
-            // mandatory typedefs in the parser and container policy
-            typedef ElementParser element_type;
-            typedef Parse_List< ExampleListPolicy > parser_type;
-            typedef Parse_List_Container< ExampleListPolicy > container_type;
-
-            // mandatory constant in parser and container policy
-            static const size_type init_bytes = 0;
-
-            // Members needed in the parser and the container policy
-            size_type bytes  (data_iterator i, state_type s) const;
-            size_type size   (data_iterator i, state_type s) const;
-            void      init   (data_iterator i, state_type s) const;
-        
-            // Members needed only in the container policy
-            void      erase  (data_iterator i, state_type s, iterator p) const;
-            void      insert (data_iterator i, state_type s, iterator p) const;
-
-            struct iterator_policy
-            {
-                iterator setBegin        (data_iterator i, state_type s);
-                iterator setEnd          (data_iterator i, state_type s);
-                void     setFromPosition (data_iterator i, state_type s, iterator p);
-                iterator next            (data_iterator i, state_type s);
-                iterator raw             (data_iterator i, state_type s) const;
-            };
-        };
-        \endcode
-
-        If necessary, you may use a different policy in the container_type. The ListPolicy must
-        define the elements bytes(), size() and init(), the container policy needs all these and
-        additionally needs erase() and insert(). The container policy will also need the
-        element_type, parser_type and container_type typedefs.
-        
-        \see \ref Parse_List
-     */
-    struct ExampleListPolicy
-    {
-        typedef PacketParserBase::data_iterator iterator;
-        typedef PacketParserBase::state_type state_type;
-        typedef PacketParserBase::size_type size_type;
-
-        typedef void element_type;      ///< Type of list elements
-                                        /**< This is the parser used to parse the list elements. */
-        typedef void parser_type;       ///< List parser type
-                                        /**< parser_type is the list parser used to parse a list of
-                                             this type,
-                                             e.g. <tt>senf::Parse_List<ExampleListPolicy></tt>. */
-        typedef void container_type;    ///< Type of container wrapper
-                                        /**< This is the container wrapper of the list, e.g.
-                                             <tt>Parse_List_Container<ExampleListPolicy></tt>. The
-                                             container may however use a \e different policy, as
-                                             long as that policy is constructible from the parser
-                                             policy. */
-
-        static const size_type init_bytes = 0; ///< Size of a new list of this type
-                                        /**< Initial size which needs to be allocated to this type
-                                             of list */
-
-        size_type bytes(iterator i, state_type s) const; ///< Size of list in bytes
-                                        /**< Return the complete size of the list in
-                                             bytes. Depending on the type of list, this call may
-                                             need to completely traverse the list ... */
-
-        size_type size(iterator i, state_type s) const; ///< Number of elements in list
-                                        /**< Return the number of elements in the list. This
-                                             operation may be quite inefficient for some lists (the
-                                             list must be traversed to find that number. */
-
-        void init(iterator i, state_type s) const; ///< Initialize new list
-                                        /**< Called after init_size bytes have been allocated to
-                                             initialize the list. After init() is called, the list
-                                             is traversed to initialize any members (probably
-                                             none) */
-
-        void erase(iterator i, state_type s, iterator p) const; ///< Erase element from list
-                                        /**< Delete the list element at p from the List (i,s). When
-                                             this operation is called, the element is still part of
-                                             the list. This call must update the meta-data as
-                                             needed. The data will be removed after this call
-                                             returns. */
-
-        void insert(iterator i, state_type s, iterator p) const; ///< Insert element into list
-                                        /**< This is called after an element has been inserted at p
-                                             into the List (i,s) to update the meta-data. */
-
-        /** \brief Example of a list iterator policy. ONLY FOR EXPOSITION.
-
-            \see \ref ExampleListPolicy \n
-                \ref Parse_List
-         */
-        struct iterator_policy 
-        {
-            iterator setBegin(iterator i, state_type s); ///< Initialize iterator to begin()
-                                        /**< Initialize the policy from the given List (i,s). Set
-                                             the iterator to the beginning iterator. Return
-                                             data_iterator to the first element.
-
-                                             \warning if the list is empty, the returned iterator
-                                             \e must be the same as the one returned by setEnd. */
-
-            iterator setEnd(iterator i, state_type s); ///< Initialize iterator to end()
-                                        /**< Initialize the policy from the given List (i,s). Set
-                                             the iterator to the end iterator. Return data_iterator
-                                             used to mark the end of the range. This may be a
-                                             special sentinel value (e.g. data().end()) if
-                                             needed. */
-
-            void setFromPosition(iterator i, state_type s, iterator p); 
-                                        ///< Initialize iterator from the given raw position
-                                        /**< Set the iterator to the Element at raw position p. This
-                                             operation can potentially be very inefficient if the
-                                             list needs to be traversed from the beginning until the
-                                             iterator is found. */
-            
-            iterator next(iterator i, state_type s); ///< Advance to next element
-                                        /**< given an iterator to an element, go to the next
-                                             element. */
-
-            iterator raw(iterator i, state_type s); ///< Return raw position of element
-                                        /**< Given the iterator state (i,s), return the raw iterator
-                                             to the datum. This will be i in almost all cases EXCEPT
-                                             if a special sentinel value is used as end() value. In
-                                             this case, this member must return the real position
-                                             after the last element. */
-        };
-
-        /** \brief Example of a list container policy. ONLY FOR EXPOSITION
-            
-            \see \ref ExampleListPolicy \n
-                \ref Parse_List
-         */
-        struct container_policy
-        {
-            void init(iterator i, state_type s); ///< Initialize new container
-            void update(iterator i, state_type s); ///< Called before every container access
-        };
-    };
-
     /** \brief Parse_List container wrapper
 
         This is the container wrapper used for list parsers. The container wrapper will stay valid
index 5fa118c..c8ee210 100644 (file)
@@ -65,6 +65,23 @@ namespace senf {
         typedef Parse_List< detail::Parse_ListB_Policy<ElementParser,BytesParser> > parser;
     };
 
+    /** \brief Define Parse_ListB field
+
+        This macro is a special helper to define a senf::Parse_ListB type field, a list of elements
+        of type \a elt_type (a parser type) directly preceded by a numeric size field of type \a
+        size_type (another parser type) giving the total number of bytes of the list (not the
+        element count).
+
+        \param[in] name field name
+        \param[in] elt_type list element type
+        \param[in] size_type size type
+        \hideinitializer
+        \ingroup packetparsermacros
+     */
+#    define SENF_PARSER_LIST_B(name, elt_type, size_type)                                         \
+        typedef senf::Parse_ListB<elt_type, size_type>::parser BOOST_PP_CAT(name, _list_t);       \
+        SENF_PARSER_FIELD( name, BOOST_PP_CAT(name, _list_t) )
+
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
index 28524bc..18c5f4b 100644 (file)
@@ -55,6 +55,22 @@ namespace senf {
         typedef Parse_List< detail::Parse_ListN_Policy<ElementParser,SizeParser> > parser;
     };
 
+    /** \brief Define Parse_ListN field
+
+        This macro is a special helper to define a senf::Parse_ListN type field, a list of elements
+        of type \a elt_type (a parser type) directly preceded by a numeric size field of type \a
+        size_type (another parser type).
+
+        \param[in] name field name
+        \param[in] elt_type list element type
+        \param[in] size_type size type
+        \hideinitializer
+        \ingroup packetparsermacros
+     */
+#    define SENF_PARSER_LIST_N(name, elt_type, size_type)                                         \
+        typedef senf::Parse_ListN<elt_type, size_type>::parser BOOST_PP_CAT(name, _list_t);       \
+        SENF_PARSER_FIELD( name, BOOST_PP_CAT(name, _list_t) )
+
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
diff --git a/Packets/ParseVariant.ct b/Packets/ParseVariant.ct
new file mode 100644 (file)
index 0000000..d147776
--- /dev/null
@@ -0,0 +1,71 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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 ParseVariant non-inline template implementation  */
+
+#include "ParseVariant.ih"
+
+// Custom includes
+#include <algorithm>
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
+template <unsigned N>
+prefix_ void senf::Parse_Variant<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::init()
+{
+    unsigned oldSize( bytes() );
+    typedef typename boost::mpl::at<parsers, boost::mpl::int_<N> >::type NewParser;
+
+    if (oldSize < senf::init_bytes<NewParser>::value) {
+        data_iterator j (i());
+        std::advance(j, oldSize);
+        std::fill(i(), j, 0u);
+        safe_data_iterator safe_i (*this);
+        data().insert(j, senf::init_bytes<NewParser>::value - oldSize, 0u);
+        VariantPolicy::variant(N, safe_i, state());
+        NewParser( VariantPolicy::begin(safe_i, state()), state() ).init();
+    } else {
+        data_iterator j (i());
+        std::advance(j, senf::init_bytes<NewParser>::value);
+        data().erase(j, boost::next(i(), oldSize));
+        std::fill(i(), j, 0u);
+        VariantPolicy::variant(N, i(), state());
+        NewParser(VariantPolicy::begin(i(), state()), state()).init();
+    }
+}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Packets/ParseVariant.cti b/Packets/ParseVariant.cti
new file mode 100644 (file)
index 0000000..f3ca98e
--- /dev/null
@@ -0,0 +1,118 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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 ParseVariant inline template implementation */
+
+#include "ParseVariant.ih"
+
+// Custom includes
+#include <boost/mpl/size.hpp>
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::Parse_Variant<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>
+
+template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
+prefix_ senf::Parse_Variant<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::
+Parse_Variant(data_iterator i, state_type s)
+    : PacketParserBase(i,s)
+{}
+
+template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
+prefix_ senf::Parse_Variant<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::
+Parse_Variant(VariantPolicy policy, data_iterator i, state_type s)
+    : PacketParserBase(i,s), VariantPolicy(policy)
+{}
+
+template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
+prefix_ senf::PacketParserBase::size_type
+senf::Parse_Variant<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::bytes()
+    const
+{
+    return detail::VariantBytes< Parse_Variant, boost::mpl::size<parsers>::value - 1 >
+        ::bytes(*this, variant()) + VariantPolicy::bytes(i(),state());
+}
+
+template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
+prefix_ void
+senf::Parse_Variant<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::init()
+{
+    VariantPolicy::variant(0,i(),state());
+    get<0>().init();
+}
+
+template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
+prefix_ unsigned senf::Parse_Variant<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::variant()
+    const
+{
+    return VariantPolicy::variant(i(),state());
+}
+
+template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS(class P)>
+template <unsigned N>
+prefix_ typename boost::mpl::at<
+    typename senf::Parse_Variant<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::parsers, 
+    boost::mpl::int_<N> >::type
+senf::Parse_Variant<VariantPolicy,SENF_PARSE_VARIANT_TPL_ARGS(P)>::get()
+    const
+{
+    BOOST_ASSERT( variant() == N );
+    return typename boost::mpl::at<parsers, boost::mpl::int_<N> >::type(
+        VariantPolicy::begin(i(), state()), state() );
+}
+
+/////////////////////////////////////////////////////////////////////////
+// senf::detail::VariantBytes<Variant,N>
+
+template <class Variant, unsigned N>
+prefix_ senf::PacketParserBase::size_type
+senf::detail::VariantBytes<Variant,N>::bytes(Variant const & v, unsigned n)
+{
+    if (n == N)
+        return senf::bytes(v.template get<N>());
+    else
+        return VariantBytes<Variant, N-1>::bytes(v, n);
+}
+
+template <class Variant>
+prefix_ senf::PacketParserBase::size_type
+senf::detail::VariantBytes<Variant,0>::bytes(Variant const & v, unsigned n)
+{
+    return senf::bytes(v.template get<0>());
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Packets/ParseVariant.dox b/Packets/ParseVariant.dox
new file mode 100644 (file)
index 0000000..d9153e5
--- /dev/null
@@ -0,0 +1,53 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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.
+
+namespace senf {
+
+    struct ExampleVariantPolicy
+    {
+        // optional typedefs used to simplify all other declarations
+        typedef PacketParserBase::data_iterator data_iterator;
+        typedef PacketParserBase::state_type state_type;
+        typedef PacketParserBase::size_type size_type;
+
+        static size_type const init_bytes = 0;
+        size_type bytes  (data_iterator i, state_type s) const;
+        data_iterator begin(data_iterator i, state_type s) const;
+
+        unsigned variant (data_iterator i, state_type s) const;
+        void variant     (unsigned v, data_iterator i, state_type s);
+    };
+
+}
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// mode: flyspell
+// mode: auto-fill
+// End:
diff --git a/Packets/ParseVariant.hh b/Packets/ParseVariant.hh
new file mode 100644 (file)
index 0000000..84564a4
--- /dev/null
@@ -0,0 +1,132 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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 ParseVariant public header */
+
+#ifndef HH_ParseVariant_
+#define HH_ParseVariant_ 1
+
+#ifndef HH_Packets_
+#error "Don't include 'ParseVariant.hh' directly, include 'Packets.hh'"
+#endif
+
+// Custom includes
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/seq/for_each.hpp>
+#include "PacketParser.hh"
+
+//#include "ParseVariant.mpp"
+#include "ParseVariant.ih"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+
+#   ifndef SENF_LIMIT_PARSER_VARIANT
+#       define SENF_LIMIT_PARSE_VARIANT 10
+#   endif
+
+#   define SENF_PARSE_VARIANT_TPL_ARGS_DFL(n)                                                     \
+        BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SENF_LIMIT_PARSE_VARIANT,                            \
+                                             n,                                                   \
+                                             boost::mpl::na )
+
+#   define SENF_PARSE_VARIANT_TPL_ARGS(n) BOOST_PP_ENUM_PARAMS( SENF_LIMIT_PARSE_VARIANT, n )
+
+    template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
+    class Parse_Variant 
+        : public PacketParserBase, private VariantPolicy
+    {
+        typedef boost::mpl::vector< SENF_PARSE_VARIANT_TPL_ARGS(P) > parsers;
+
+    public:
+        Parse_Variant(data_iterator i, state_type s);
+        Parse_Variant(VariantPolicy policy, data_iterator i, state_type s);
+
+        size_type bytes() const;
+        void init();
+        
+        static const size_type init_bytes = 
+            senf::init_bytes<P0>::value + VariantPolicy::init_bytes;
+
+        ///////////////////////////////////////////////////////////////////////////
+
+        unsigned variant() const;
+        
+        template <unsigned N>
+        typename boost::mpl::at< parsers, boost::mpl::int_<N> >::type get() const;
+
+        template <unsigned N>
+        void init();
+
+    private:
+    };
+
+    template <class ChooserType, unsigned Distance, SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
+    struct Parse_Variant_Direct
+    {
+        typedef Parse_Variant< detail::Parse_Variant_Direct<ChooserType, Distance>,
+                               SENF_PARSE_VARIANT_TPL_ARGS(P) > parser;
+    };
+
+#   define SENF_PARSER_VARIANT_(r, data, elem) ,elem
+
+#   define SENF_PARSER_VARIANT(name, chooser, types)                                              \
+        typedef senf::Parse_Variant_Direct<                                                       \
+            BOOST_PP_CAT(chooser, _t),                                                            \
+            SENF_PARSER_CURRENT_FIXED_OFFSET() - SENF_PARSER_FIXED_OFFSET(chooser)                \
+            BOOST_PP_SEQ_FOR_EACH( SENF_PARSER_VARIANT_, _, types )                               \
+            >::parser BOOST_PP_CAT(name, _variant_t);                                             \
+        SENF_PARSER_FIELD( name, BOOST_PP_CAT(name, _variant_t) )
+
+#   define SENF_PARSER_PRIVATE_VARIANT(name, chooser, types)                                      \
+        typedef senf::Parse_Variant_Direct<                                                       \
+            BOOST_PP_CAT(chooser, _t),                                                            \
+            SENF_PARSER_CURRENT_FIXED_OFFSET() - SENF_PARSER_FIXED_OFFSET(chooser)                \
+            BOOST_PP_SEQ_FOR_EACH( SENF_PARSER_VARIANT_, _, types )                               \
+            >::parser BOOST_PP_CAT(name, _variant_t);                                             \
+        SENF_PARSER_PRIVATE_FIELD( name, BOOST_PP_CAT(name, _variant_t) )
+
+}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(HH_Packets__decls_) && !defined(HH_ParseVariant_i_)
+#define HH_ParseVariant_i_
+//#include "ParseVariant.cci"
+#include "ParseVariant.ct"
+#include "ParseVariant.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Packets/ParseVariant.ih b/Packets/ParseVariant.ih
new file mode 100644 (file)
index 0000000..c022af5
--- /dev/null
@@ -0,0 +1,85 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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 ParseVariant internal header */
+
+#ifndef IH_ParseVariant_
+#define IH_ParseVariant_ 1
+
+// Custom includes
+#include "PacketParser.hh"
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace senf {
+namespace detail {
+
+    template <class Variant, unsigned N>
+    struct VariantBytes {
+        static PacketParserBase::size_type bytes(Variant const & v, unsigned n);
+    };
+
+    template <class Variant>
+    struct VariantBytes<Variant,0> {
+        static PacketParserBase::size_type bytes(Variant const & v, unsigned n);
+    };
+    
+    template <class ChooserType, unsigned Distance>
+    struct Parse_Variant_Direct
+    {
+        typedef PacketParserBase::data_iterator data_iterator;
+        typedef PacketParserBase::state_type state_type;
+        typedef PacketParserBase::size_type size_type;
+
+        static size_type const init_bytes = 0;
+        size_type bytes(data_iterator i, state_type s) const { return 0; }
+        data_iterator begin(data_iterator i, state_type s) const { return i; }
+
+        ChooserType chooser(data_iterator i, state_type s) const {
+            return ChooserType(boost::prior(i, Distance),s);
+        }
+        
+        unsigned variant(data_iterator i, state_type s) const {
+            return chooser(i,s).value();
+        }
+
+        void variant(unsigned v, data_iterator i, state_type s) {
+            chooser(i,s).value(v);
+        }
+    };
+
+}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Packets/ParseVariant.test.cc b/Packets/ParseVariant.test.cc
new file mode 100644 (file)
index 0000000..feac293
--- /dev/null
@@ -0,0 +1,144 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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 ParseVariant.test unit tests */
+
+//#include "ParseVariant.test.hh"
+//#include "ParseVariant.test.ih"
+
+// Custom includes
+#include "Packets.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(parseVariant)
+{
+    typedef senf::Parse_Array<10, senf::Parse_UInt8> Array10;
+    typedef senf::Parse_Variant_Direct< senf::Parse_UInt8, 1, 
+        senf::VoidPacketParser,
+        Array10, 
+        senf:: Parse_UInt32 
+        >::parser Variant;
+    
+    unsigned char data[] = { 0x01, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+                             0x19, 0x1A, 0x1B };
+    senf::DataPacket p (senf::DataPacket::create(data));
+    {
+        Variant v ( boost::next(p.data().begin()), & p.data() );
+        BOOST_REQUIRE_EQUAL( v.variant(), 1u );
+        BOOST_CHECK_EQUAL( senf::bytes(v), 10u );
+        BOOST_CHECK_EQUAL_COLLECTIONS( v.get<1>().begin(), v.get<1>().end(),
+                                       data+1, data+11 );
+        v.init();
+        // The container size should not change in this case but now variant should be 0 ...
+        BOOST_REQUIRE_EQUAL( p.data().size(), 11u );
+        BOOST_REQUIRE_EQUAL( v.variant(), 0u );
+        BOOST_CHECK_EQUAL( senf::bytes(v), 0u );
+        
+        v.init<2>();
+        // v invalidated
+    }
+    {
+        Variant v ( boost::next(p.data().begin()), & p.data() );
+
+        BOOST_CHECK_EQUAL( p.data()[0], 2u );
+        BOOST_REQUIRE_EQUAL( v.variant(), 2u );
+        BOOST_CHECK_EQUAL( senf::bytes(v), 4u );
+
+        unsigned char data2[] = { 0x02, 0x00, 0x00, 0x00, 0x00,
+                                  0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+                                  0x19, 0x1A, 0x1B };
+        BOOST_CHECK_EQUAL_COLLECTIONS( p.data().begin(), p.data().end(),
+                                       data2, data2+sizeof(data2) );
+        BOOST_CHECK_EQUAL( v.get<2>().value(), 0u );
+        BOOST_CHECK_EQUAL( p.data().size(), 15u );
+        p.data()[4] = 0x01u;
+        BOOST_CHECK_EQUAL( v.get<2>().value(), 1u );
+    };
+}
+
+namespace {
+    
+    struct SubParser : public senf::PacketParserBase
+    { 
+#       include SENF_FIXED_PARSER()
+
+        SENF_PARSER_FIELD( foo, senf::Parse_UInt32 );
+        SENF_PARSER_FIELD( bar, senf::Parse_Int16 );
+
+        SENF_PARSER_FINALIZE(SubParser);
+    };
+
+    struct TestParser : public senf::PacketParserBase
+    {
+#       include SENF_PARSER()
+        
+        SENF_PARSER_SKIP_BITS( 4 );
+        SENF_PARSER_PRIVATE_BITFIELD( type_, 4, unsigned );
+        SENF_PARSER_PRIVATE_VARIANT( content_, type_, (senf::VoidPacketParser)(SubParser) );
+
+        bool hasContent() const { return content_().variant() == 1; }
+        void hasContent(bool v) const { if (v) content_().init<1>(); else content_().init<0>(); }
+        SubParser content() const { return content_().get<1>(); }
+
+        SENF_PARSER_FINALIZE(TestParser);
+    };
+    
+}
+
+BOOST_AUTO_UNIT_TEST(parseVariantMacro)
+{
+    senf::DataPacket p (senf::DataPacket::create(senf::init_bytes<TestParser>::value));
+    
+    {
+        TestParser v (p.data().begin(), & p.data());
+    
+        BOOST_CHECK( ! v.hasContent() );
+        BOOST_CHECK_EQUAL( senf::bytes(v), 1u );
+        v.hasContent(true);
+    }
+    {
+        TestParser v (p.data().begin(), & p.data());
+        BOOST_CHECK( v.hasContent() );
+        BOOST_CHECK_EQUAL( senf::bytes(v), 7u );
+        BOOST_CHECK_EQUAL( v.content().foo(), 0u );
+    }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Packets/ParseVec.dox b/Packets/ParseVec.dox
new file mode 100644 (file)
index 0000000..f496f36
--- /dev/null
@@ -0,0 +1,94 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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.
+
+namespace senf {
+
+    /** \brief Example vector sizer. ONLY FOR EXPOSITION
+
+        This class shows the interface which must be implemented by a vector sizer policy. It is not
+        a vector sizer, it is only a declaration of the interface:
+        \code
+        struct ExampleVectorPolicy
+        {
+            // optional typedefs used to simplify all other declarations
+            typedef PacketParserBase::size_type size_type;
+            typedef PacketParserBase::data_iterator iterator;
+            typedef PacketParserBase::state_type state_type;
+
+            // mandatory members
+            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;
+        };
+        \endcode
+
+        A sizer may if needed define additional data members.
+     */
+    struct ExampleVectorPolicy
+    {
+        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 of a new vector of this size
+                                        /**< Initial size which needs to be allocated to this type
+                                             of list */
+
+        size_type  size  (iterator i, state_type s) const; ///< Get current vector size
+                                        /**< Return the current number of elements in the 
+                                             vector. */
+        void       size  (iterator i, state_type s, size_type v) const; ///< Change vector size
+                                        /**< Set the size of the vector to \a v. */
+        iterator   begin (iterator i, state_type s) const; 
+                                        ///< Return data_iterator to first element
+                                        /**< The returned data_iterator must point to the beginning
+                                             of the first vector element. The last iterator can than
+                                             automatically be calculated from the fixed element size
+                                             and the number of vector elements. */
+        size_type  bytes (iterator i, state_type s) const; ///< Bytes taken by the vector size
+                                        /**< Return the additional size which needs to be added to
+                                             the size of the vector data (calculated form \c size()
+                                             * <em>ElementType::fixed_bytes</em>) to get the size of
+                                             the complete vector. This may be zero if the size is
+                                             not considered part of the vector. */
+        void       init  (iterator i, state_type s) const; ///< Initialize new vector
+                                        /** Called to initialize a new vector after allocating
+                                            init_bytes number of bytes for the vector. */
+    };
+
+}
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// mode: flyspell
+// mode: auto-fill
+// End:
index ded220a..beb953f 100644 (file)
@@ -137,59 +137,21 @@ namespace senf {
                               detail::Parse_VectorN_Sizer<SizeParser> > parser;
     };
 
-    /** \brief Example vector sizer. ONLY FOR EXPOSITION
-
-        This class shows the interface which must be implemented by a vector sizer policy. It is not
-        a vector sizer, it is only a declaration of the interface:
-        \code
-        struct ExampleVectorPolicy
-        {
-            // optional typedefs used to simplify all other declarations
-            typedef PacketParserBase::size_type size_type;
-            typedef PacketParserBase::data_iterator iterator;
-            typedef PacketParserBase::state_type state_type;
-
-            // mandatory members
-            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;
-        };
-        \endcode
-
-        A sizer may if needed define additional data members.
+    /** \brief Define Parse_VectorN field
+        
+        This macro is a special helper to define a senf::Parse_VectorN type field, a vector of
+        elements of type \a elt_type (a parser) directly preceded by a numeric size field of type \a
+        size_type (another parser).
+        
+        \param[in] name field name
+        \param[in] elt_type vector element type
+        \param[in] size_type size type
+        \hideinitializer
+        \ingroup packetparsermacros
      */
-    struct ExampleVectorPolicy
-    {
-        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 of a new vector of this size
-                                        /**< Initial size which needs to be allocated to this type
-                                             of list */
-
-        size_type  size  (iterator i, state_type s) const; ///< Get current vector size
-                                        /**< Return the current number of elements in the 
-                                             vector. */
-        void       size  (iterator i, state_type s, size_type v) const; ///< Change vector size
-                                        /**< Set the size of the vector to \a v. */
-        iterator   begin (iterator i, state_type s) const; 
-                                        ///< Return data_iterator to first element
-                                        /**< The returned data_iterator must point to the beginning
-                                             of the first vector element. The last iterator can than
-                                             automatically be calculated from the fixed element size
-                                             and the number of vector elements. */
-        size_type  bytes (iterator i, state_type s) const; ///< Size of vector parser
-                                        /**< Return the size of the complete vector in bytes. This
-                                             is not necessarily the same as \c size() * \e
-                                             fixed_element_bytes. */
-        void       init  (iterator i, state_type s) const; ///< Initialize new vector
-                                        /** Called to initialize a new vector after allocating
-                                            init_bytes number of bytes for the vector. */
-    };
+#   define SENF_PARSER_VEC_N(name, elt_type, size_type)                                           \
+        typedef senf::Parse_VectorN<elt_type, size_type>::parser BOOST_PP_CAT(name, _vec_t);      \
+        SENF_PARSER_FIELD( name, BOOST_PP_CAT(name, _vec_t) )
 
     /** \brief Parse_Vector container wrapper