Packets: Add nestet transform/bytes auxtag support
g0dil [Mon, 9 Jun 2008 15:33:17 +0000 (15:33 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@870 270642c3-0616-0410-b53a-bc976706d245

Packets/ListBParser.ih
Packets/ListBParser.test.cc
Packets/ListNParser.ih
Packets/ParseHelpers.ih
Packets/VectorParser.ih

index b44e35a..ff88629 100644 (file)
@@ -131,6 +131,15 @@ namespace detail {
         typedef ListBParser_Policy<ElementParser, AuxPolicy> type;
     };
 
+    template <class ElementParser, class AuxPolicy, class Transform>
+    struct ListParserPolicy<ElementParser, AuxPolicy, 
+                            senf::detail::auxtag::transform<Transform, 
+                                                            senf::detail::auxtag::bytes> >
+    {
+        typedef ListBParser_Policy< ElementParser,
+                                    TransformAuxParserPolicy<AuxPolicy, Transform> > type;
+    };
+
 }}
 
 ///////////////////////////////ih.e////////////////////////////////////////
index 0a53ae4..ecdb63a 100644 (file)
@@ -147,6 +147,13 @@ BOOST_AUTO_UNIT_TEST(ListBParser_container)
 
 namespace {
     
+    struct TestTransform
+    {
+        typedef unsigned value_type;
+        static unsigned get(unsigned v) { return v/2; }
+        static unsigned set(unsigned v) { return 2*v; }
+    };
+
     struct TestListParser
         : public senf::PacketParserBase
     {
@@ -156,7 +163,8 @@ namespace {
         SENF_PARSER_PRIVATE_FIELD ( size2 , senf::UInt8Parser );
         SENF_PARSER_FIELD         ( dummy , senf::UInt32Parser );
         SENF_PARSER_LIST          ( list1  , bytes(size1) , VectorParser );
-        SENF_PARSER_LIST          ( list2  , bytes(size2) , VectorParser );
+        SENF_PARSER_LIST          ( list2  , transform(TestTransform, bytes(size2)) , 
+                                             VectorParser );
 
         SENF_PARSER_FINALIZE(TestListParser);
     };
@@ -165,8 +173,8 @@ namespace {
 
 BOOST_AUTO_UNIT_TEST(listBytesMacro)
 {
-    unsigned char data[] = { 0x08,                   // size1
-                             0x09,                   // size2
+    unsigned char data[] = {    8,                   // size1
+                               18,                   // size2
                              0x01, 0x02, 0x03, 0x04, // dummy
                              0x01,                   // list1()[0].size()
                              0x05, 0x06,             // list1().vec()[0]
index ba39b52..fc9b462 100644 (file)
@@ -80,7 +80,9 @@ namespace detail {
     };
 
     template <class ElementParser, class AuxPolicy, class Transform>
-    struct ListParserPolicy<ElementParser, AuxPolicy, senf::detail::auxtag::transform<Transform> >
+    struct ListParserPolicy<ElementParser, AuxPolicy, 
+                            senf::detail::auxtag::transform<Transform, 
+                                                            senf::detail::auxtag::none> >
     {
         typedef ListNParser_Policy< ElementParser,
                                     TransformAuxParserPolicy<AuxPolicy, Transform> > type;
index 18f58e5..a1c80bc 100644 (file)
@@ -29,6 +29,7 @@
 # include <boost/preprocessor/if.hpp>
 # include <boost/preprocessor/expand.hpp>
 # include <boost/preprocessor/facilities/is_empty.hpp>
+# include <boost/preprocessor/punctuation/comma.hpp>
 # include "../Utils/mpl.hh"
 #
 # ////////////////////////////////ih.p///////////////////////////////////////
   namespace senf { namespace detail { namespace auxtag { 
       struct bytes {}; } } }
   namespace senf { namespace detail { namespace auxtag { 
-      template <class T> 
+      template <class Transform, class Tag> 
       struct transform {}; } } }
 #
 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__bytes(x)
-# define SENF_PARSER_COLLECTION_TAG__bytes(x) senf::detail::auxtag::bytes
+# define SENF_PARSER_COLLECTION_TAG__bytes(x) bytes()
+# define SENF_PARSER_COLLECTION_TAG_EXPAND__bytes() senf::detail::auxtag::bytes
 # define SENF_PARSER_COLLECTION_TAG_GETAUX__bytes(x) x
 #
+# // No recursive call so we need some more of theese ... ARGH !!!
+# define SENF_CAT_RECURS1(a, b) SENF_CAT_RECURS1_I(a,b)
+# define SENF_CAT_RECURS1_I(a, b) a ## b
+# define SENF_CAT_RECURS2(a, b) SENF_CAT_RECURS2_I(a,b)
+# define SENF_CAT_RECURS2_I(a, b) a ## b
+#
 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__transform(x,y)
-# define SENF_PARSER_COLLECTION_TAG__transform(x,y) senf::detail::auxtag::transform<x>
-# define SENF_PARSER_COLLECTION_TAG_GETAUX__transform(x,y) y
+# define SENF_PARSER_COLLECTION_TAG__transform(x,y) \
+      transform(x, SENF_PARSER_COLLECTION_TAG_RECURS1(y))
+# define SENF_PARSER_COLLECTION_TAG_EXPAND__transform(x,y)                                        \
+      senf::detail::auxtag::transform<                                                            \
+          x,                                                                                      \
+          SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_EXPAND__, y)>
+# define SENF_PARSER_COLLECTION_TAG_GETAUX__transform(x,y) \
+      SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(y)
+#
+# define SENF_PARSER_COLLECTION_TAG_EXPAND__none() senf::detail::auxtag::none
+#
+# define SENF_PARSER_COLLECTION_TAG_RECURS1(aux)                                                  \
+      BOOST_PP_IF(                                                                                \
+          SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                                \
+          BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG__, aux),                                        \
+          none() )
+#
+# define SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(aux)                                           \
+      BOOST_PP_IF(                                                                                \
+          SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                                \
+          BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                                 \
+          aux)
 #
 # define SENF_PARSER_COLLECTION_HAS_KEYWORD(x)                                                    \
-      BOOST_PP_IS_EMPTY( BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_GOBBLE__, x) )
+      BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_GOBBLE__, x) )
 #
 # define SENF_PARSER_COLLECTION_I(access, name, aux, traits)                                      \
       BOOST_PP_EXPAND(                                                                            \
                   SENF_PARSER_COLLECTION_HAS_KEYWORD(aux),                                        \
                   ( access,                                                                       \
                     name,                                                                         \
-                    BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                       \
-                    BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG__, aux),                              \
+                    SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux),                   \
+                    SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG__, aux),                          \
                     traits ),                                                                     \
                   ( access,                                                                       \
                     name,                                                                         \
                     aux,                                                                          \
-                    senf::detail::auxtag::none,                                                   \
+                    none(),                                                                       \
                     traits ) ))
 #
 # define SENF_PARSER_COLLECTION_II(access, name, aux, tag, traits)                                \
               BOOST_PP_CAT(name,_aux_policy);                                                     \
           typedef traits::parser<                                                                 \
               BOOST_PP_CAT(name,_aux_policy),                                                     \
-              tag                                                                                 \
+              BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_EXPAND__, tag)                              \
               >::type BOOST_PP_CAT(name, _collection_t);                                          \
       access:                                                                                     \
           SENF_PARSER_FIELD_SETUP_I( name,                                                        \
index 7a013cc..9f6771c 100644 (file)
@@ -54,7 +54,8 @@ namespace detail {
 
     template <class ElementParser, class AuxPolicy, class Transform>
     struct VectorParserPolicy<ElementParser, AuxPolicy, 
-                              senf::detail::auxtag::transform<Transform> >
+                              senf::detail::auxtag::transform<Transform,
+                                                              senf::detail::auxtag::none> >
     {
         typedef senf::detail::TransformAuxParserPolicy<AuxPolicy, Transform> type;
     };