Packets: senf::Parse_Variant documentation
g0dil [Tue, 23 Oct 2007 09:43:19 +0000 (09:43 +0000)]
Packets/MPEGDVBBundle: Use senf::Parse_Variant in SNDUPacket

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

Examples/DVBAdapter/ULEdec.cc
Packets/MPEGDVBBundle/Doxyfile
Packets/MPEGDVBBundle/SNDUPacket.hh
Packets/PacketParser.hh
Packets/ParseHelpers.hh
Packets/ParseVariant.dox
Packets/ParseVariant.hh
Packets/ParseVariant.ih
Packets/ParseVariant.test.cc
doclib/Doxyfile.global
senf.dict

index 3c1de25..395688c 100644 (file)
@@ -197,7 +197,11 @@ ULEdec::iterator ULEdec::readNewSNDUPacket(iterator i, iterator const i_end)
                 "SNDU length error. length=%d") % sndu_length) );
      }
     this->snduPacket = senf::SNDUPacket::create(sndu_length+4);
-    this->snduPacket->d_bit() = dbit;
+
+    if (dbit)
+        this->snduPacket->withoutDestination();
+    // else not needed since default on newly created packet is withDestination()
+
     this->snduPacket->length() = sndu_length;
     this->snduPacketData_iter = boost::next(this->snduPacket.data().begin(), 2);
     this->priv_sndu_type_1 = false;
@@ -283,6 +287,6 @@ int main(int argc, char const * argv[])
 // c-file-style: "senf"
 // indent-tabs-mode: nil
 // ispell-local-dictionary: "american"
-// compile-command: "scons -u test"
+// compile-command: "scons -U"
 // comment-column: 40
 // End:
index c209022..e67ad83 100644 (file)
@@ -7,6 +7,7 @@ ALPHABETICAL_INDEX = NO
 
 TAGFILES = \
        "$(TOPDIR)/Packets/doc/Packets.tag" \
+       "$(TOPDIR)/Packets/DefaultBundle/doc/DefaultBundle.tag" \
        "$(TOPDIR)/Socket/doc/Socket.tag" \
-       "$(TOPDIR)/Utils/doc/Utils.tag" 
+       "$(TOPDIR)/Utils/doc/Utils.tag"
 
index 19d9b8d..7cb9e76 100644 (file)
@@ -47,27 +47,32 @@ namespace senf {
     {
 #       include SENF_PARSER()
 
-        SENF_PARSER_BITFIELD     ( d_bit       ,  1 , bool     );
-        SENF_PARSER_BITFIELD     ( length      , 15 , unsigned );
+        /* We first define the fields as they appear in the field. Some of the fields are declared
+           private. We provide custom accessors for those fields further down. */
+
+        SENF_PARSER_PRIVATE_BITFIELD ( d_bit_       ,  1 , unsigned );
+        SENF_PARSER_BITFIELD         ( length       , 15 , unsigned );
+        SENF_PARSER_FIELD            ( type         , Parse_UInt16  );
+        SENF_PARSER_PRIVATE_VARIANT  ( destination_ , d_bit_        , 
+                                                      (Parse_MAC) (VoidPacketParser) );
+        
+        SENF_PARSER_FINALIZE( Parse_SNDUPacket );
+        
+        Parse_MAC destination()         /// Only defined if d_bit() == \c false
+            { return destination_().get<0>(); }
 
-        SENF_PARSER_FIELD        ( type        , Parse_UInt16  );
+        bool d_bit()                    /// Destination absent bit
+            { return d_bit_(); }
 
-        // This field only exists, if d_bit() is *not* set. New SNDUPackets are created with d_bit()
-        // set to 0, they have destination. We set the size of this field depending on the value of
-        // d_bit(), the init_bytes value is set to 6 bytes (the size of a MAC address)
-        SENF_PARSER_CUSTOM_FIELD ( destination , Parse_MAC     , d_bit() ? 0 : 6 , 6 ) {
-            BOOST_ASSERT( ! d_bit() );
-            return parse<destination_t>( destination_offset() );
-        }
+        void withDestination()          /// Clear destination absent bit
+            { destination_().init<0>(); }
+        
+        void withoutDestination()       /// Set destination absent bit
+            { destination_().init<1>(); }
 
-        // This field is placed at the end of the parser. It is therefore only considered for
-        // calculating init_bytes but not for calculating bytes()
-        SENF_PARSER_CUSTOM_FIELD ( crc         , Parse_UInt32  , 0 , 4 ) {
-            return parse<crc_t>( data().size() - 4 );
-        }
+        Parse_UInt32 crc() 
+            { return parse<Parse_UInt32>( data().size() - 4 ); }
 
-        SENF_PARSER_FINALIZE( Parse_SNDUPacket );
-        
         boost::uint32_t calcCrc() const;
     };
 
index 3585280..543ba9c 100644 (file)
     pointers, it should hold a copy of the value (it's Ok for \c value() to return such a reference
     as long as assigning it to a \c value_type variable will copy the value).
 
+    \see parseint
+
     \subsection parserimpl_collection Collection parsers
 
     A collection parser \a SomeParser should model STL containers. The parsers themselves will
     parser. Instead, you can rely on senf::Parse_Vector or senf::Parse_List and implement new
     policies.
 
+    \see parsecollection
+
     \subsection parserimpl_composite Composite parsers
     
     If possible, composite parsers should be implemented using the \ref packetparsermacros. In
index 6561dbf..c3e2ab4 100644 (file)
     at the end), those bit's will be skipped.
 
     Since consecutive bit-field commands are aggregated into a single bit-field group, the offset of
-    all these bit-fields will be the offset of the \e beginning of the bit-field irrespective of the
+    all these bit-fields will be the offset of the \e beginning of the group irrespective of the
     number of bits parsed so far. Changing the offset to some bitfield using \ref SENF_PARSER_GOTO()
     will therefore always go to the position at the beginning of this bitfield group. And since the
     current offset does not include the bit position, the bit position will be 0, the first bit. You
         SENF_PARSER_PRIVATE_FIELD_RO()
     \hideinitializer
  */
-#define SENF_PARSER_FIELD(name, type)
+#define SENF_PARSER_FIELD(name, type) 
 
 /** \brief Define parser field (read-only)
     
     \see SENF_PARSER_FIELD() 
     \hideinitializer
 */
-#define SENF_PARSER_FIELD_RO(name, type)
+#define SENF_PARSER_FIELD_RO(name, type) 
 
 /** \brief Define parser field (private)
 
     \see SENF_PARSER_FIELD()
     \hideinitializer
  */
-#define SENF_PARSER_PRIVATE_FIELD(name, type)
+#define SENF_PARSER_PRIVATE_FIELD(name, type) 
 
 /** \brief Define parser field (private + read-only)
 
     \see SENF_PARSER_FIELD()
     \hideinitializer
  */
-#define SENF_PARSER_PRIVATE_FIELD_RO(name, type)
+#define SENF_PARSER_PRIVATE_FIELD_RO(name, type) 
 
 /** \brief Define custom field accessor
 
     \param[in] size size of the field, either a single value \a bytes for fixed size parsers or two
         separate arguments \a bytes and \a init_bytes for dynamically sized parsers
  */
-#define SENF_PARSER_CUSTOM_FIELD(name, type, size)
+#define SENF_PARSER_CUSTOM_FIELD(name, type, size) 
 
 ///@}
 
 
     \hideinitializer
  */
-#define SENF_PARSER_BITFIELD(name, bits, type)
+#define SENF_PARSER_BITFIELD(name, bits, type) 
 
 /** \brief Define bit-field (read-only) 
 
     \see \ref SENF_PARSER_BITFIELD()
     \hideinitializer
  */
-#define SENF_PARSER_BITFIELD_RO(name, bits, type)
+#define SENF_PARSER_BITFIELD_RO(name, bits, type) 
 
 /** \brief Define bit-field (private) 
 
     \see \ref SENF_PARSER_BITFIELD()
     \hideinitializer
  */
-#define SENF_PARSER_PRIVATE_BITFIELD(name, bits, type)
+#define SENF_PARSER_PRIVATE_BITFIELD(name, bits, type) 
 
 /** \brief Define bit-field (private + read-only) 
 
  */
 #define SENF_PARSER_FIXED_OFFSET(name)
 
+/** \brief Get current fixed offset, if possible
+    This macro will return the current fixed offset, a compile-time constant expression. This is
+    always possible when defining a fixed size parser.
+
+    Even in dynamically sized parsers this macro will work, up tp now only fixed size fields have
+    been defined. This macro does \e not validate this condition, it will return an arbitrary
+    incorrect value otherwise.
+
+    \pre Current position preceded by fixed-size parsers only
+    \returns compile-time constant offset from parsers start
+    \hideinitializer
+ */
+#define SENF_PARSER_CURRENT_FIXED_OFFSET()
+
 ///@}
 
 #else
index d9153e5..3747a03 100644 (file)
 
 namespace senf {
 
+    /** \brief Example of a variant policy. ONLY FOR EXPOSITION
+
+        This class shows the interace which must be impemented by a variant policy. It is \e not a
+        variant policy, it is only a declaration of the interface:
+        \code
+        struct ExampleVariantPolicy
+        {
+            // optional typedefs used tosimplify all other declarations
+            typedef PacketParserBase::data_iterator data_iterator;
+            typedef PacketParserBase::state_type state_type;
+            typedef PacketParserBase::size_type size_type;
+
+            // mandatory members
+            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);
+        };
+        \endcode
+
+        The \a VariantPolicy may define additional data members if needed. It must be either default
+        constructible or copy constructible. If a \a VariantPolicy is not default constructible, an
+        additional \a VariantPolicy argument needs to be passed to the senf::Parse_Variant
+        constructor which is used to copy-initialize the embeded policy.
+
+        \see senf::Parse_Variant
+     */
     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;
+        static size_type const init_bytes = 0; ///< Additional initial size
+                                        /**< This value is added to the size of the first variant
+                                             sub-parser to calculate the \c init_bytes value. */
+
         size_type bytes  (data_iterator i, state_type s) const;
+                                        ///< Additional parser size
+                                        /**< The return value is added to the size of the current
+                                             variant. */
+
         data_iterator begin(data_iterator i, state_type s) const;
+                                        ///< Advance \a i to beginning of variant data
+                                        /**< This member must return the beginning of the variant's
+                                             data (the place, where the sub-parsers reside in the
+                                             packet). */
 
         unsigned variant (data_iterator i, state_type s) const;
+                                        ///< Get current variant index
+                                        /**< \returns current variant sub-parser, interpreted as
+                                             index into the 0-indexed list of sub-parsers. */
+
         void variant     (unsigned v, data_iterator i, state_type s);
+                                        ///< Set current variant index
+                                        /**< Must set the current variant to \a v which is the index
+                                             into the 0-index list of sub-parsers of the currently
+                                             active variant sub-parser.
+
+                                             This member must not process the sub-parser data (like
+                                             initializing the sub-parser or changing the data
+                                             container size). */
     };
 
 }
index 84564a4..e8593b5 100644 (file)
 
 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 )
+#   ifndef SENF_LIMIT_PARSE_VARIANT
+        /** \brief Maximum number of senf::Parse_Variant sub-parsers.
 
-#   define SENF_PARSE_VARIANT_TPL_ARGS(n) BOOST_PP_ENUM_PARAMS( SENF_LIMIT_PARSE_VARIANT, n )
+            This number defines the maximum number of parser arguments senf::Parse_Variant takes.
+         */
+#       define SENF_LIMIT_PARSE_VARIANT 6
+#   endif
 
+    /** \brief Variant parser
+
+        This is not really a collection parser (it does not provide a collection
+        interface). However, it is not a composite parser or value parser either.
+
+        A variant parser will parse any number of sub-parsers discriminated by an arbitrary, policy
+        defined condition. This is the parser to use, if the type and/or number of fields of a
+        packet change depending on some condition.
+        \code
+        typedef senf::Parse_Variant< 
+            MyVariantPolicy, 
+            senf::VoidPacketParser, Parse_TypeA, Parse_TypeB> MyVariant;
+        \endcode
+        This typedef defines a variant parser choosing one of three sub
+        parsers. senf::VoidPacketParser is an empty parser, it effectively makes this parser
+        optional.
+
+        When creating a new packet containing a variant parser, the variant parser will always be
+        initialized to the first sub-parser.
+
+        \see 
+            ExampleVariantPolicy on how to implement the \a VariantPolicy \n
+            \ref SENF_PARSER_VARIANT() on how to integrate the parser into another parser
+        \ingroup parsecollection
+     */
     template <class VariantPolicy, SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
     class Parse_Variant 
         : public PacketParserBase, private VariantPolicy
@@ -62,6 +84,9 @@ namespace senf {
         typedef boost::mpl::vector< SENF_PARSE_VARIANT_TPL_ARGS(P) > parsers;
 
     public:
+        ///\name Parser interface
+        ///\{
+
         Parse_Variant(data_iterator i, state_type s);
         Parse_Variant(VariantPolicy policy, data_iterator i, state_type s);
 
@@ -71,19 +96,61 @@ namespace senf {
         static const size_type init_bytes = 
             senf::init_bytes<P0>::value + VariantPolicy::init_bytes;
 
+        ///\}
         ///////////////////////////////////////////////////////////////////////////
 
-        unsigned variant() const;
+        unsigned variant() const;       ///< Get current variant
+                                        /**< Get the currently selected variant index. The returned
+                                             number directly indexes the list of sub parsers.
+                                             \returns Index of currently selected variant. Integer
+                                                 in the range from 0 to (number-of-sub-parsers - 1)
+                                          */
         
         template <unsigned N>
         typename boost::mpl::at< parsers, boost::mpl::int_<N> >::type get() const;
+                                        ///< Access sub-parser
+                                        /**< This call will return the sub-parser at index \a
+                                             N. This call will fail, if the currently active
+                                             variant() is not \a N.
+                                             \pre variant() == \a N
+                                             \returns sub-parser at index \a N */
 
         template <unsigned N>
-        void init();
-
-    private:
+        void init();                    ///< Re-initialize field
+                                        /**< This will reinitialize the field to the variant
+                                             sub-parser at index \a N changing the currently
+                                             selected variant.
+                                             \post variant() == \a N */
     };
 
+    /** \brief Variant with direct, fixed distance type field
+        
+        This struct is a template typedef defining a senf::Parser_Variant instantiation. It defines
+        a variant parser which interprets the value returned by some other parser directly as index
+        into the list of sub parsers (the numeric template argument to senf::Parse_Variant::get()
+        and senf::Parser_Variant::init()).
+
+        \code
+            // Define a variant choosing between Parse_Foo and Parse_Bar depending on the directly
+            // preceding 1-byte 8bit uint value
+            typedef senf::Parse_Variant_Direct< senf::Parse_UInt8, 1u, 
+                                                Parse_Foo, Parse_Bar >::parser MyVariant;
+        \endcode
+
+        \a ChooserType defines the type of the field used to choose the sub parser. This must be a
+        fixed-size value parser. \a Distance gives the \e fixed distance of this field \e before the
+        currently defined field.
+
+        It is best to define a field of this type using \ref SENF_PARSER_VARIANT() or \ref
+        SENF_PARSER_PRIVATE_VARIANT().
+
+        \param[in] ChooserType type of chooser field (a value parser)
+        \param[in] Distance    fixed distance of the chooser field before the current field
+        \param[in] P           any number of sub parsers
+
+        \see senf::Parser_Variant
+        \ingroup parsecollection
+     */
     template <class ChooserType, unsigned Distance, SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
     struct Parse_Variant_Direct
     {
@@ -91,23 +158,69 @@ namespace senf {
                                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) )
+    /** \brief Define Parse_Variant_Direct field
+
+        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.
+
+        \code
+        struct SomeParser : public PacketParserBase
+        {
+        #   include SENF_PARSER()
+        
+            SENF_PARSER_PRIVATE_FIELD( type, senf::Parse_UInt8 );
+            SENF_PARSER_PRIVATE_VARIANT( content, type,
+                                            (senf::VoidPacketParser)
+                                            (senf::Parse_UInt8)
+                                            (senf::Parse_UInt16)
+                                            (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>(); }
+
+            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>(); }
+
+            SENF_PARSER_FINALIZE(SomeParser);
+        };
+        \endcode
+
+        The variant \c content chooses one of the sub parsers depending on the \c type field. If \c
+        type is 0, senf::VoidPacketParser is selected, if it is 1, senf::Parse_UInt8 and so on. 
+
+        It is customary, to hide the variant parser (by defining it private) and provide more
+        conveniently named accessors.
+
+        \param[in] name name of the field
+        \param[in] chooser name of the field choosing the variant to use
+        \param[in] types a Boost.Preprocessor style sequence of sub-parser types
+
+        \see 
+            senf::Parse_Variant \n 
+            \ref SENF_PARSER_PRIVATE_VARIANT()
+        \hideinitializer
+        \ingroup packetparsermacros
+     */
+#   define SENF_PARSER_VARIANT(name, chooser, types) \
+        SENF_PARSER_VARIANT_I(SENF_PARSER_FIELD, name, chooser, types)
+
+    /** \brief Define Parse_Variant_Direct field (private)
+        
+        \see \ref SENF_PARSER_VARIANT()
+        \hideinitializer
+        \ingroup packetparsermacros
+     */
+#   define SENF_PARSER_PRIVATE_VARIANT(name, chooser, types) \
+        SENF_PARSER_VARIANT_I(SENF_PARSER_PRIVATE_FIELD, name, chooser, types)
 
 }
 
index c022af5..0e33da0 100644 (file)
 namespace senf {
 namespace detail {
 
+#   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 )
+
+#   ifndef DOXYGEN
+
     template <class Variant, unsigned N>
     struct VariantBytes {
         static PacketParserBase::size_type bytes(Variant const & v, unsigned n);
@@ -43,7 +52,10 @@ namespace detail {
     struct VariantBytes<Variant,0> {
         static PacketParserBase::size_type bytes(Variant const & v, unsigned n);
     };
+
+#   endif
     
+    /** \brief Internal: Variant Policy used by senf::Parse_Variant_Direct */
     template <class ChooserType, unsigned Distance>
     struct Parse_Variant_Direct
     {
@@ -68,6 +80,16 @@ namespace detail {
         }
     };
 
+#   define SENF_PARSER_VARIANT_(r, data, elem) ,elem
+
+#   define SENF_PARSER_VARIANT_I(field, 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);                                             \
+        field( name, BOOST_PP_CAT(name, _variant_t) )
+
 }}
 
 ///////////////////////////////ih.e////////////////////////////////////////
index feac293..d3bd24f 100644 (file)
@@ -120,6 +120,7 @@ BOOST_AUTO_UNIT_TEST(parseVariantMacro)
         BOOST_CHECK( ! v.hasContent() );
         BOOST_CHECK_EQUAL( senf::bytes(v), 1u );
         v.hasContent(true);
+        // Parser invalidated
     }
     {
         TestParser v (p.data().begin(), & p.data());
index a9a4c4b..f4c8095 100644 (file)
@@ -27,28 +27,35 @@ SEARCHENGINE           = YES
 
 MACRO_EXPANSION        = YES
 EXPAND_ONLY_PREDEF     = YES
-PREDEFINED             = DOXYGEN \
-                         "SENF_PPI_MODULE(x)=" \
-                         "SENF_PARSER_INHERIT(name)=" \
-                         "SENF_PARSER_FIELD(name,type)=type name() const" \
-                         "SENF_PARSER_FIELD_RO(name,type)=type::value_type name() const" \
-                         "SENF_PARSER_BITFIELD(name, bits, type)=senf::ParseField_ ## type(bits) name() const" \
-                         "SENF_PARSER_BITFIELD_RO(name, bits, type)=senf::ParseField_ ## type(bits)::value_type name() const" \
-                         "SENF_PARSER_CUSTOM_FIELD(name, type, size, isize)=type name() const" \
-                         "SENF_PARSER_PRIVATE_FIELD(name,type)=private: type name() const; public:" \
-                         "SENF_PARSER_PRIVATE_FIELD_RO(name, type)=private: type::value_type name() const; public:" \
-                         "SENF_PARSER_PRIVATE_BITFIELD(name, bits, type)=private: senf::ParseField_ ## type(bits) name() const; public:" \
-                         "SENF_PARSER_PRIVATE_BITFIELD_RO(name, bits, type)=private: senf::ParseField_ ## type(bits)::value_type name() const; public:" \
-                         "SENF_PARSER_SKIP(x)=" \
-                         "SENF_PARSER_SKIP_BITS(x)=" \
-                         "SENF_PARSER_GOTO(x)=" \
-                         "SENF_PARSER_GOTO_OFFSET(x)=" \
-                         "SENF_PARSER_LABEL(x)=" \
-                         "SENF_PARSER_INIT()=void init()" \
-                         "SENF_PARSER_FINALIZE(name)=" \
-                         "ParseField_unsigned(b)=Parse_UIntField<?,?+b>" \
-                         "ParseField_signed(b)=Parse_IntField<?,?+b>" \
-                         "ParseField_bool(b)=Parse_Flag<?>"
+PREDEFINED             = \
+    DOXYGEN \
+    "SENF_PPI_MODULE(x)=" \
+    "SENF_PARSER_INHERIT(name)=" \
+    "SENF_PARSER_FIELD(name,type)=type name() const" \
+    "SENF_PARSER_FIELD_RO(name,type)=type::value_type name() const" \
+    "SENF_PARSER_BITFIELD(name, bits, type)=senf::ParseField_ ## type(bits) name() const" \
+    "SENF_PARSER_BITFIELD_RO(name, bits, type)=senf::ParseField_ ## type(bits)::value_type name() const" \
+    "SENF_PARSER_CUSTOM_FIELD(name, type, size, isize)=type name() const" \
+    "SENF_PARSER_PRIVATE_FIELD(name,type)=private: type name() const; public:" \
+    "SENF_PARSER_PRIVATE_FIELD_RO(name, type)=private: type::value_type name() const; public:" \
+    "SENF_PARSER_PRIVATE_BITFIELD(name, bits, type)=private: senf::ParseField_ ## type(bits) name() const; public:" \
+    "SENF_PARSER_PRIVATE_BITFIELD_RO(name, bits, type)=private: senf::ParseField_ ## type(bits)::value_type name() const; public:" \
+    "SENF_PARSER_SKIP(x)=" \
+    "SENF_PARSER_SKIP_BITS(x)=" \
+    "SENF_PARSER_GOTO(x)=" \
+    "SENF_PARSER_GOTO_OFFSET(x)=" \
+    "SENF_PARSER_LABEL(x)=" \
+    "SENF_PARSER_INIT()=void init()" \
+    "SENF_PARSER_FINALIZE(name)=" \
+    "ParseField_unsigned(b)=Parse_UIntField<?,?+b>" \
+    "ParseField_signed(b)=Parse_IntField<?,?+b>" \
+    "ParseField_bool(b)=Parse_Flag<?>" \
+    "SENF_PARSER_ARRAY(name,elt_type,size)=senf::Parse_Array<size,elt_type> name() const" \
+    "SENF_PARSER_LIST_B(name,elt_type,size_type)=senf::Parse_ListB<elt_type,size_type>::parser name() const" \
+    "SENF_PARSER_LIST_N(name,elt_type,size_type)=senf::Parse_ListN<elt_type,size_type>::parser name() const" \
+    "SENF_PARSER_VARIANT(name,chooser,types)=senf::Parse_Variant_Direct<chooser ## _t,?,types>::parser name() const" \
+    "SENF_PARSER_PRIVATE_VARIANT(name,chooser,types)=private: senf::Parse_Variant_Direct<chooser ## _t,?,types>::parser name() const; public:" \
+    "SENF_PARSER_VEC_N(name,elt_type,size_type)=senf::Parse_VectorN<elt_type,size_type> name() const"
 EXPAND_AS_DEFINED      = prefix_
 
 HTML_HEADER            = "$(TOPDIR)/doclib/doxy-header.html"
@@ -72,3 +79,8 @@ DOT_CLEANUP            = NO
 DOT_PATH               = "$(TOPDIR)/doclib"
 
 @INCLUDE = "$(TOPDIR)/Doxyfile.local"
+
+# Local Variables:
+# mode: indented-text
+# indent-tabs-mode: nil
+# End:
\ No newline at end of file
index e4106b2..1c6835c 100644 (file)
--- a/senf.dict
+++ b/senf.dict
@@ -86,6 +86,7 @@ EventManager
 eventsPerInterval
 EventType
 ExampleListPolicy
+ExampleVariantPolicy
 ExampleVectorPolicy
 ExtendedParser
 FFFF
@@ -155,10 +156,13 @@ MPEGDVBBundle
 multicast
 MyList
 MyParser
+MyVariant
+MyVariantPolicy
 MyVector
 namespace
 nc
 netcat
+NETwork
 NextPacket
 nextPacketKey
 nextPacketRange
@@ -213,6 +217,7 @@ parsermacrofields
 parsermacroinit
 parsermacrooffset
 parsermacrosbitfields
+ParseVariant
 ParseVec
 PassiveConnector
 PassiveInput
@@ -295,6 +300,8 @@ tr
 TruncatedPacketException
 tt
 ttl
+TypeA
+TypeB
 typeField
 udp
 UDPPacket