Packets: Add additional parse helper macros
g0dil [Tue, 16 Oct 2007 12:46:33 +0000 (12:46 +0000)]
Packets: Add parse helper unit-test

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

Packets/ParseHelpers.hh
Packets/ParseHelpers.ih
Packets/ParseHelpers.test.cc [new file with mode: 0644]

index 9fc6cc0..46bb7b5 100644 (file)
 #define SENF_PARSE_BITFIELD     BOOST_PP_CAT( SENF_PARSE_BITFIELD_     , SENF_PARSER_TYPE )
 #define SENF_PARSE_BITFIELD_RO  BOOST_PP_CAT( SENF_PARSE_BITFIELD_RO_  , SENF_PARSER_TYPE )
 
-#define SENF_PARSER_FINALIZE    BOOST_PP_CAT( SENF_PARSER_FINALIZE_    , SENF_PARSER_TYPE )
-
 #define SENF_PARSER_SKIP        BOOST_PP_CAT( SENF_PARSER_SKIP_        , SENF_PARSER_TYPE )
 #define SENF_PARSER_GOTO        BOOST_PP_CAT( SENF_PARSER_GOTO_        , SENF_PARSER_TYPE )
 #define SENF_PARSER_GOTO_OFFSET BOOST_PP_CAT( SENF_PARSER_GOTO_OFFSET_ , SENF_PARSER_TYPE )
 
 #define SENF_PARSER_INIT()      void init(int)
 
+#define SENF_PARSER_FINALIZE    BOOST_PP_CAT( SENF_PARSER_FINALIZE_    , SENF_PARSER_TYPE )
+
 ///////////////////////////////hh.e////////////////////////////////////////
 #endif
 #if !defined(HH_Packets__decls_) && !defined(HH_ParseHelpers_i_)
index 8b76054..4b381e1 100644 (file)
@@ -63,9 +63,9 @@
         SENF_MPL_SLOT_SET(index, 1);                                                              \
         SENF_MPL_SLOT_SET(init_bytes, senf::init_bytes<name>::value);                             \
         size_type field_offset_(senf::mpl::rv<1>*) const {                                        \
-            return senf::bytes( *static_cast<name*>(this) );                                      \
+            return senf::bytes( *static_cast<name const*>(this) );                                \
         }                                                                                         \
-        void init_chain(senf::mpl::rv<inherit_index_>*) {                                         \
+        void init_chain(senf::mpl::rv<1>*) {                                                      \
             name::init();                                                                         \
         }                                                                                         \
     public:
 # ///////////////////////////////////////////////////////////////////////////
 # // SENF_PARSE_FIELD_*
 #
-# define SENF_PARSE_FIELD_var(name, type)    SENF_PARSER_FIELD_I(name, type, var, rw)
-# define SENF_PARSE_FIELD_RO_var(name, type) SENF_PARSER_FIELD_I(name, type, var, ro)
+# define SENF_PARSE_FIELD_var(name, type)    SENF_PARSER_FIELD_I(name, type, var, rw, public)
+# define SENF_PARSE_FIELD_RO_var(name, type) SENF_PARSER_FIELD_I(name, type, var, ro, public)
 #
-# define SENF_PARSE_FIELD_fix(name, type)    SENF_PARSER_FIELD_I(name, type, fix, rw)
-# define SENF_PARSE_FIELD_RO_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, ro)
+# define SENF_PARSE_FIELD_fix(name, type)    SENF_PARSER_FIELD_I(name, type, fix, rw, public)
+# define SENF_PARSE_FIELD_RO_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, ro, public)
 #
-# define SENF_PARSER_FIELD_I(name, type, ofstype, rwtype)                                         \
+# define SENF_PARSER_FIELD_I(name, type, ofstype, rwtype, access)                                 \
+    access:                                                                                       \
         SENF_PARSER_I_BITFIELD_RESET()                                                            \
-        SENF_PARSER_I_FIELD_INTRO(name, type)                                                     \
-        BOOST_PP_CAT(SENF_PARSER_I_FIELD_INIT_, rwtype) (name, type)                              \
-        BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type)                              \
+        SENF_PARSER_I_FIELD_INTRO(name, type, access)                                             \
+        BOOST_PP_CAT(SENF_PARSER_I_FIELD_INIT_, rwtype) (name, type, access)                      \
+        BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                      \
         BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (                                       \
             name, type,                                                                           \
             BOOST_PP_CAT(SENF_PARSER_I_SIZE_, ofstype) (name, type),                              \
-            BOOST_PP_CAT(SENF_PARSER_I_INITBYTES_, ofstype) (name, type) )                        \
-        BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, ofstype)
+            BOOST_PP_CAT(SENF_PARSER_I_INITBYTES_, ofstype) (name, type),                         \
+            access )                                                                              \
+        BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, ofstype, access)              \
+    public:
 #
 # ////////////////////////////////////////
 # // SENF_PARSER_I_FIELD_INTRO
 #
-# define SENF_PARSER_I_FIELD_INTRO(name, type)                                                    \
+# define SENF_PARSER_I_FIELD_INTRO(name, type, access)                                            \
         typedef type BOOST_PP_CAT(name, _t);                                                      \
         static size_type const BOOST_PP_CAT(name,_index) = SENF_MPL_SLOT_GET(index)+1;            \
     private:                                                                                      \
         SENF_MPL_SLOT_SET(index, BOOST_PP_CAT(name,_index));                                      \
-    public:
+    access:
 #
 # ////////////////////////////////////////
 # // SENF_PARSER_I_FIELD_INIT_*
 #
-# define SENF_PARSER_I_FIELD_INIT_rw(name, type)                                                  \
+# define SENF_PARSER_I_FIELD_INIT_rw(name, type, access)                                                  \
     private:                                                                                      \
         void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) {                              \
             init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));              \
             name().init();                                                                        \
         }                                                                                         \
-    public:
+    access:
 #
-# define SENF_PARSER_I_FIELD_INIT_ro(name, type)                                                  \
+# define SENF_PARSER_I_FIELD_INIT_ro(name, type, access)                                                  \
     private:                                                                                      \
         void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) {                              \
             init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));              \
         }                                                                                         \
-    public:
+    access:
 #
-# define SENF_PARSER_I_FIELD_OFS_var(name, type)                                                  \
+# ////////////////////////////////////////
+# // SENF_PARSER_I_FIELD_OFS_*
+#
+# define SENF_PARSER_I_FIELD_OFS_var(name, type, access)                                          \
         size_type BOOST_PP_CAT(name,_offset)() const {                                            \
             return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));    \
         }
 #
-# ////////////////////////////////////////
-# // SENF_PARSER_I_FIELD_OFS_*
-#
-# define SENF_PARSER_I_FIELD_OFS_fix(name, type)                                                  \
+# define SENF_PARSER_I_FIELD_OFS_fix(name, type, access)                                          \
         static size_type const BOOST_PP_CAT(name, _offset) = SENF_MPL_SLOT_GET(offset);
 #
-# define SENF_PARSER_FINALIZE_GENERIC(name)                                                       \
-         void defaultInit() {                                                                     \
-             init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));                \
-         }                                                                                        \
-         name(data_iterator i, state_type s) : parser_base_type(i,s) {}                           \
-    private:                                                                                      \
-         template <class T> void init(T) { defaultInit(); }                                       \
-    public:                                                                                       \
-         void init() { init(0); }
-#
 # ////////////////////////////////////////
 # // SENF_PARSER_I_ADVANCE_OFS_*
 #
-# define SENF_PARSER_I_SIZE_var(name, type) senf::bytes(name())
+# // 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_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)                                   \
+# define SENF_PARSER_I_ADVANCE_OFS_var(name, type, size, isize, access)                           \
         size_type BOOST_PP_CAT(name, _next_offset)() const {                                      \
             return BOOST_PP_CAT(name,_offset)() + size;                                           \
         }                                                                                         \
             return BOOST_PP_CAT(name, _next_offset)();                                            \
         }                                                                                         \
         SENF_MPL_SLOT_SET(init_bytes, BOOST_PP_CAT(name,_next_init_bytes));                       \
-    public:
+    access:
 #
-# define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize)                                   \
+# define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize, access)                           \
         static size_type const BOOST_PP_CAT(name, _next_offset) =                                 \
             BOOST_PP_CAT(name, _offset) + size;                                                   \
     private:                                                                                      \
         SENF_MPL_SLOT_SET(offset, BOOST_PP_CAT(name, _next_offset));                              \
-    public:
+    access:
 #
 # ////////////////////////////////////////
 # // SENF_PARSER_I_FIELD_VAL_*
 # define SENF_PARSER_I_MAYBECALL_var() ()
 # define SENF_PARSER_I_MAYBECALL_fix()
 #
-# define SENF_PARSER_I_FIELD_VAL_rw(name,type,ofstype)                                            \
+# define SENF_PARSER_I_FIELD_VAL_rw(name, type, ofstype, access)                                  \
         BOOST_PP_CAT(name, _t) name() const {                                                     \
             return parse<type>(                                                                   \
                 BOOST_PP_CAT(name,_offset) BOOST_PP_CAT(SENF_PARSER_I_MAYBECALL_, ofstype)());    \
         }
 #
-# define SENF_PARSER_I_FIELD_VAL_ro(name,type,ofstype)                                            \
+# define SENF_PARSER_I_FIELD_VAL_ro(name, type, ofstype, access)                                  \
         BOOST_PP_CAT(name, _t)::value_type name() const {                                         \
             return parse<type>(                                                                   \
-                BOOST_PP_CAT(name,_offset) BOOST_PP_CAT(SENF_PARSER_I_MAYBECALL_, ofstype)()      \
-                    .value()                                                                      \
+                BOOST_PP_CAT(name,_offset) BOOST_PP_CAT(SENF_PARSER_I_MAYBECALL_, ofstype)())     \
+                    .value();                                                                     \
         }
 #
 # ///////////////////////////////////////////////////////////////////////////
 #
 # define SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, ofstype)                             \
         SENF_PARSER_I_BITFIELD_RESET()                                                            \
-        SENF_PARSER_I_FIELD_INTRO(name, type)                                                     \
-        SENF_PARSER_I_FIELD_INIT_ro(name, type)                                                   \
-        BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type)                              \
-        BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize)               \
+        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(name, _t) name() const
 #
 # ///////////////////////////////////////////////////////////////////////////
 # // SENF_PARSE_BITFIELD_*
 #
 # define SENF_PARSE_BITFIELD_var(name, bits, type)                                                \
-      SENF_PARSER_BITFIELD_I(name, bits, type, var, rw)
+      SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, public)
 # define SENF_PARSE_BITFIELD_RO_var(name, bits, type)                                             \
-      SENF_PARSER_BITFIELD_I(name, bits, type, var, ro)
+      SENF_PARSER_BITFIELD_I(name, bits, type, var, ro, public)
 #
 # define SENF_PARSE_BITFIELD_fix(name, bits, type)                                                \
-      SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw)
+      SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, public)
 # define SENF_PARSE_BITFIELD_RO_fix(name, bits, type)                                             \
-      SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro)
+      SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro, public)
 #
 # ////////////////////////////////////////
 # // SENF_PARSER_BITFIELD_I
 # define SENF_PARSER_BITFIELD_TYPE_unsigned(start, bits) senf::Parse_UIntField<start, start+bits>
 # define SENF_PARSER_BITFIELD_TYPE_bool(start, bits)     senf::Parse_Flag<start>
 #
-# define SENF_PARSER_BITFIELD_I(name, bits, type, ofstype, rwtype)                                \
+# define SENF_PARSER_BITFIELD_I(name, bits, type, ofstype, rwtype, access)                        \
+    access:                                                                                       \
         static size_type const BOOST_PP_CAT(name, _bit) = SENF_MPL_SLOT_GET(bit);                 \
     private:                                                                                      \
         SENF_MPL_SLOT_SET(bit, BOOST_PP_CAT(name, _bit) + bits);                                  \
         typedef BOOST_PP_CAT(SENF_PARSER_BITFIELD_TYPE_, type)( BOOST_PP_CAT(name, _bit), bits )  \
              BOOST_PP_CAT(name,_bit_t );                                                          \
-    public:                                                                                       \
-        SENF_PARSER_BITFIELD_II( name, bits, BOOST_PP_CAT(name, _bit_t), ofstype, rwtype)
+    access:                                                                                       \
+        SENF_PARSER_BITFIELD_II( name, bits, BOOST_PP_CAT(name, _bit_t), ofstype, rwtype, access) \
+    public:
 #
-# define SENF_PARSER_BITFIELD_II(name, bits, type, ofstype, rwtype)                               \
-         SENF_PARSER_I_FIELD_INTRO(name, type)                                                    \
-         SENF_PARSER_I_FIELD_INIT_ro(name, type)                                                  \
-         BOOST_PP_CAT(SENF_PARSER_I_BITFIELD_OFS_, ofstype) (name, type)                          \
+# define SENF_PARSER_BITFIELD_II(name, bits, type, ofstype, rwtype, access)                       \
+         SENF_PARSER_I_FIELD_INTRO(name, type, access)                                            \
+         SENF_PARSER_I_FIELD_INIT_ro(name, type, access)                                          \
+         BOOST_PP_CAT(SENF_PARSER_I_BITFIELD_OFS_, ofstype) (name, type, access)                  \
          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 )           \
+             BOOST_PP_CAT(name, _t)::fixed_bytes, BOOST_PP_CAT(name, _t)::fixed_bytes,            \
+             access)                                                                              \
     private:                                                                                      \
          SENF_MPL_SLOT_SET(bitfield_size, BOOST_PP_CAT(name, _t)::fixed_bytes);                   \
-    public:                                                                                       \
-         BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, ofstype)
+    access:                                                                                       \
+         BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, ofstype, access)             \
+    public:
 #
 # ////////////////////////////////////////
 # // SENF_PARSER_I_BITFIELD_OFS_*
 #
-# define SENF_PARSER_I_BITFIELD_OFS_var(name, type)                                               \
+# define SENF_PARSER_I_BITFIELD_OFS_var(name, type, access)                                       \
         size_type BOOST_PP_CAT(name,_offset)() const {                                            \
             return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0))     \
                 - SENF_MPL_SLOT_GET(bitfield_size);                                               \
         }
 #
-# define SENF_PARSER_I_BITFIELD_OFS_fix(name, type)                                               \
+# define SENF_PARSER_I_BITFIELD_OFS_fix(name, type, access)                                       \
         static size_type const BOOST_PP_CAT(name, _offset) = SENF_MPL_SLOT_GET(offset)            \
             - SENF_MPL_SLOT_GET(bitfield_size);
 #
     SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
     static size_type const fixed_bytes = SENF_MPL_SLOT_GET(offset);
 #
-# define SENF_PARSER_SKIP_var
-# define SENF_PARSER_SKIP_fix
+# define SENF_PARSER_FINALIZE_GENERIC(name)                                                       \
+         void defaultInit() {                                                                     \
+             init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));                \
+         }                                                                                        \
+         name(data_iterator i, state_type s) : parser_base_type(i,s) {}                           \
+    private:                                                                                      \
+         template <class T> void init(T) { defaultInit(); }                                       \
+    public:                                                                                       \
+         void init() { init(0); }
+#
+# ///////////////////////////////////////////////////////////////////////////
+# // SENF_PARSER_SKIP_*
 #
-# define SENF_PARSER_GOTO_var
-# define SENF_PARSER_GOTO_fix
+# define SENF_PARSER_SKIP_var(bytes, ibytes)                                                      \
+      SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, ibytes, var)
 #
-# define SENF_PARSER_GOTO_OFFSET_var
-# define SENF_PARSER_GOTO_OFFSET_fix
+# define SENF_PARSER_SKIP_fix(bytes)                                                              \
+      SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, bytes, fix)
 #
-# define SENF_PARSER_LABEL_var
-# define SENF_PARSER_LABEL_fix
+# define SENF_PARSER_I_SKIP(name, bytes, ibytes, ofstype)                                         \
+    private:                                                                                      \
+          SENF_PARSER_I_BITFIELD_RESET()                                                          \
+          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)  \
+    public:
+#
+# ///////////////////////////////////////////////////////////////////////////
+# // SENF_PARSER_GOTO_*
+#
+# define SENF_PARSER_GOTO_var(name)                                                               \
+      SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__),                                     \
+                          BOOST_PP_CAT(name, _offset)(),                                          \
+                          BOOST_PP_CAT(name, _init_bytes),                                        \
+                          var )
+#
+# define SENF_PARSER_GOTO_fix(name)                                                               \
+      SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__),                                     \
+                          BOOST_PP_CAT(name, _offset),                                            \
+                          BOOST_PP_CAT(name, _offset),                                            \
+                          fix )
+#
+# define SENF_PARSER_GOTO_OFFSET_var(offset, isize)                                               \
+      SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, isize, var )
+#
+# define SENF_PARSER_GOTO_OFFSET_fix(offset)                                                      \
+      SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, offset, fix )
+#
+# define SENF_PARSER_I_GOTO(name, offset, initsize, ofstype)                                      \
+      private:                                                                                    \
+          SENF_PARSER_I_BITFIELD_RESET()                                                          \
+          SENF_PARSER_I_FIELD_INTRO(name, void, private)                                          \
+          SENF_PARSER_I_FIELD_INIT_ro(name, void, private)                                        \
+          BOOST_PP_CAT( SENF_PARSE_I_GOTO_SET_OFS_, ofstype ) (name, offset, initsize)            \
+      public:
+#
+# define SENF_PARSE_I_GOTO_SET_OFS_var(name, offs, initsize)                                      \
+          size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {              \
+              return offs;                                                                        \
+          }                                                                                       \
+          SENF_MPL_SLOT_SET(init_bytes, initsize);
+#
+# define SENF_PARSE_I_GOTO_SET_OFS_fix(name, offs, initsize)                                      \
+          SENF_MPL_SLOT_SET(offset, offs);
+#
+# ///////////////////////////////////////////////////////////////////////////
+# // SENF_PARSER_LABEL_*
+#
+# define SENF_PARSER_LABEL_var(name) SENF_PARSER_I_LABEL( name, var, public )
+# define SENF_PARSER_LABEL_fix(name) SENF_PARSER_I_LABEL( name, fix, public )
+#
+# define SENF_PARSER_I_LABEL(name, ofstype, access)                                               \
+      access:                                                                                     \
+          SENF_PARSER_I_BITFIELD_RESET()                                                          \
+          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)             \
+      public:
 #
 # ////////////////////////////////ih.e///////////////////////////////////////
 # endif
diff --git a/Packets/ParseHelpers.test.cc b/Packets/ParseHelpers.test.cc
new file mode 100644 (file)
index 0000000..6d69414
--- /dev/null
@@ -0,0 +1,262 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     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 ParseHelpers.test unit tests */
+
+//#include "ParseHelpers.test.hh"
+//#include "ParseHelpers.test.ih"
+
+// Custom includes
+#include "Packets.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+
+    struct FixedBaseParser : public senf::PacketParserBase
+    {
+#       include SENF_FIXED_PARSER()
+
+        SENF_PARSE_FIELD        ( normalField          , senf::Parse_UInt16 );
+        SENF_PARSE_FIELD_RO     ( roField              , senf::Parse_UInt16 );
+
+        SENF_PARSE_CUSTOM_FIELD ( customField          , int, 2             ) {
+            return parse<senf::Parse_UInt16>(customField_offset);
+        }
+        
+        SENF_PARSE_BITFIELD     ( signedBitfield       , 4, signed          );
+        SENF_PARSE_BITFIELD     ( unsignedBitfield     , 3, unsigned        );
+        SENF_PARSE_BITFIELD     ( boolBitfield         , 1, bool            );
+
+        SENF_PARSE_BITFIELD_RO  ( roSignedBitfield     , 4, signed          );
+        SENF_PARSE_BITFIELD_RO  ( roUnsignedBitfield   , 3, unsigned        );
+        SENF_PARSE_BITFIELD_RO  ( roBoolBitfield       , 1, bool            );
+
+        SENF_PARSER_LABEL( end );
+        SENF_PARSER_GOTO( roField );
+
+        SENF_PARSE_FIELD        ( overlayOfRoField     , senf::Parse_Int16  );
+        SENF_PARSER_SKIP( 2 );
+        SENF_PARSE_FIELD        ( overlayOfBitfield    , senf::Parse_UInt8  );
+
+        SENF_PARSER_GOTO_OFFSET( 1 );
+
+        SENF_PARSE_FIELD        ( lowbyteOfNormalField , senf::Parse_UInt8  );
+
+        SENF_PARSER_GOTO( end );
+
+        SENF_PARSER_FINALIZE( FixedBaseParser );
+    };
+
+    struct FixedDerivedParser : public FixedBaseParser
+    {
+#       include SENF_FIXED_PARSER()
+
+        SENF_PARSER_INHERIT( FixedBaseParser );
+        
+        SENF_PARSE_FIELD        ( derivedField         , senf::Parse_UInt16 );
+
+        SENF_PARSER_LABEL( end );
+        SENF_PARSER_GOTO( signedBitfield );
+
+        SENF_PARSE_FIELD        ( anotherOverlay       , senf::Parse_UInt16 );
+        
+        SENF_PARSER_GOTO( end );
+
+        SENF_PARSER_FINALIZE( FixedDerivedParser )
+    };
+}
+
+BOOST_AUTO_UNIT_TEST(fixedParser)
+{
+    unsigned char data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x83, 0x84, 0x07, 0x08 };
+
+    senf::DataPacket p (senf::DataPacket::create(data));
+
+    FixedBaseParser baseParser (p.data().begin(), &p.data());
+
+    BOOST_CHECK_EQUAL( FixedBaseParser::fixed_bytes+0, 8u );
+
+    BOOST_CHECK_EQUAL (   baseParser.normalField()          , 0x0102u );
+    BOOST_CHECK_EQUAL (   baseParser.roField()              , 0x0304u );
+    BOOST_CHECK_EQUAL (   baseParser.customField()          , 0x0506  );
+
+    BOOST_CHECK_EQUAL (   baseParser.signedBitfield()       , -8      );
+    BOOST_CHECK_EQUAL (   baseParser.unsignedBitfield()     , 1u      );
+    BOOST_CHECK       (   baseParser.boolBitfield()                   );
+
+    BOOST_CHECK_EQUAL (   baseParser.roSignedBitfield()     , -8      );
+    BOOST_CHECK_EQUAL (   baseParser.roUnsignedBitfield()   , 2u      );
+    BOOST_CHECK       ( ! baseParser.roBoolBitfield()                 );
+
+    BOOST_CHECK_EQUAL (   baseParser.overlayOfRoField()     , 0x0304  );
+    BOOST_CHECK_EQUAL (   baseParser.overlayOfBitfield()    , 0x83u   );
+    BOOST_CHECK_EQUAL (   baseParser.lowbyteOfNormalField() , 0x02u   );
+
+    FixedDerivedParser derivedParser (p.data().begin(), &p.data());
+
+    BOOST_CHECK_EQUAL( FixedDerivedParser::fixed_bytes+0, 10u );
+
+    BOOST_CHECK_EQUAL (   derivedParser.normalField()          , 0x0102u );
+    BOOST_CHECK_EQUAL (   derivedParser.roField()              , 0x0304u );
+    BOOST_CHECK_EQUAL (   derivedParser.customField()          , 0x0506  );
+
+    BOOST_CHECK_EQUAL (   derivedParser.signedBitfield()       , -8      );
+    BOOST_CHECK_EQUAL (   derivedParser.unsignedBitfield()     , 1u      );
+    BOOST_CHECK       (   derivedParser.boolBitfield()                   );
+
+    BOOST_CHECK_EQUAL (   derivedParser.roSignedBitfield()     , -8      );
+    BOOST_CHECK_EQUAL (   derivedParser.roUnsignedBitfield()   , 2u      );
+    BOOST_CHECK       ( ! derivedParser.roBoolBitfield()                 );
+
+    BOOST_CHECK_EQUAL (   derivedParser.overlayOfRoField()     , 0x0304  );
+    BOOST_CHECK_EQUAL (   derivedParser.overlayOfBitfield()    , 0x83u   );
+    BOOST_CHECK_EQUAL (   derivedParser.lowbyteOfNormalField() , 0x02u   );
+    
+    BOOST_CHECK_EQUAL (   derivedParser.derivedField()         , 0x0708u );
+    BOOST_CHECK_EQUAL (   derivedParser.anotherOverlay()       , 0x8384u );
+}
+
+namespace {
+
+    struct VariableBaseParser : public senf::PacketParserBase
+    {
+#       include SENF_PARSER()
+
+        SENF_PARSE_FIELD        ( normalField          , senf::Parse_UInt16 );
+        SENF_PARSE_FIELD_RO     ( roField              , senf::Parse_UInt16 );
+
+        SENF_PARSE_CUSTOM_FIELD ( customField          , int, 2, 2          ) {
+            return parse<senf::Parse_UInt16>(customField_offset());
+        }
+        
+        SENF_PARSE_BITFIELD     ( signedBitfield       , 4, signed          );
+        SENF_PARSE_BITFIELD     ( unsignedBitfield     , 3, unsigned        );
+        SENF_PARSE_BITFIELD     ( boolBitfield         , 1, bool            );
+
+        SENF_PARSE_BITFIELD_RO  ( roSignedBitfield     , 4, signed          );
+        SENF_PARSE_BITFIELD_RO  ( roUnsignedBitfield   , 3, unsigned        );
+        SENF_PARSE_BITFIELD_RO  ( roBoolBitfield       , 1, bool            );
+
+        SENF_PARSER_LABEL( end );
+        SENF_PARSER_GOTO( roField );
+
+        SENF_PARSE_FIELD        ( overlayOfRoField     , senf::Parse_Int16  );
+        SENF_PARSER_SKIP( 2, 2 );
+        SENF_PARSE_FIELD        ( overlayOfBitfield    , senf::Parse_UInt8  );
+
+        SENF_PARSER_GOTO_OFFSET( 1, 1 );
+
+        SENF_PARSE_FIELD        ( lowbyteOfNormalField , senf::Parse_UInt8  );
+
+        SENF_PARSER_GOTO( end );
+
+        SENF_PARSER_FINALIZE( VariableBaseParser );
+    };
+
+    struct VariableDerivedParser : public VariableBaseParser
+    {
+#       include SENF_PARSER()
+
+        SENF_PARSER_INHERIT( VariableBaseParser );
+        
+        SENF_PARSE_FIELD        ( derivedField         , senf::Parse_UInt16 );
+
+        SENF_PARSER_LABEL( end );
+        SENF_PARSER_GOTO( signedBitfield );
+
+        SENF_PARSE_FIELD        ( anotherOverlay       , senf::Parse_UInt16 );
+        
+        SENF_PARSER_GOTO( end );
+
+        SENF_PARSER_FINALIZE( VariableDerivedParser );
+    };
+}
+
+BOOST_AUTO_UNIT_TEST(variableParser)
+{
+    unsigned char data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x83, 0x84, 0x07, 0x08 };
+
+    senf::DataPacket p (senf::DataPacket::create(data));
+
+    VariableBaseParser baseParser (p.data().begin(), &p.data());
+    
+    BOOST_CHECK_EQUAL ( senf::bytes(baseParser), 8u );
+
+    BOOST_CHECK_EQUAL (   baseParser.normalField()          , 0x0102u );
+    BOOST_CHECK_EQUAL (   baseParser.roField()              , 0x0304u );
+    BOOST_CHECK_EQUAL (   baseParser.customField()          , 0x0506  );
+
+    BOOST_CHECK_EQUAL (   baseParser.signedBitfield()       , -8      );
+    BOOST_CHECK_EQUAL (   baseParser.unsignedBitfield()     , 1u      );
+    BOOST_CHECK       (   baseParser.boolBitfield()                   );
+
+    BOOST_CHECK_EQUAL (   baseParser.roSignedBitfield()     , -8      );
+    BOOST_CHECK_EQUAL (   baseParser.roUnsignedBitfield()   , 2u      );
+    BOOST_CHECK       ( ! baseParser.roBoolBitfield()                 );
+
+    BOOST_CHECK_EQUAL (   baseParser.overlayOfRoField()     , 0x0304  );
+    BOOST_CHECK_EQUAL (   baseParser.overlayOfBitfield()    , 0x83u   );
+    BOOST_CHECK_EQUAL (   baseParser.lowbyteOfNormalField() , 0x02u   );
+
+    VariableDerivedParser derivedParser (p.data().begin(), &p.data());
+
+    BOOST_CHECK_EQUAL ( senf::bytes(derivedParser), 10u );
+
+    BOOST_CHECK_EQUAL (   derivedParser.normalField()          , 0x0102u );
+    BOOST_CHECK_EQUAL (   derivedParser.roField()              , 0x0304u );
+    BOOST_CHECK_EQUAL (   derivedParser.customField()          , 0x0506  );
+
+    BOOST_CHECK_EQUAL (   derivedParser.signedBitfield()       , -8      );
+    BOOST_CHECK_EQUAL (   derivedParser.unsignedBitfield()     , 1u      );
+    BOOST_CHECK       (   derivedParser.boolBitfield()                   );
+
+    BOOST_CHECK_EQUAL (   derivedParser.roSignedBitfield()     , -8      );
+    BOOST_CHECK_EQUAL (   derivedParser.roUnsignedBitfield()   , 2u      );
+    BOOST_CHECK       ( ! derivedParser.roBoolBitfield()                 );
+
+    BOOST_CHECK_EQUAL (   derivedParser.overlayOfRoField()     , 0x0304  );
+    BOOST_CHECK_EQUAL (   derivedParser.overlayOfBitfield()    , 0x83u   );
+    BOOST_CHECK_EQUAL (   derivedParser.lowbyteOfNormalField() , 0x02u   );
+    
+    BOOST_CHECK_EQUAL (   derivedParser.derivedField()         , 0x0708u );
+    BOOST_CHECK_EQUAL (   derivedParser.anotherOverlay()       , 0x8384u );
+}
+
+///////////////////////////////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: