Macros | |
#define | SENF_PARSER_ARRAY(name, elt_type, size) |
Define array field. More... | |
#define | SENF_PARSER_LIST(name, size, elt_type) |
Define ListParser field. More... | |
#define | SENF_PARSER_PRIVATE_LIST(name, size, elt_type) |
Define private ListParser field. More... | |
#define | SENF_PARSER_VARIANT(name, chooser, types) |
Define VariantParser field. More... | |
#define | SENF_PARSER_PRIVATE_VARIANT(name, chooser, types) |
Define private VariantParser field. More... | |
#define | SENF_PARSER_VECTOR(name, size, elt_type) |
Define VectorParser field. More... | |
#define | SENF_PARSER_PRIVATE_VECTOR(name, size, elt_type) |
Define private VectorParser field. More... | |
Control information | |
#define | SENF_FIXED_PARSER() |
Define fixed size parser. More... | |
#define | SENF_PARSER() |
Define dynamically sized parser. More... | |
#define | SENF_PARSER_INIT() |
Define parser initialization routine. More... | |
#define | SENF_PARSER_INHERIT(base) |
Define parser inheritance. More... | |
#define | SENF_PARSER_FINALIZE(name) |
Generate parser control members. More... | |
Parser fields | |
#define | SENF_PARSER_FIELD(name, type) |
Define normal parser field. More... | |
#define | SENF_PARSER_FIELD_RO(name, type) |
Define parser field (read-only) More... | |
#define | SENF_PARSER_PRIVATE_FIELD(name, type) |
Define parser field (private) More... | |
#define | SENF_PARSER_CUSTOM_FIELD(name, type, size) |
Define custom field accessor. More... | |
Bit fields | |
#define | SENF_PARSER_BITFIELD(name, bits, type) |
Define bit-field. More... | |
#define | SENF_PARSER_BITFIELD_RO(name, bits, type) |
Define bit-field (read-only) More... | |
#define | SENF_PARSER_PRIVATE_BITFIELD(name, bits, type) |
Define bit-field (private) More... | |
Current offset | |
#define | SENF_PARSER_SKIP(skip) |
Skip bytes. More... | |
#define | SENF_PARSER_SKIP_BITS(bits) |
Skip bits within bitfield group. More... | |
#define | SENF_PARSER_GOTO(name) |
Change current offset. More... | |
#define | SENF_PARSER_GOTO_OFFSET(offset) |
Change current offset to explicit value. More... | |
#define | SENF_PARSER_LABEL(name) |
Define offset label. More... | |
#define | SENF_PARSER_OFFSET(name) |
Get field offset. More... | |
#define | SENF_PARSER_FIXED_OFFSET(name) |
Get fixed field offset, if possible. More... | |
#define | SENF_PARSER_CURRENT_FIXED_OFFSET() |
Get current fixed offset, if possible. More... | |
To simplify the definition of simple packet parsers, several macros are provided. Before using these macros you should familiarize yourself with the packet parser interface as described in senf::PacketParserBase.
These macros simplify providing the above defined interface. A typical packet declaration using these macros has the following form (This is a concrete example from the definition of the ethernet packet in DefaultBundle/EthernetPacket.hh
)
The macros take care of the following: \li They define the accessor functions returning parsers of the given type. \li They automatically calculate the offset of the fields from the preceding fields. \li The macros provide a definition for \c init() \li The macros define the \c bytes(), \c fixed_bytes and \c init_bytes members as needed. You may define either a fixed or a dynamically sized parser. Fixed size parsers are defined by starting the packet with <tt>\#include SENF_FIXED_PARSER()</tt>, dynamically sized parsers start with <tt>\#include SENF_PARSER()</tt>. The different members are implemented such that: \li The needed parser constructor is defined \li \c init() calls \c defaultInit(). \c defaultInit() is defined to call \c init() on each of the fields. \li \c bytes() (on dynamically sized parser) respectively \c fixed_bytes (on fixed size parsers) is defined to return the sum of the sizes of all fields. \li On dynamically sized parsers, \c init_bytes is defined to return the sum of the \c init_byte's of all fields
The macros provided to help implement composite parsers implement a very small declarative language. This way of to think of the macros simplifies understanding, how the macros work. Central to this language is the concept of <em>current offset</em>. The current offset is the place (in bytes) from the beginning of the parser at which the next field will be added. Adding fields to the parser will advance this offset by the size of the field added. Additional commands allow to arbitrarily manipulate the current offset manually. For fixed size parsers, the current offset is a single constant integral value, the number of bytes from the parsers start. For dynamically sized parsers, the current offset really consists of two values: One is the number of bytes from the parsers start, which however needs not be a constant expression, the other value is the \c init_bytes value at this point, which is an integral constant. To demonstrate this functionality, here a more complex example (taken from \c MPEGDVBBundle and then simplified by removing some fields)
This code defines two parsers, the second of which is based on the first. Both are fixed size parsers. The definition of \c Parse_DSMCCSection is straight forward (more on bit fields below). The derived parser is a little bit more complex. It starts out the same defining itself as a fixed size parser. Then the base class is imported. Among other things, this call sets the current offset to the first byte after the base parser (the base parser need not be implemented using the packet parser macros, it just needs to be a valid parser). The additional fields \c mac_addr_4 and \c mac_addr_3 are defined. Then we finalize the parser declaration. <em>After</em> \ref SENF_PARSER_FINALIZE we add two more fields but not at the end of the parser. \ref SENF_PARSER_GOTO jumps back to a previously defined label or field. Since the base parser \c Parse_DSMCCSection is defined using the packet parser macros, we can even jump to labels or fields defined in the base parser. Here, we jump to the beginning of the \c table_id_extension field. \c mac_addr_6 and \c mac_addr_5 are therefore defined starting at that offset and therefore overlay the \c table_id_extension field.
\par "" \ref SENF_FIXED_PARSER(), \ref SENF_PARSER(), \ref SENF_PARSER_INHERIT(), \ref SENF_PARSER_INIT(), \ref SENF_PARSER_FINALIZE() Every parser using the parser macros starts either with <tt>\#include SENF_PARSER()</tt> or with <tt>\#include SENF_FIXED_PARSER()</tt>. This command sets the current offset to zero and defines the type of parser to define. A following optional \ref SENF_PARSER_INHERIT(\e base_class) is necessary if the parser does not derive from senf::PacketParserBase. This call sets the base class and advances the current offset to the end of the base parser. \ref SENF_PARSER_INIT() is used to define the parser initialization code (the \c init() member). \ref SENF_PARSER_FINALIZE(\e class_name) is called to define the parsers constructor, the \c init() member and to set the parsers size (\c fixed_bytes for fixed size parsers or \c bytes() and \c init_bytes for dynamically sized parsers). It is valid to define further fields \e after \ref SENF_PARSER_FINALIZE() has been called, however \li Fields defined after \ref SENF_PARSER_FINALIZE() will \e not be initialized by \c defaultInit() (and therefore not by the default provided \c init() member). This can be very helpful when defining overlaying fields to avoid initializing some bytes multiple times. \li The size of the parser is given by the current offset at the time of the \ref SENF_PARSER_FINALIZE() call.
\par "" \ref SENF_PARSER_FIELD(), \ref SENF_PARSER_FIELD_RO(), \ref SENF_PARSER_PRIVATE_FIELD(), \ref SENF_PARSER_CUSTOM_FIELD() There are quite a few commands available to define fields. All these macros do the same thing: they define a field accessor plus some auxiliary symbols. The accessor will use the parser type passed to the macro to parse the field. The current offset is adjusted according to the size of that parser. Normally, the parser will return an instance of the given parser type. There are some properties the field defining macros might have. These properties are parts of the macro name: \par \c RO: Read only fields Macros with \c RO in their name define read only fields. This is only possible, if the field's parser is a value parser (that is, it must have a \c value_type typedef member and must provide the \c value() accessor member function). In this case, the value returned from the \e name() accessor member is not the parser but the parsers value and therefore it does not allow assignment to the field. \par \c PRIVATE: Fields private to the parser class A private field will not be accessible from the outside (it is made \c private to the parser class). This is very handy when providing other accessor members to access a field in a manner more suitable for the specific field, when combining several fields into a single return value etc. The field defining macros come in groups which members only differ in their properties: <dl><dt><em>Standard fields:</em><dt><dd>\ref SENF_PARSER_FIELD(), \ref SENF_PARSER_FIELD_RO(), \ref SENF_PARSER_PRIVATE_FIELD() define standard fields.</dd> <dt><em>Arbitrary custom field:</em><dt><dd>\ref SENF_PARSER_CUSTOM_FIELD()</dd></dl> See the documentation of each of these macros for a detailed description of the macro arguments and usage. Bit-fields are handled in the following section. There also some supplementary macros for defining fields of more complex composite types (e.g. vectors). See the list of 'Defines' further down this page.
\par "" \ref SENF_PARSER_BITFIELD(), \ref SENF_PARSER_BITFIELD_RO(), \ref SENF_PARSER_PRIVATE_BITFIELD()\n Bit-fields play a special role. They are quite frequent in packet definitions but don't fit into the byte offset based parsing infrastructure defined so far. Since defining the correctly parameterized senf::IntFieldParser, senf::UIntFieldParser and senf::FlagParser typedefs is quite tedious, these helper macros are provided. It is important to recognize, that the current offset does \e not include the current bit position. The current offset after defining a bit-field will be the first complete byte after that bit-field. Only the bit-field macros additionally take care of the current bit position which is reset automatically by any intervening non-bitfield command. So bit-field commands will come in groups. Any group of consecutive bitfield commands defines a set of consecutive bits. The group as a whole will always be considered to cover a fixed number of complete bytes. If the group does not cover those bytes completely (there are some bit's left at the end), those bit's will be skipped. Since consecutive bit-field commands are aggregated into a single bit-field group, the offset of all these bit-fields will be the offset of the \e beginning of the group irrespective of the number of bits parsed so far. Changing the offset to some bitfield using \ref SENF_PARSER_GOTO() will therefore always go to the position at the beginning of this bitfield group. And since the current offset does not include the bit position, the bit position will be 0, the first bit. You may however break a bit-field group into two groups (at a byte boundary) by placing a \ref SENF_PARSER_LABEL() command between the two groups. The additional command \ref SENF_PARSER_SKIP_BITS() can be used to skip bit's between two bit-fields.
\par "" \ref SENF_PARSER_SKIP(), \ref SENF_PARSER_SKIP_BITS(), \ref SENF_PARSER_GOTO(), \ref SENF_PARSER_GOTO_OFFSET(), \ref SENF_PARSER_LABEL() To define more complex parsers, there are some macro commands which change the current offset. \ref SENF_PARSER_SKIP(\e bytes) will skip the given number of bytes. \ref SENF_PARSER_SKIP_BITS(\e bits) will work within bitfield definition to skip that number of bits. \ref SENF_PARSER_GOTO(\e label_or_field) will change the offset to the given field or label. The following fields will therefore start at that offset and overlay any fields already defined. \ref SENF_PARSER_GOTO_OFFSET(\e offset) will jump to the given byte offset from the start of the parser. \ref SENF_PARSER_LABEL(\e name) will define \e name as a label for the current offset which can then later be referenced using \ref SENF_PARSER_GOTO(). This also defines <em>name</em><tt>_offset</tt> as a constant or member (for fixed respectively dynamically sized parsers). It is very important to recognize, that the size of the parser is defined by the current offset <em>at the time \ref SENF_PARSER_FINALIZE() is called</em>. This allows to arbitrarily manipulate the size of the parser by changing the current offset accordingly. For dynamically sized parsers, the offset can even be any expression involving member function calls. See the documentation of the respective macros for more details.
#define SENF_FIXED_PARSER | ( | ) |
Define fixed size parser.
This macro must be called using #include
at the beginning of every fixed size parser using the packet parser helper macros:
The parser must directly or indirectly inherit from senf::PacketParserBase
Definition at line 293 of file ParseHelpers.hh.
#define SENF_PARSER | ( | ) |
Define dynamically sized parser.
This macro must be called using #include
at the beginning of every dynamically sized parser using the packet parser helper macros:
The parser must directly or indirectly inherit from senf::PacketParserBase
Definition at line 310 of file ParseHelpers.hh.
#define SENF_PARSER_ARRAY | ( | name, | |
elt_type, | |||
size | |||
) |
Define array field.
This macro is a special helper to define a senf::ArrayParser type field, a fixed size collection of fixed size elements.
[in] | name | field name |
[in] | elt_type | array element type |
[in] | size | constant number of elements |
Definition at line 100 of file ArrayParser.hh.
Define bit-field.
Bit fields are supported by a special family of parser macros. These macros simplify defining fields using the senf::IntFieldParser, senf::UIntFieldParser and senf::FlagParser parsers by keeping track of the current bit position and automatically creating the correct template parameters.
The type parameter specifies the type of bitfield to define. This value is one of
signed
, for signed bit fields (senf::IntFieldParser) unsigned
, for unsigned bit fields (senf::UIntFieldParser) or bool
, for single-bit flags (senf::FlagParser).The bits parameter specifies the number of bits the field covers. For signed
or unsigned
fields, this value may be any numeric value from 1 to 32, for bool
fields, this value must be 1.
For more information see Bit-fields
[in] | name | name of the bit field |
[in] | bits | number of bits |
[in] | type | bit field type, one of signed , unsigned or bool |
Definition at line 506 of file ParseHelpers.hh.
Define bit-field (read-only)
Define read-only bit field. This is for bit-fields what SENF_PARSER_FIELD_RO is for ordinary fields.
Definition at line 515 of file ParseHelpers.hh.
#define SENF_PARSER_CURRENT_FIXED_OFFSET | ( | ) |
Get current fixed offset, if possible.
This macro will return the current fixed offset, a compile-time constant expression. This is always possible when defining a fixed size parser.
Even in dynamically sized parsers this macro will work, if all parser defined before the current position are fixed-size parsers. This macro does not validate this condition, it will return an arbitrary incorrect value otherwise.
Definition at line 654 of file ParseHelpers.hh.
Define custom field accessor.
This macro is used to define a field using a custom access method:
The macro defines the same auxiliary symbols defined by \ref SENF_PARSER_FIELD(\a name, \a type), the accessor method however is provided by the user. \a size depends on the type of parser being defined: \li If defining a fixed parser, \a size is a single value \a bytes which must be a constant integral expression giving the fixed size of the field. \li If defining a dynamically sized parser, \a size is given by two parameters \a bytes and \a init_bytes. \a bytes is an arbitrary (not necessarily constant) expression giving the dynamic size of the field whereas \a init_bytes is the constant initial size assigned to the field. \param[in] name name of the field to define \param[in] type return type of the accessor function \param[in] size size of the field, either a single value \a bytes for fixed size parsers or two separate arguments \a bytes and \a init_bytes for dynamically sized parsers
Definition at line 474 of file ParseHelpers.hh.
Define normal parser field.
The family of SENF_PARSER_FIELD() macros is used to define standard fields of a composite parser. Every field is accessed by an accessor method named after the name parameter. The field will be parsed using the type parser which must be a valid packet parser. If the current parser is defined as a fixed size parser, all sub parsers must also be fixed size, otherwise dynamically sized parser (e.g. collection parsers) are Ok.
Defining a field will always define several members:
()
const
The accessor member will return the parsed value when called. For normal fields, return_type equals type, the type of the sub parser. This allows to change the value via the returned sub-parser. If the field is marked read-only (SENF_PARSER_FIELD_RO()), the return type will be type::value_type
.
typedef
type name_t
This typedef symbol is an alias for the fields type.
size_type
const
name_offset
Defined only for fixed size parsers, this gives the fixed starting offset of the field from the beginning of the parser.
size_type
name_offset() const
[in] | name | field name |
[in] | type | parser type |
Definition at line 418 of file ParseHelpers.hh.
Define parser field (read-only)
Define read-only parser field. Read-only fields may only be defined for type's which are value parsers: The parser type must have a value_type
typedef member and a value()
member, which returns the current value of the field.
Defining such a field really defines two accessors: A read/write private field and a read-only public accessor. The name of the private read/write field is given by adding a trailing '_' to name. The read-only public accessor is called name.
Definition at line 433 of file ParseHelpers.hh.
#define SENF_PARSER_FINALIZE | ( | name | ) |
Generate parser control members.
SENF_PARSER_FINALIZE() will generate the necessary parser control members (default constructor, parser size, parser initialization). SENF_PARSER_FINALIZE() needs not be the last macro command within the parser though it will often be the last command since SENF_PARSER_FINALIZE() does not account for fields defined later.
SENF_PARSER_FINALIZE() uses the information from SENF_PARSER_INHERIT() to construct the parsers base class (which must be a valid parser class).
defaultInit()
is defined to initialize all fields defined before the call to SENF_PARSER_FINALIZE(). Fields defined later will not be initialized. If SENF_PARSER_INIT() is not used, init()
is defined to call defaultInit()
.
The parsers size (either fixed_bytes
for fixed size parsers or bytes()
and init_bytes
for dynamically sized parsers) is set to the current offset. By manipulating the current offset before calling SENF_PARSER_FINALIZE(), the parser size can therefore be arbitrarily manipulated. E.g., using SENF_PARSER_GOTO_OFFSET() allows to set the size to an arbitrary value.
[in] | name | name of the parser class currently being defined |
Definition at line 378 of file ParseHelpers.hh.
#define SENF_PARSER_FIXED_OFFSET | ( | name | ) |
Get fixed field offset, if possible.
This macro will return the fixed offset to the field name, a compile-time constant expression. This is identical to SENF_PARSER_OFFSET() when defining a fixed size parser.
Even in dynamically sized parsers this macro will work, if the field name is preceded by fixed size fields only. This macro does not validate this condition, it will return an arbitrary incorrect value otherwise.
[in] | name | field or label name |
Definition at line 639 of file ParseHelpers.hh.
#define SENF_PARSER_GOTO | ( | name | ) |
Change current offset.
This command will change the current offset to the field or label name. Fields defined after this command will start at that position and will therefore overlay any fields defined earlier for these byte positions.
SENF_PARSER_GOTO() does not take into account the current bit position within bit fields. When passed the name of a field within a bit field group, this command will always jump to the beginning of the complete group (not the field within the bit field), even if the group covers multiple bytes before the bit field name.
[in] | name | field or label to jump to |
Definition at line 577 of file ParseHelpers.hh.
#define SENF_PARSER_GOTO_OFFSET | ( | offset | ) |
Change current offset to explicit value.
SENF_PARSER_GOTO_OFFSET() allows to change the current offset manually to an arbitrary value. The offset parameter depends on the type of field currently being defined.
[in] | offset | Depending on the parser type, either single bytes value or two arguments bytes and init_size. |
Definition at line 595 of file ParseHelpers.hh.
#define SENF_PARSER_INHERIT | ( | base | ) |
Define parser inheritance.
If the a parser does not directly inherit senf::PacketParserBase, SENF_PARSER_INHERIT() must be called to define the parser's base-class. This call will additionally move the current offset to the end of the inherited parser so additional fields can be added.
If you want to define collection fields which reference auxiliary fields in the base parser, <em>you must define the base parser as a variable parser not a fixed parser</em>. \param[in] base name of base class
Definition at line 354 of file ParseHelpers.hh.
#define SENF_PARSER_INIT | ( | ) |
Define parser initialization routine.
This macro allows to replace the default initialization code. The default init()
implementation will call defaultInit()
which in turn will call init()
of every field defined before SENF_PARSER_FINALIZE().
SENF_PARSER_INIT() allows to replace init()
with custom code:
Defining the initialization code manually skips the automatic call of defaultInit(), which may be performed manually. Should the initialization code be more complex, it should be placed into a non-inline private member which is called from SENF_PARSER_INIT()
Definition at line 331 of file ParseHelpers.hh.
#define SENF_PARSER_LABEL | ( | name | ) |
Define offset label.
This command defines name as a label for the current offset. The member name_offset
is defined (either as a constant for fixed size parsers or as a member function for dynamically sized parsers) to return the position at the point of label definition.
SENF_PARSER_GOTO() can later be used to jump to a position which has previously been labeled with SENF_PARSER_LABEL()
[in] | name | label name |
Definition at line 610 of file ParseHelpers.hh.
#define SENF_PARSER_LIST | ( | name, | |
size, | |||
elt_type | |||
) |
Define ListParser field.
This macro is a special helper to define a senf::ListParser type field, a list of elements of type elt_type (a parser) which size is determined by size.
Here \c EltParser can be an arbitrary parser and need not have a fixed size. \warning Realize, that the \a size field is controlled by the list parser. This field should therefore be declared either read-only or private and must be changed only via the list parser. 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 packetSize()</td><td>Use the size of the packet to get the list size. The list will occupy all space up to the end of the packet.</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
\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:
\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. \par "Implementation note:" 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 \see How to use \ref packet_usage_fields_collection \n senf::ListParser the list parser API for list field access senf::ListParser_Container the list parser container API for list field access
Definition at line 306 of file ListParser.hh.
#define SENF_PARSER_OFFSET | ( | name | ) |
Get field offset.
This macro will return the offset of the given field or label. This macro may only be used while defining the parser, normally while defining inline functions.
This macro will return the correct value when defining fixed or dynamically sized parsers.
[in] | name | field or label name |
Definition at line 623 of file ParseHelpers.hh.
Define bit-field (private)
Define a bit field which is marked as private
and may only be accessed from the parser class itself.
Definition at line 525 of file ParseHelpers.hh.
Define parser field (private)
Define a parser field which is marked as private
and may only be accessed from the parser class itself.
Definition at line 443 of file ParseHelpers.hh.
#define SENF_PARSER_PRIVATE_LIST | ( | name, | |
size, | |||
elt_type | |||
) |
Define private ListParser field.
Definition at line 316 of file ListParser.hh.
#define SENF_PARSER_PRIVATE_VARIANT | ( | name, | |
chooser, | |||
types | |||
) |
Define private VariantParser field.
Definition at line 245 of file VariantParser.hh.
#define SENF_PARSER_PRIVATE_VECTOR | ( | name, | |
size, | |||
elt_type | |||
) |
Define private VectorParser field.
Definition at line 299 of file VectorParser.hh.
#define SENF_PARSER_SKIP | ( | skip | ) |
Skip bytes.
Moves the offset by the given distance (which may be negative). skip depends on the type of parser being defined and is either bytes or bytes, init_bytes.
init_bytes
value. bytes is allowed to be any integral expression, and need not be constant. The second argument init_bytes on the other hand needs to be a constant integral expression.[in] | bytes | number of bytes to skip |
[in] | init_bytes | only for dynamically sized parsers, value to adjust the init_bytes value with. |
Definition at line 551 of file ParseHelpers.hh.
#define SENF_PARSER_SKIP_BITS | ( | bits | ) |
Skip bits within bitfield group.
This command will skip the given number of bits within a bitfield group. This command does only affect bitfield commands. Therefore, a SENF_PARSER_SKIP_BITS command which is not followed by a bitfield command will be ignored.
Definition at line 561 of file ParseHelpers.hh.
#define SENF_PARSER_VARIANT | ( | name, | |
chooser, | |||
types | |||
) |
Define VariantParser field.
This macro is a special helper to define a senf::VariantParser type field.
The variant \c content chooses one of the sub parsers depending on the \c type field. If \c type is 0, senf::VoidPacketParser is selected, if it is 1, senf::UInt8Parser and so on. \warning Realize, that the \a chooser field is controlled by the variant parser. This field should therefore be declared either read-only or private and must be changed only via the variant parser. The \a types parameter specifies the types of sub-objects supported by this variant parser. This parameter is a (Boost.Preprocessor style) sequence <pre>(\a type) (\a type) ...</pre> of parser types with additional optional information: <table class="senf fixedcolumn"> <tr><td>\a type</td><td>Do not provide accessor and use the 0-based type index as key.</td></tr> <tr><td>\c id(\a name, \a type)</td><td>Automatically create an accessor \a name, a test function <tt>has_</tt>\a name and a function to switch to this type <tt>init_</tt>\a name for this type. Identical to \c ids(\a name, <tt>has_</tt>\a name, <tt>init_</tt>\a name, \a type)</td></tr> <tr><td>\c novalue(\a name, \a type)</td><td>This is like \c id but only provides an initializer called \a name and no accessor. Identical to \c ids(\c na, \c na, \a name, \a type)</td></tr> <tr><td>\c ids(\a accessorId, \a testId, \a initId, \a type)</td><td>This is again like \c id but the names of the accessor, test function and init function are given explicitly. Setting any of the id's to \c na will disable that function.</td></tr> <tr><td>\c key(\a value, \a type)</td><td>Use \a value to identity this type. The type is selected, when the \a chooser is equal to \a value</td></tr> <tr><td>\c id(\a name, \c key(\a value, \a type))<br/>\c novalue(\a name, \c key(\a value, \a type))</td><td>The options may be nested in this way.</td></tr> </table> Whenever an id is specified for any type, the variant itself will automatically be made private so the only access to the variant from the outside is via the accessors. The functions defined by specifying an id are: <table class="senf fixedcolumn"> <tr><td><em>name</em><tt>_t</tt></td><td>The type for this specific variant value if not \c novalue.</td></tr> <tr><td><em>name</em><tt>_t</tt> <em>name</em>()</td><td>Return the variant value at this id if not \c novalue.</td></tr> <tr><td><tt>void</tt> <tt>init_</tt><em>name</em>()</td><td>Set the variant to have a value of this type. If the field is \c novalue, the \c init_ prefix is omitted.</td></tr> <tr><td><tt>bool</tt> <tt>has_</tt><em>name</em>()</td><td>Return \c true, if the variant currently holds this kind of value, \c false otherwise. Only if not \c novalue.</td></tr> </table> If \c key specs are given, they designate the value to expect in the \a chooser field to select a specific variant type. If the \a chooser value does not match any key, the variant will be initialized to the \e first type. 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 chooser)</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
other_type
is the chooser ::value_type
whereas the value_type
typedef is the arbitrary return type of the transform.
The tags are applied to the chooser parameter:
\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 \see senf::VariantParser for the VariantParser API\n \ref SENF_PARSER_PRIVATE_VARIANT()
Definition at line 236 of file VariantParser.hh.
#define SENF_PARSER_VECTOR | ( | name, | |
size, | |||
elt_type | |||
) |
Define VectorParser field.
This macro is a special helper to define a senf::VectorParser type field, a vector of elements of type elt_type (a parser) which size is given by the size field.
\warning Realize, that the \a size field is controlled by the vector parser. This field should therefore be declared either read-only or private and must be changed only via the vector parser. 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 packetSize()</td><td>Use the size of the packet to get the vector size. The vector will occupy all space up to the end of the packet.</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
other_type
is the size ::value_type
where as the value_type
typedef is the arbitrary return type of the transform.
The tags are applied to the size parameter:
\param[in] name field name \param[in] size name of field giving the vector size \param[in] elt_type vector element type \see How to use \ref packet_usage_fields_collection \n senf::VectorParser the vector parser API for vector field access senf::VectorParser_Container the vector parser container API for vector field access
Definition at line 289 of file VectorParser.hh.