// $Id$
//
-// Copyright (C) 2007
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer NETwork research (NET)
+// 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
#include "PacketParser.hh"
//#include "VariantParser.mpp"
-#include "VariantParser.ih"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
packet change depending on some condition.
\code
typedef senf::VariantParser<
- MyVariantPolicy,
- senf::VoidPacketParser, TypeAParser, TypeBParser> MyVariantParser;
+ MyAuxPolicy,
+ 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
initialized to the first sub-parser.
\see
- ExampleVariantPolicy on how to implement the \a VariantPolicy \n
+ ExampleAuxPolicy on how to implement the \a AuxPolicy \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)>
+ template <class AuxPolicy, class Parsers>
class VariantParser
- : public PacketParserBase, private VariantPolicy
+ : public PacketParserBase, private AuxPolicy
{
- typedef boost::mpl::vector< SENF_PARSE_VARIANT_TPL_ARGS(P) > parsers;
+ typedef Parsers parsers;
public:
///\name Parser interface
///\{
VariantParser(data_iterator i, state_type s);
- VariantParser(VariantPolicy policy, data_iterator i, state_type s);
+ VariantParser(AuxPolicy policy, data_iterator i, state_type s);
size_type bytes() const;
void init();
- static const size_type init_bytes =
- senf::init_bytes<P0>::value + VariantPolicy::init_bytes;
+ static const size_type init_bytes = senf::init_bytes<
+ typename boost::mpl::at<parsers, boost::mpl::int_<0> >::type>::value
+ + AuxPolicy::aux_bytes;
///\}
///////////////////////////////////////////////////////////////////////////
\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::VariantParser::get()
- and senf::Parser_Variant::init()).
-
- \code
- // Define a variant choosing between FooParser and BarParser depending on the directly
- // preceding 1-byte 8bit uint value
- typedef senf::DirectVariantParser< senf::UInt8Parser, 1u,
- FooParser, BarParser >::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, class Translator,
- SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
- struct DirectVariantParser
- {
- typedef VariantParser< detail::DirectVariantParser<ChooserType, Distance, Translator>,
- SENF_PARSE_VARIANT_TPL_ARGS(P) > parser;
- };
-
- /** \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
\hideinitializer
\ingroup packetparsermacros
*/
-# define SENF_PARSER_VARIANT(name, chooser, types) \
- SENF_PARSER_VARIANT_I(SENF_PARSER_FIELD, \
- name, \
- chooser, \
- senf::detail::VariantParser_IdentityTranslator, \
- types)
-
- /** \brief Define DirectVariantParser 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, \
- senf::detail::VariantParser_IdentityTranslator, \
- 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.
+# define SENF_PARSER_VARIANT(name, chooser, types) \
+ SENF_PARSER_VARIANT_I(public, name, chooser, types)
- \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 DirectVariantParser field with translator (private)
+ /** \brief Define private VariantParser field
- \see \ref SENF_PARSER_VARIANT_TRANS()
+ \see \ref SENF_PARSER_VARIANT()
\hideinitializer
\ingroup packetparsermacros
*/
-# define SENF_PARSER_PRIVATE_VARIANT_TRANS(name, chooser, types) \
- SENF_PARSER_VARIANT_I(SENF_PARSER_PRIVATE_FIELD, \
- name, \
- chooser, \
- translator, \
- types)
-
+# define SENF_PARSER_PRIVATE_VARIANT(name, chooser, types) \
+ SENF_PARSER_VARIANT_I(private, name, chooser, types)
}
///////////////////////////////hh.e////////////////////////////////////////