Utils/Daemon: BUGFIX: Fix command line argument parsing
[senf.git] / Packets / ParseVariant.hh
index e8593b5..f7e9670 100644 (file)
@@ -151,10 +151,11 @@ namespace senf {
         \see senf::Parser_Variant
         \ingroup parsecollection
      */
-    template <class ChooserType, unsigned Distance, SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
+    template <class ChooserType, unsigned Distance, class Translator,
+              SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
     struct Parse_Variant_Direct
     {
-        typedef Parse_Variant< detail::Parse_Variant_Direct<ChooserType, Distance>,
+        typedef Parse_Variant< detail::Parse_Variant_Direct<ChooserType, Distance, Translator>,
                                SENF_PARSE_VARIANT_TPL_ARGS(P) > parser;
     };
 
@@ -163,8 +164,9 @@ namespace senf {
         This macro is a special helper to define a senf::Parse_Variant_Direct type field. This is a
         variant field which chooses the sub-type by directly taking the value of some other field.
 
-        This is a dynamically sized parser. Nevertheless, the chooser field \e must have a \e fixed
-        distance to this field, the \a chooser must be a fixed-size value parser.
+        \warning
+          This is a dynamically sized parser. Nevertheless, the chooser field \e must have a
+          \e fixed distance to this field, the \a chooser must be a fixed-size value parser.
 
         \code
         struct SomeParser : public PacketParserBase
@@ -179,16 +181,16 @@ namespace senf {
                                             (senf::Parse_UInt24)
                                             (senf::Parse_UInt32) );
 
-            senf::Parse_UInt8 uint8()  const { return content().get<1>(); }
-            senf::Parse_UInt8 uint16() const { return content().get<2>(); }
-            senf::Parse_UInt8 uint24() const { return content().get<3>(); }
-            senf::Parse_UInt8 uint32() const { return content().get<4>(); }
+            senf::Parse_UInt8  uint8()  const { return content().get<1>(); }
+            senf::Parse_UInt16 uint16() const { return content().get<2>(); }
+            senf::Parse_UInt24 uint24() const { return content().get<3>(); }
+            senf::Parse_UInt32 uint32() const { return content().get<4>(); }
 
             void disable()    const { content().init<0>(); }
             void set_uint8()  const { content().init<1>(); }
-            void set_uint16() const { content().init<1>(); }
-            void set_uint24)  const { content().init<1>(); }
-            void set_uint23() const { content().init<1>(); }
+            void set_uint16() const { content().init<2>(); }
+            void set_uint24)  const { content().init<3>(); }
+            void set_uint23() const { content().init<4>(); }
 
             SENF_PARSER_FINALIZE(SomeParser);
         };
@@ -210,8 +212,12 @@ namespace senf {
         \hideinitializer
         \ingroup packetparsermacros
      */
-#   define SENF_PARSER_VARIANT(name, chooser, types) \
-        SENF_PARSER_VARIANT_I(SENF_PARSER_FIELD, name, chooser, types)
+#   define SENF_PARSER_VARIANT(name, chooser, types)                                              \
+        SENF_PARSER_VARIANT_I(SENF_PARSER_FIELD,                                                  \
+                              name,                                                               \
+                              chooser,                                                            \
+                              senf::detail::Parse_Variant_IdentityTranslator,                     \
+                              types)
 
     /** \brief Define Parse_Variant_Direct field (private)
         
@@ -219,8 +225,60 @@ namespace senf {
         \hideinitializer
         \ingroup packetparsermacros
      */
-#   define SENF_PARSER_PRIVATE_VARIANT(name, chooser, types) \
-        SENF_PARSER_VARIANT_I(SENF_PARSER_PRIVATE_FIELD, name, chooser, types)
+#   define SENF_PARSER_PRIVATE_VARIANT(name, chooser, types)                                      \
+        SENF_PARSER_VARIANT_I(SENF_PARSER_PRIVATE_FIELD,                                          \
+                              name,                                                               \
+                              chooser,                                                            \
+                              senf::detail::Parse_Variant_IdentityTranslator,                     \
+                              types)
+
+    /** \brief Define Parse_Variant_Direct field with translator
+        
+        This is like \ref SENF_PARSER_VARIANT(), however it allows to specify a \a translator
+        argument which translates between \a chooser values and type indices:
+        \code
+        struct SomeTranslator {
+            static unsigned fromChooser(chooser_field_t::value_type value) {
+                switch (value) {
+                case 1  : return 0 ;
+                case 5  : return 1 ;
+                default : return 2 ;
+                }
+            }
+            static chooser_field_t::value_type toChooser(unsigned value) {
+                static chooser_field_t::value_type table[] const = { 1, 5, 0 };
+                return table[value];
+            }
+        };
+        \endcode
+        The \a translator class must have two publicly accessible static members, \c fromChooser and
+        \c toChooser. \c fromChooser takes the value as returned by the \a chooser field and must
+        return the corresponding class index whereas \c toChooser takes the class index and must
+        return the value to write into the \a chooser field.
+
+        \see \ref SENF_PARSER_VARIANT()
+        \hideinitializer
+        \ingroup packetparsermacros
+     */
+#   define SENF_PARSER_VARIANT_TRANS(name, chooser, translator, types)                            \
+        SENF_PARSER_VARIANT_I(SENF_PARSER_FIELD,                                                  \
+                              name,                                                               \
+                              chooser,                                                            \
+                              translator,                                                         \
+                              types)
+
+    /** \brief Define Parse_Variant_Direct field with translator (private)
+        
+        \see \ref SENF_PARSER_VARIANT_TRANS()
+        \hideinitializer
+        \ingroup packetparsermacros
+     */
+#   define SENF_PARSER_PRIVATE_VARIANT_TRANS(name, chooser, types)                                \
+        SENF_PARSER_VARIANT_I(SENF_PARSER_PRIVATE_FIELD,                                          \
+                              name,                                                               \
+                              chooser,                                                            \
+                              translator,                                                         \
+                              types)
 
 }