X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FVariantParser.hh;h=1887cd911e3e0a6fc57213db6644dd0c6b143c29;hb=6d96e131a920c32fe244f31b6621339a663414c2;hp=0bba1b1447d4376cd166f25363359e7e4de9dc91;hpb=a1001797645cc68c869ef296f5e9ba13aa8e80c4;p=senf.git diff --git a/Packets/VariantParser.hh b/Packets/VariantParser.hh index 0bba1b1..1887cd9 100644 --- a/Packets/VariantParser.hh +++ b/Packets/VariantParser.hh @@ -1,8 +1,8 @@ // $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 // // This program is free software; you can redistribute it and/or modify @@ -39,7 +39,6 @@ #include "PacketParser.hh" //#include "VariantParser.mpp" -#include "VariantParser.ih" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { @@ -62,8 +61,8 @@ namespace senf { packet change depending on some condition. \code typedef senf::VariantParser< - MyVariantPolicy, - senf::VoidPacketParser, TypeAParser, TypeBParser> MyVariantParser; + MyAuxPolicy, + senf::mpl::vector > 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 @@ -73,28 +72,29 @@ namespace senf { 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 + template 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::value + VariantPolicy::init_bytes; + static const size_type init_bytes = senf::init_bytes< + typename boost::mpl::at >::type>::value + + AuxPolicy::aux_bytes; ///\} /////////////////////////////////////////////////////////////////////////// @@ -123,51 +123,11 @@ namespace senf { \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 - struct DirectVariantParser - { - typedef VariantParser< detail::DirectVariantParser, - 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 { @@ -202,6 +162,36 @@ namespace senf { 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: + + + +
\c transform(\a transform, \a size)The \a transform is applied to the \a + chooser value, the value is not used directly
+ + 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 @@ -212,74 +202,17 @@ namespace senf { \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////////////////////////////////////////