#include "Server.hh"
#include "ParsedCommand.hh"
#include "ScopedDirectory.hh"
+#include "OverloadedCommand.hh"
#include "Config.hh"
+#include "ConfigFile.hh"
+#include "ProgramOptions.hh"
///////////////////////////////hh.e////////////////////////////////////////
//#include "Console.cci"
\see \ref console_testserver for a complete example application
- \section intro_usage Access
+ \section intro_usage Access: Configuration files, Network console, ...
There are several ways to access the node tree:
\li By parsing configuration files
\li By parsing command line parameters
- \li By providing interactive console access
+ \li By providing interactive or non-interactive network console access
\see console_access
namespace senf {
namespace detail {
+ /** \brief Internal: Prefix aux-parser policy
+
+ Place auxiliary field directly before a container/collection.
+ */
template <class P>
struct PrefixAuxParserPolicy
{
PacketParserBase::data_iterator adjust(PacketParserBase::data_iterator i, PacketParserBase::state_type s) const;
};
+ /** \brief Internal: Fixed distance aux-parser policy
+
+ Place auxiliary field a fixed distance before the container/collection
+ */
template <class P, unsigned Dist>
struct FixedAuxParserPolicy
{
template <class P> struct DynamicWrapperAuxParserPolicy;
+ /** \brief Internal: Dynamic aux-parser policy
+
+ Place auxiliary field at a variable distance before the container/collection
+ */
template <class P>
struct DynamicAuxParserPolicy
{
mutable P p_;
};
+ /** \brief Internal: Dynamic aux-parser policy (container wrapper)
+
+ Place auxiliary field at a variable distance before the container/collection. This is the
+ wrapper policy used by DynamicAuxParserPolicy
+ */
template <class P>
struct DynamicWrapperAuxParserPolicy
{
mutable SafePacketParserWrapper<P> p_;
};
+ /** \brief Internal: Apply transformation to arbitrary aux-parser policy
+
+ Transform must statisfy the interface
+ \code
+ struct Transform
+ {
+ typedef unspecified value_type;
+ static value_type get(unspecified v);
+ static unspecified set(value_type v);
+ };
+ \endcode
+ */
template <class Policy, class Transform>
struct TransformAuxParserPolicy
: public Policy
namespace senf {
- namespace detail { template <class ElementParser, class BytesParser>
- class ListBParser_Policy; }
-
- /** \brief List parser with size-field in bytes
-
- This list parser will parse a list which size is given by a preceding field containing the
- length of the list in bytes. This struct is just a template typedef:
- \code
- typedef senf::VectorNParser< Parser_UInt32, Parser_UInt16 >::parser MyVectorParser;
- typedef senf::ListBParser< MyVectorParser, UInt16Parser >::parser MyListParser;
- \endcode
- This first defines a Vector of 32 bit unsigned integers with 16 bit length counter. Then it
- defines a list of such vectors with a 16 bit bytes field.
-
- \warning There are some caveats when working with this kind of list
- \li You may <b>only change the size of a contained element from a container wrapper</b>.
- \li While you hold a container wrapper, <b>only access the packet through this wrapper</b>
- or a nested wrapper either for reading or writing.
-
- If lists are nested, you need to allocate a container wrapper for each level and may only
- access the packet through the lowest-level active container wrapper.
-
- \implementation These restrictions are necessary to ensure correct recalculation of the
- <tt>bytes</tt> field. For more info, see the comments in \ref ListBParser.ih
-
- \see ListParser
- \ingroup parsecollection
- */
-
- /** \brief Define ListBParser field
-
- This macro is a special helper to define a senf::ListBParser 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
- */
}
///////////////////////////////hh.e////////////////////////////////////////
size_type size (data_iterator i, state_type s) const;
void init (data_iterator i, state_type s) const;
+ /** \brief Internal: ListBParser container/wrapper policy */
struct container_policy
: public AuxPolicy
{
void insert (container_type & c, data_iterator p);
void update (container_type const & c) const;
+ /** \brief Internal: ListBParser specific iterator data */
struct iterator_data {};
data_iterator setBegin (container_type const & c, iterator_data & d) const;
};
};
+#ifndef DOXYGEN
+
template <class ElementParser, class AuxPolicy>
struct ListParserPolicy<ElementParser, AuxPolicy, senf::detail::auxtag::bytes>
{
TransformAuxParserPolicy<AuxPolicy, Transform> > type;
};
+#endif
+
}}
///////////////////////////////ih.e////////////////////////////////////////
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
-
- /** \brief List parser with size-field giving number of list elements
-
- This parser will parse a list which size is giving by a preceding field containing the
- number of list elements. This struct is just a 'template typedef':
- \code
- senf::VectorNParser< Parser_UInt32, Parser_UInt16 >::parser MyVectorParser;
- senf::ListNParser< MyVectorParser, UInt16Parser >::parser MyListParser;
- \endcode
- This first defines a Vector of 32 bit unsigned integers with 16 bit length counter. Then it
- defines a list of such vectors with a 16 bit size field.
-
- \see ListParser
- \ingroup parsecollection
- */
-
- /** \brief Define ListNParser field
-
- This macro is a special helper to define a senf::ListNParser 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
- */
}
///////////////////////////////hh.e////////////////////////////////////////
void insert (container_type & c, data_iterator p) const;
void update (container_type const & c) const;
+ /** Internal: ListNParser iterator specific data
struct iterator_data {
size_type n_;
};
data_iterator raw (container_type const & c, iterator_data const & d) const;
};
+#ifndef DOXYGEN
+
template <class ElementParser, class AuxPolicy>
struct ListParserPolicy<ElementParser, AuxPolicy, senf::detail::auxtag::none>
{
TransformAuxParserPolicy<AuxPolicy, Transform> > type;
};
+#endif
+
}}
///////////////////////////////ih.e////////////////////////////////////////
provides a reduced interface to this sequence, the container wrapper provides the complete
interface.
- Pare_List makes use of a policy template argument, \a ListPolicy, to customize the way the
- list is laid out. This policy is given quite some freedom in the list
- implementation. It is however important, that list elements <em>always follow each other
- without padding</em> (if padding is needed, it needs to be part of the element parser).
+ ListParser makes use of a policy template argument, \a ListPolicy, to customize the way the
+ list is laid out. This policy is given quite some freedom in the list implementation. It is
+ however important, that list elements <em>always follow each other without padding</em> (if
+ padding is needed, it needs to be part of the element parser).
+
+ You will normally not instantiate ListParser directly, you will use the \ref
+ SENF_PARSER_LIST() helper macro.
\see ExampleListPolicy
\ingroup parsecollection
size_type i_;
};
-# define SENF_PARSER_LIST(name, size, elt_type) \
- SENF_PARSER_LIST_I(public, name, size, elt_type)
+ /** \brief Define ListParser field
+
+ This macro is a special helper to define a senf::ListParser type field, a list of elements
+ of type \a elt_type (a parser) which size is determined by \a size.
+
+ \code
+ // The size field should be declared private or read-only (size is accessible via the list)
+ SENF_PARSER_PRIVATE_FIELD ( list_size_, senf::UInt16Parser );
+ // Define the list
+ SENF_PARSER_VECTOR ( list, list_size_, EltParser );
+ \endcode
+
+ Here \c EltParser can be an arbitrary parser and need not have a fixed size.
+
+ Further additional tags are supported which modify the type of list created:
+
+ <table class="senf fixedcolumn">
+ <tr><td>\c bytes(\a size)</td><td>\a size gives the size of the list in bytes not the
+ number of contained elements</td></tr>
+
+ <tr><td>\c transform(\a transform, \a size)</td><td>The \a transform is applied to the \a
+ size value, the value is not used directly</td>
+
+ <tr><td>\c transform(\a transform, \c bytes(\a size))</td><td>The \a transform is applied to
+ the \a size value. The value is then interpreted containing the list size in bytes not
+ number of elements</td>
+ </table>
+
+ The optional \a transform is a class with the following layout
+ \code
+ struct MyTransform
+ {
+ typedef ... value_type;
+ static value_type get(other_type v);
+ static other_type set(value_type v);
+ };
+ \endcode
+
+ \c other_type is \a size ::\c value_type, the type of the value returned by the \a size
+ field, whereas the \c value_type typedef is the arbitrary return type of the transform.
+
+ The tags are applied to the \a size parameter:
+ \code
+ SENF_PARSER_LIST ( vec, transform(MyTransform, list_size_), EltParser );
+ \endcode
+
+ \warning There are some caveats when working with \c bytes() type lists:
+ \li You may <b>only change the size of a contained element from a container wrapper</b>.
+ \li While you hold a container wrapper, <b>only access the packet through this wrapper</b>
+ or a nested wrapper either for reading or writing.
+
+ \warning If lists are nested, you need to allocate a container wrapper for each level and
+ may only access the packet through the lowest-level active container wrapper.
+
+ \implementation These restrictions are necessary to ensure correct recalculation of the
+ <tt>bytes</tt> field. For more info, see the comments in \ref ListBParser.ih
+
+ \param[in] name field name
+ \param[in] size name of field giving the list size
+ \param[in] elt_type list element type
+
+ \hideinitializer
+ \ingroup packetparsermacros
+ */
+# define SENF_PARSER_LIST(name, size, elt_type) \
+ SENF_PARSER_LIST_I(public, name, size, elt_type)
+
+ /** \brief Define private ListParser field
+
+ \see \ref SENF_PARSER_LIST()
-# define SENF_PARSER_PRIVATE_LIST(name, size, elt_type) \
+ \hideinitializer
+ \ingroup packetparsermacros
+ */
+# define SENF_PARSER_PRIVATE_LIST(name, size, elt_type) \
SENF_PARSER_LIST_I(private, name, size, elt_type)
}
Container const * c_;
};
+#ifndef DOXYGEN
+
template <class ElementParser, class AuxPolicy, class AuxTag>
struct ListParserPolicy
{};
size, \
senf::detail::ListParserTraits<elt_type> )
+#endif
+
}}
///////////////////////////////ih.e////////////////////////////////////////
struct init_bytes : public detail::ParserInitBytes<Parser>
{};
+ /** \brief Test, whether a parser is a fixed-size parser
+
+ This meta-function is called like
+ \code
+ senf::is_fixed<SomeParser>::value
+ \endcode
+
+ This expression evaluates to a compile-time constant boolean expression which is \c true, if
+ \a SomeParser is a fixed size parser, \c false otherwise
+
+ \param[in] Parser The Parser to test
+ \returns \c true, if \a Parser is fixed size, \c false otherwise
+ \ingroup packetparser
+ */
template <class Parser>
struct is_fixed : public detail::ParserIsFixed<Parser>
{};
# ///////////////////////////////////////////////////////////////////////////
# // SENF_PARSER_COLLECTION_I
#
+# ifndef DOXYGEN
+#
namespace senf { namespace detail { namespace auxtag {
struct none {}; } } }
namespace senf { namespace detail { namespace auxtag {
namespace senf { namespace detail { namespace auxtag {
template <class Transform, class Tag>
struct transform {}; } } }
+#
+# endif
#
# define SENF_PARSER_COLLECTION_TAG_GOBBLE__bytes(x)
# define SENF_PARSER_COLLECTION_TAG__bytes(x) bytes()
#
# define SENF_PARSER_COLLECTION_AUXTYPE_fix(name, aux)
#
+# ifndef DOXYGEN
+#
namespace senf { namespace detail {
template <class Parser> struct DynamicAuxParserPolicy;
template <class Parser, unsigned offset> struct FixedAuxParserPolicy;
{ typedef senf::detail::FixedAuxParserPolicy<Parser, fixedOffset> type; };
}};
#
+# endif
+#
# define SENF_PARSER_COLLECTION_AUX_I_var(name, aux) \
senf::detail::ParserAuxPolicySelect< BOOST_PP_CAT(aux, _t), \
SENF_PARSER_CURRENT_FIXED_OFFSET() \
+++ /dev/null
-// $Id$
-//
-// Copyright (C) 2007
-// Fraunhofer Institute for Open Communication Systems (FOKUS)
-// Competence Center NETwork research (NET), St. Augustin, GERMANY
-// 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 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
- {
- 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; ///< 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). */
- };
-
-}
-
-\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:
\code
typedef senf::VariantParser<
MyAuxPolicy,
- senf::VoidPacketParser, TypeAParser, TypeBParser> MyVariantParser;
+ senf::mpl::vector<senf::VoidPacketParser, TypeAParser, TypeBParser> > MyVariantParser;
\endcode
This typedef defines a variant parser choosing one of three sub
parsers. senf::VoidPacketParser is an empty parser, it effectively makes this parser
\post variant() == \a N */
};
- /** \brief Define DirectVariantParser field
+ /** \brief Define VariantParser field
This macro is a special helper to define a senf::DirectVariantParser type field. This is a
variant field which chooses the sub-type by directly taking the value of some other field.
- \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
{
It is customary, to hide the variant parser (by defining it private) and provide more
conveniently named accessors.
+ Further additional tags are supported which modify the way, the \a chooser field is
+ interpreted:
+
+ <table class="senf fixedcolumn">
+ <tr><td>\c transform(\a transform, \a size)</td><td>The \a transform is applied to the \a
+ chooser value, the value is not used directly</td>
+ </table>
+
+ The optional \a transform is a class with the following layout
+
+ \code
+ struct MyTransform
+ {
+ typedef ... value_type;
+ static value_type get(other_type v);
+ static other_type set(value_type v);
+ };
+ \endcode \c other_type is the \a chooser ::\c value_type where as the \c value_type typedef
+ is the arbitrary return type of the transform.
+
+ The tags are applied to the \a chooser parameter:
+ \code
+ SENF_PARSER_VARIANT ( content, transform(MyTransform, type_),
+ (senf::VoidPacketParser)
+ (senf::UInt8Parser)
+ (senf::UInt16Parser)
+ (senf::UInt24Parser)
+ (senf::UInt32Parser) );
+ \endcode
+
\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
# define SENF_PARSER_VARIANT(name, chooser, types) \
SENF_PARSER_VARIANT_I(public, name, chooser, types)
- /** \brief Define DirectVariantParser field (private)
+ /** \brief Define private VariantParser field
\see \ref SENF_PARSER_VARIANT()
\hideinitializer
*/
# define SENF_PARSER_PRIVATE_VARIANT(name, chooser, types) \
SENF_PARSER_VARIANT_I(private, name, chooser, types)
-
- /** \brief Define DirectVariantParser 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
- */
-
-
}
///////////////////////////////hh.e////////////////////////////////////////
static PacketParserBase::size_type bytes(Variant const & v, unsigned n);
};
-# endif
-
template <class AuxPolicy, class AuxTag>
struct VariantParserPolicy {};
};
};
-# define SENF_PARSER_VARIANT_I(access, name, chooser, types) \
+# define SENF_PARSER_VARIANT_I(access, name, chooser, types) \
typedef boost::mpl::vector< BOOST_PP_SEQ_ENUM(types) > BOOST_PP_CAT(name, _parsers); \
SENF_PARSER_REQUIRE_VAR(variant) \
SENF_PARSER_COLLECTION_I( \
chooser, \
senf::detail::VariantParserTraits< BOOST_PP_CAT(name, _parsers) > )
+# endif
+
}}
///////////////////////////////ih.e////////////////////////////////////////
+++ /dev/null
-// $Id$
-//
-// Copyright (C) 2007
-// Fraunhofer Institute for Open Communication Systems (FOKUS)
-// Competence Center NETwork research (NET), St. Augustin, GERMANY
-// 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:
A vector is a model of an STL random-access sequence. The parser only provides a reduced
interface, the container wrapper however completes this interface.
- VectorParser makes use of a policy template argument, \a Sizer, to customize the way the
- containers size is obtained. You will normally not instantiate Parser_Vector directly, you
- will use one of the 'template typedefs' (which are templated structures since C++ does not
- provide real template typedefs) provided with the policy implementations.
+ VectorParser makes use of a policy template argument, \a AuxPolicy, to customize the way the
+ containers size is obtained. You will normally not instantiate VectorParser directly, you
+ will use the \ref SENF_PARSER_VECTOR() helper macro.
- \todo Make the sizer a private base-class to profit from the empty-base-class optimization
-
- \see ExampleVectorPolicy
\ingroup parsecollection
*/
template <class ElementParser, class AuxPolicy>
friend class VectorParser_Container<ElementParser,AuxPolicy>;
};
- /** \brief Define VectorNParser field
-
- This macro is a special helper to define a senf::VectorNParser type field, a vector of
- elements of type \a elt_type (a parser) which size is given by the \a size field.
-
- \code
- // The size field should be declared private (size is accessible via the vector)
- SENF_PARSER_PRIVATE_FIELD ( vec_size_, senf::UInt16Parser );
- // Define the vector, here it has 32bit unsigned integer elements
- SENF_PARSER_VEC_N ( vec, vec_size_, senf::UInt32Parser );
- \endcode
-
- \param[in] name field name
- \param[in] size name of field giving the vector size
- \param[in] elt_type vector element type
- \hideinitializer
- \ingroup packetparsermacros
- */
-
- /** \brief Define VectorNParser field
-
- \see \ref SENF_PARSER_VEC_N()
- \hideinitializer
- \ingroup packetparsermacros
- */
-
-# define SENF_PARSER_VECTOR(name, size, elt_type) \
- SENF_PARSER_VECTOR_I(public, name, size, elt_type)
-
-# define SENF_PARSER_PRIVATE_VECTOR(name, size, elt_type) \
- SENF_PARSER_VECTOR_I(private, name, size, elt_type)
-
-
-
/** \brief VectorParser container wrapper
This is the container wrapper used for vector parsers. The container wrapper will stay valid
size_type i_;
};
+ /** \brief Define VectorParser field
+
+ This macro is a special helper to define a senf::VectorParser type field, a vector of
+ elements of type \a elt_type (a parser) which size is given by the \a size field.
+
+ \code
+ // The size field should be declared private (size is accessible via the vector)
+ SENF_PARSER_PRIVATE_FIELD ( vec_size_, senf::UInt16Parser );
+ // Define the vector, here it has 32bit unsigned integer elements
+ SENF_PARSER_VECTOR ( vec, vec_size_, senf::UInt32Parser );
+ \endcode
+
+ Further additional tags are supported which modify the way, the \a size field is
+ interpreted:
+
+ <table class="senf fixedcolumn">
+ <tr><td>\c bytes(\a size)</td><td>\a size gives the size of the vector in bytes not the
+ number of contained elements</td></tr>
+
+ <tr><td>\c transform(\a transform, \a size)</td><td>The \a transform is applied to the \a
+ size value, the value is not used directly</td>
+ </table>
+
+ The optional \a transform is a class with the following layout
+
+ \code
+ struct MyTransform
+ {
+ typedef ... value_type;
+ static value_type get(other_type v);
+ static other_type set(value_type v);
+ };
+ \endcode \c other_type is the \a size ::\c value_type where as the \c value_type typedef is
+ the arbitrary return type of the transform.
+
+ The tags are applied to the \a size parameter:
+ \code
+ SENF_PARSER_VECTOR ( vec, transform(MyTransform, vec_size_), senf::UInt32Parser );
+ \endcode
+
+ \param[in] name field name
+ \param[in] size name of field giving the vector size
+ \param[in] elt_type vector element type
+
+ \hideinitializer
+ \ingroup packetparsermacros
+ */
+# define SENF_PARSER_VECTOR(name, size, elt_type) \
+ SENF_PARSER_VECTOR_I(public, name, size, elt_type)
+
+ /** \brief Define private VectorParser field
+
+ \see \ref SENF_PARSER_VECTOR()
+
+ \hideinitializer
+ \ingroup packetparsermacros
+ */
+# define SENF_PARSER_PRIVATE_VECTOR(name, size, elt_type) \
+ SENF_PARSER_VECTOR_I(private, name, size, elt_type)
}
///////////////////////////////hh.e////////////////////////////////////////
namespace senf {
namespace detail {
+#ifndef DOXYGEN
+
template <class ElementParser, class AuxPolicy, class AuxTag>
struct VectorParserPolicy
{};
size, \
senf::detail::VectorParserTraits<elt_type> )
+#endif
+
}}
///////////////////////////////ih.e////////////////////////////////////////