From: g0dil Date: Thu, 22 Nov 2007 16:42:31 +0000 (+0000) Subject: Packets: Add 'Translator' argument to Parse_Variant_Direct X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=8c97e5bc3a21a54d09b20b32853a3b2b76b119b2;p=senf.git Packets: Add 'Translator' argument to Parse_Variant_Direct git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@526 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Packets/ParseVariant.hh b/Packets/ParseVariant.hh index 9deb622..0c33791 100644 --- a/Packets/ParseVariant.hh +++ b/Packets/ParseVariant.hh @@ -151,10 +151,11 @@ namespace senf { \see senf::Parser_Variant \ingroup parsecollection */ - template + template struct Parse_Variant_Direct { - typedef Parse_Variant< detail::Parse_Variant_Direct, + typedef Parse_Variant< detail::Parse_Variant_Direct, SENF_PARSE_VARIANT_TPL_ARGS(P) > parser; }; @@ -210,8 +211,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 +224,61 @@ 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 foChooser(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) } diff --git a/Packets/ParseVariant.ih b/Packets/ParseVariant.ih index 0e33da0..1166077 100644 --- a/Packets/ParseVariant.ih +++ b/Packets/ParseVariant.ih @@ -56,7 +56,7 @@ namespace detail { # endif /** \brief Internal: Variant Policy used by senf::Parse_Variant_Direct */ - template + template struct Parse_Variant_Direct { typedef PacketParserBase::data_iterator data_iterator; @@ -72,20 +72,27 @@ namespace detail { } unsigned variant(data_iterator i, state_type s) const { - return chooser(i,s).value(); + return Translator::fromChooser(chooser(i,s).value()); } void variant(unsigned v, data_iterator i, state_type s) { - chooser(i,s).value(v); + chooser(i,s).value(Translator::toChooser(v)); } }; + /** \brief Internal: Identity chooser translator */ + struct Parse_Variant_IdentityTranslator { + static unsigned fromChooser(unsigned value) { return value; } + static unsigned toChooser(unsigned value) { return value; } + }; + # define SENF_PARSER_VARIANT_(r, data, elem) ,elem -# define SENF_PARSER_VARIANT_I(field, name, chooser, types) \ +# define SENF_PARSER_VARIANT_I(field, name, chooser, translator, types) \ typedef senf::Parse_Variant_Direct< \ BOOST_PP_CAT(chooser, _t), \ - SENF_PARSER_CURRENT_FIXED_OFFSET() - SENF_PARSER_FIXED_OFFSET(chooser) \ + SENF_PARSER_CURRENT_FIXED_OFFSET() - SENF_PARSER_FIXED_OFFSET(chooser), \ + translator \ BOOST_PP_SEQ_FOR_EACH( SENF_PARSER_VARIANT_, _, types ) \ >::parser BOOST_PP_CAT(name, _variant_t); \ field( name, BOOST_PP_CAT(name, _variant_t) ) diff --git a/Packets/ParseVariant.test.cc b/Packets/ParseVariant.test.cc index e795e49..41935d5 100644 --- a/Packets/ParseVariant.test.cc +++ b/Packets/ParseVariant.test.cc @@ -38,7 +38,7 @@ BOOST_AUTO_UNIT_TEST(parseVariant) { typedef senf::Parse_Array<10, senf::Parse_UInt8> Array10; - typedef senf::Parse_Variant_Direct< senf::Parse_UInt8, 1, + typedef senf::Parse_Variant_Direct< senf::Parse_UInt8, 1, senf::detail::Parse_Variant_IdentityTranslator, senf::VoidPacketParser, Array10, senf:: Parse_UInt32