\see senf::Parser_Variant
\ingroup parsecollection
*/
- template <class ChooserType, unsigned Distance, SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
+ template <class ChooserType, unsigned Distance, class Translator,
+ SENF_PARSE_VARIANT_TPL_ARGS_DFL(class P)>
struct Parse_Variant_Direct
{
- typedef Parse_Variant< detail::Parse_Variant_Direct<ChooserType, Distance>,
+ typedef Parse_Variant< detail::Parse_Variant_Direct<ChooserType, Distance, Translator>,
SENF_PARSE_VARIANT_TPL_ARGS(P) > parser;
};
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.
+ \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
(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>(); }
+ senf::Parse_UInt8 uint8() const { return content().get<1>(); }
+ senf::Parse_UInt16 uint16() const { return content().get<2>(); }
+ senf::Parse_UInt24 uint24() const { return content().get<3>(); }
+ senf::Parse_UInt32 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>(); }
+ void set_uint16() const { content().init<2>(); }
+ void set_uint24) const { content().init<3>(); }
+ void set_uint23() const { content().init<4>(); }
SENF_PARSER_FINALIZE(SomeParser);
};
\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)
\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 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
+ */
+# 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)
}