switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Packets / ParseHelpers.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief ParseHelpers public header */
30
31 #ifndef HH_SENF_Packets_ParseHelpers_
32 #define HH_SENF_Packets_ParseHelpers_ 1
33
34 #ifndef HH_SENF_Packets_Packets_
35 #error "Don't include 'ParseHelpers.hh' directly, include 'Packets.hh'"
36 #endif
37
38 // Custom includes
39
40 //#include "ParseHelpers.mpp"
41 #include "ParseHelpers.ih"
42 //-/////////////////////////////////////////////////////////////////////////////////////////////////
43
44 /** \defgroup packetparsermacros Helper macros for defining new packet parsers
45
46     To simplify the definition of simple packet parsers, several macros are provided. Before
47     using these macros you should familiarize yourself with the packet parser interface as
48     described in senf::PacketParserBase.
49
50     These macros simplify providing the above defined interface. A typical packet declaration
51     using these macros has the following form (This is a concrete example from the definition of
52     the ethernet packet in <tt>DefaultBundle/EthernetPacket.hh</tt>)
53
54     \code
55     struct EthVLanPacketParser : public PacketParserBase
56     {
57     #   include SENF_FIXED_PARSER()
58
59         SENF_PARSER_BITFIELD( priority,  3, unsigned );
60         SENF_PARSER_BITFIELD( cfi,       1, bool     );
61         SENF_PARSER_BITFIELD( vlanId,   12, unsigned );
62
63         SENF_PARSER_FIELD( type, UInt16Parser );
64
65         SENF_PARSER_FINALIZE(EthVLanPacketParser);
66     };
67     \endcode
68
69     The macros take care of the following:
70     \li They define the accessor functions returning parsers of the given type.
71     \li They automatically calculate the offset of the fields from the preceding fields.
72     \li The macros provide a definition for \c init()
73     \li The macros define the \c bytes(), \c fixed_bytes and \c init_bytes members as needed.
74
75     You may define either a fixed or a dynamically sized parser. Fixed size parsers are defined by
76     starting the packet with <tt>\#include SENF_FIXED_PARSER()</tt>, dynamically sized parsers start
77     with <tt>\#include SENF_PARSER()</tt>. The different members are implemented such that:
78
79     \li The needed parser constructor is defined
80     \li \c init() calls \c defaultInit(). \c defaultInit() is defined to call \c init() on each
81         of the fields.
82     \li \c bytes() (on dynamically sized parser) respectively \c fixed_bytes (on fixed size
83         parsers) is defined to return the sum of the sizes of all fields.
84     \li On dynamically sized parsers, \c init_bytes is defined to return the sum of the
85         \c init_byte's of all fields
86
87     \section parserlanguage The Parser Macro micro-language
88
89     The macros provided to help implement composite parsers implement a very small declarative
90     language. This way of to think of the macros simplifies understanding, how the macros work.
91
92     Central to this language is the concept of <em>current offset</em>. The current offset is the
93     place (in bytes) from the beginning of the parser at which the next field will be added. Adding
94     fields to the parser will advance this offset by the size of the field added. Additional
95     commands allow to arbitrarily manipulate the current offset manually.
96
97     For fixed size parsers, the current offset is a single constant integral value, the number of
98     bytes from the parsers start. For dynamically sized parsers, the current offset really consists
99     of two values: One is the number of bytes from the parsers start, which however needs not be a
100     constant expression, the other value is the \c init_bytes value at this point, which is an
101     integral constant.
102
103     To demonstrate this functionality, here a more complex example (taken from \c MPEGDVBBundle and
104     then simplified by removing some fields)
105     \code
106     struct Parse_DSMCCSection : public PacketParserBase
107     {
108     #   include SENF_FIXED_PARSER()
109
110         SENF_PARSER_FIELD    ( table_id            , UInt8Parser   );
111
112         SENF_PARSER_BITFIELD ( ssi                 ,  1 , bool     );
113         SENF_PARSER_BITFIELD ( private_indicator   ,  1 , bool     );
114         SENF_PARSER_SKIP_BITS( 2 );
115         SENF_PARSER_BITFIELD ( sec_length          , 12 , unsigned );
116
117         SENF_PARSER_FIELD    ( table_id_extension  , UInt16Parser  );
118
119         SENF_PARSER_FINALIZE( Parse_DSMCCSection );
120     };
121
122     struct Parse_DatagramSection : public Parse_DSMCCSection
123     {
124     #   include SENF_FIXED_PARSER()
125
126         SENF_PARSER_INHERIT( Parse_DSMCCSection );
127
128         SENF_PARSER_FIELD    ( mac_addr_4          , UInt8Parser   );
129         SENF_PARSER_FIELD    ( mac_addr_3          , UInt8Parser   );
130
131         SENF_PARSER_FINALIZE( Parse_DatagramSection );
132
133         // Parse table_id_extension as two bytes
134         SENF_PARSER_GOTO( table_id_extension );
135         SENF_PARSER_FIELD    ( mac_addr_6          , UInt8Parser   );
136         SENF_PARSER_FIELD    ( mac_addr_5          , UInt8Parser   );
137     };
138     \endcode
139
140     This code defines two parsers, the second of which is based on the first. Both are fixed size
141     parsers. The definition of \c Parse_DSMCCSection is straight forward (more on bit fields
142     below).
143
144     The derived parser is a little bit more complex. It starts out the same defining itself as a
145     fixed size parser. Then the base class is imported. Among other things, this call sets the
146     current offset to the first byte after the base parser (the base parser need not be implemented
147     using the packet parser macros, it just needs to be a valid parser). The additional fields \c
148     mac_addr_4 and \c mac_addr_3 are defined. Then we finalize the parser declaration.
149
150     <em>After</em> \ref SENF_PARSER_FINALIZE we add two more fields but not at the end of the
151     parser. \ref SENF_PARSER_GOTO jumps back to a previously defined label or field. Since the base
152     parser \c Parse_DSMCCSection is defined using the packet parser macros, we can even jump to
153     labels or fields defined in the base parser. Here, we jump to the beginning of the \c
154     table_id_extension field. \c mac_addr_6 and \c mac_addr_5 are therefore defined starting at that
155     offset and therefore overlay the \c table_id_extension field.
156
157     \section parsermacroinit Parser initialization
158
159     \par ""
160         \ref SENF_FIXED_PARSER(), \ref SENF_PARSER(), \ref SENF_PARSER_INHERIT(), \ref
161         SENF_PARSER_INIT(), \ref SENF_PARSER_FINALIZE()
162
163     Every parser using the parser macros starts either with <tt>\#include SENF_PARSER()</tt> or with
164     <tt>\#include SENF_FIXED_PARSER()</tt>. This command sets the current offset to zero and defines
165     the type of parser to define.
166
167     A following optional \ref SENF_PARSER_INHERIT(\e base_class) is necessary if the parser does not
168     derive from senf::PacketParserBase. This call sets the base class and advances the current
169     offset to the end of the base parser.
170
171     \ref SENF_PARSER_INIT() is used to define the parser initialization code (the \c init()
172     member).
173
174     \ref SENF_PARSER_FINALIZE(\e class_name) is called to define the parsers constructor, the \c
175     init() member and to set the parsers size (\c fixed_bytes for fixed size parsers or \c bytes()
176     and \c init_bytes for dynamically sized parsers). It is valid to define further fields \e after
177     \ref SENF_PARSER_FINALIZE() has been called, however
178     \li Fields defined after \ref SENF_PARSER_FINALIZE() will \e not be initialized by \c
179         defaultInit() (and therefore not by the default provided \c init() member). This can be very
180         helpful when defining overlaying fields to avoid initializing some bytes multiple times.
181     \li The size of the parser is given by the current offset at the time of the \ref
182         SENF_PARSER_FINALIZE() call.
183
184     \section parsermacrofields Defining fields
185
186     \par ""
187         \ref SENF_PARSER_FIELD(), \ref SENF_PARSER_FIELD_RO(), \ref SENF_PARSER_PRIVATE_FIELD(),
188         \ref SENF_PARSER_CUSTOM_FIELD()
189
190     There are quite a few commands available to define fields. All these macros do the same thing:
191     they define a field accessor plus some auxiliary symbols. The accessor will use the parser type
192     passed to the macro to parse the field. The current offset is adjusted according to the size of
193     that parser. Normally, the parser will return an instance of the given parser type.
194
195     There are some properties the field defining macros might have. These properties are parts
196     of the macro name:
197
198     \par \c RO: Read only fields
199         Macros with \c RO in their name define read only fields. This is only possible, if the
200         field's parser is a value parser (that is, it must have a \c value_type typedef member and
201         must provide the \c value() accessor member function). In this case, the value returned from
202         the \e name() accessor member is not the parser but the parsers value and therefore it does
203         not allow assignment to the field.
204
205     \par \c PRIVATE: Fields private to the parser class
206         A private field will not be accessible from the outside (it is made \c private to the parser
207         class). This is very handy when providing other accessor members to access a field in a
208         manner more suitable for the specific field, when combining several fields into a single
209         return value etc.
210
211     The field defining macros come in groups which members only differ in their properties:
212
213     <dl><dt><em>Standard fields:</em><dt><dd>\ref SENF_PARSER_FIELD(), \ref SENF_PARSER_FIELD_RO(),
214         \ref SENF_PARSER_PRIVATE_FIELD() define standard fields.</dd>
215
216     <dt><em>Arbitrary custom field:</em><dt><dd>\ref SENF_PARSER_CUSTOM_FIELD()</dd></dl>
217
218     See the documentation of each of these macros for a detailed description of the macro arguments
219     and usage. Bit-fields are handled in the following section.
220
221     There also some supplementary macros for defining fields of more complex composite types
222     (e.g. vectors). See the list of 'Defines' further down this page.
223
224     \subsection parsermacrosbitfields Bit-fields
225
226     \par ""
227         \ref SENF_PARSER_BITFIELD(), \ref SENF_PARSER_BITFIELD_RO(), \ref
228         SENF_PARSER_PRIVATE_BITFIELD()\n
229
230     Bit-fields play a special role. They are quite frequent in packet definitions but don't fit into
231     the byte offset based parsing infrastructure defined so far. Since defining the correctly
232     parameterized senf::IntFieldParser, senf::UIntFieldParser and senf::FlagParser typedefs is quite
233     tedious, these helper macros are provided.
234
235     It is important to recognize, that the current offset does \e not include the current bit
236     position. The current offset after defining a bit-field will be the first complete byte after
237     that bit-field. Only the bit-field macros additionally take care of the current bit position
238     which is reset automatically by any intervening non-bitfield command.
239
240     So bit-field commands will come in groups. Any group of consecutive bitfield commands defines a
241     set of consecutive bits. The group as a whole will always be considered to cover a fixed number
242     of complete bytes. If the group does not cover those bytes completely (there are some bit's left
243     at the end), those bit's will be skipped.
244
245     Since consecutive bit-field commands are aggregated into a single bit-field group, the offset of
246     all these bit-fields will be the offset of the \e beginning of the group irrespective of the
247     number of bits parsed so far. Changing the offset to some bitfield using \ref SENF_PARSER_GOTO()
248     will therefore always go to the position at the beginning of this bitfield group. And since the
249     current offset does not include the bit position, the bit position will be 0, the first bit. You
250     may however break a bit-field group into two groups (at a byte boundary) by placing a \ref
251     SENF_PARSER_LABEL() command between the two groups.
252
253     The additional command \ref SENF_PARSER_SKIP_BITS() can be used to skip bit's between two
254     bit-fields.
255
256     \section parsermacrooffset Manipulating the current offset
257
258     \par ""
259         \ref SENF_PARSER_SKIP(), \ref SENF_PARSER_SKIP_BITS(), \ref SENF_PARSER_GOTO(), \ref
260         SENF_PARSER_GOTO_OFFSET(), \ref SENF_PARSER_LABEL()
261
262     To define more complex parsers, there are some macro commands which change the current offset.
263
264     \ref SENF_PARSER_SKIP(\e bytes) will skip the given number of bytes. \ref
265     SENF_PARSER_SKIP_BITS(\e bits) will work within bitfield definition to skip that number of bits.
266
267     \ref SENF_PARSER_GOTO(\e label_or_field) will change the offset to the given field or label. The
268     following fields will therefore start at that offset and overlay any fields already defined.
269
270     \ref SENF_PARSER_GOTO_OFFSET(\e offset) will jump to the given byte offset from the start of the
271     parser.
272
273     \ref SENF_PARSER_LABEL(\e name) will define \e name as a label for the current offset which can
274     then later be referenced using \ref SENF_PARSER_GOTO(). This also defines
275     <em>name</em><tt>_offset</tt> as a constant or member (for fixed respectively dynamically sized
276     parsers).
277
278     It is very important to recognize, that the size of the parser is defined by the current offset
279     <em>at the time \ref SENF_PARSER_FINALIZE() is called</em>. This allows to arbitrarily
280     manipulate the size of the parser by changing the current offset accordingly. For dynamically
281     sized parsers, the offset can even be any expression involving member function calls. See the
282     documentation of the respective macros for more details.
283
284     \ingroup packetparser
285  */
286 ///\addtogroup packetparsermacros
287 //\{
288
289 ///\name Control information
290 //\{
291
292 /** \brief Define fixed size parser
293
294     This macro must be called using \c \#include at the beginning of every fixed size parser using
295     the packet parser helper macros:
296
297     \code
298     struct SomeParser : public senf::PacketParserBase
299     {
300     #   include SENF_FIXED_PARSER()
301     \endcode
302
303     The parser must directly or indirectly inherit from senf::PacketParserBase
304
305     \hideinitializer
306  */
307 #define SENF_FIXED_PARSER()      SENF_ABSOLUTE_INCLUDE_PATH(Packets/parse_fixed_setup.hh)
308
309 /** \brief Define dynamically sized parser
310
311     This macro must be called using \c \#include at the beginning of every dynamically sized parser
312     using the packet parser helper macros:
313
314     \code
315     struct SomeParser : public senf::PacketParserBase
316     {
317     #   include SENF_PARSER()
318     \endcode
319
320     The parser must directly or indirectly inherit from senf::PacketParserBase
321
322     \hideinitializer
323  */
324 #define SENF_PARSER()            SENF_ABSOLUTE_INCLUDE_PATH(Packets/parse_setup.hh)
325
326 /** \brief Define parser initialization routine
327
328     This macro allows to replace the default initialization code. The default \c init()
329     implementation will call \c defaultInit() which in turn will call \c init() of every field
330     defined before \ref SENF_PARSER_FINALIZE().
331
332     \ref SENF_PARSER_INIT() allows to replace \c init() with custom code:
333     \code
334     SENF_PARSER_INIT() {
335         defaultInit();
336         foo() = 2;
337     }
338     \endcode
339     Defining the initialization code manually skips the automatic call of defaultInit(), which may
340     be performed manually. Should the initialization code be more complex, it should be placed into
341     a non-inline private member which is called from \ref SENF_PARSER_INIT()
342
343     \hideinitializer
344  */
345 #define SENF_PARSER_INIT()       void init(int) const
346
347 #ifdef DOXYGEN
348
349 /** \brief Define parser inheritance
350
351     If the a parser does not directly inherit senf::PacketParserBase, \ref SENF_PARSER_INHERIT()
352     must be called to define the parser's base-class. This call will additionally move the current
353     offset to the end of the inherited parser so additional fields can be added.
354     \code
355     struct MyParser : public BaseParser
356     {
357     #   include SENF_FIXED_PARSER() // or SENF_PARSER()
358
359         SENF_PARSER_INHERIT(BaseParser)
360     \endcode
361
362     If you want to define collection fields which reference auxiliary fields in the base parser,
363     <em>you must define the base parser as a variable parser not a fixed parser</em>.
364
365     \param[in] base name of base class
366     \hideinitializer
367  */
368 #define SENF_PARSER_INHERIT(base)
369
370 /** \brief Generate parser control members
371
372     \ref SENF_PARSER_FINALIZE() will generate the necessary parser control members (default
373     constructor, parser size, parser initialization). \ref SENF_PARSER_FINALIZE() needs not be the
374     last macro command within the parser though it will often be the last command since \ref
375     SENF_PARSER_FINALIZE() does not account for fields defined later.
376
377     \ref SENF_PARSER_FINALIZE() uses the information from \ref SENF_PARSER_INHERIT() to construct
378     the parsers base class (which must be a valid parser class).
379
380     \c defaultInit() is defined to initialize all fields <em>defined before the call to \ref
381     SENF_PARSER_FINALIZE()</em>. Fields defined later will \e not be initialized. If \ref
382     SENF_PARSER_INIT() is not used, \c init() is defined to call \c defaultInit().
383
384     The parsers size (either \c fixed_bytes for fixed size parsers or \c bytes() and \c init_bytes
385     for dynamically sized parsers) is set to the current offset. By manipulating the current offset
386     before calling \ref SENF_PARSER_FINALIZE(), the parser size can therefore be arbitrarily
387     manipulated. E.g., using \ref SENF_PARSER_GOTO_OFFSET() allows to set the size to an arbitrary
388     value.
389
390     \param[in] name name of the parser class currently being defined
391  */
392 #define SENF_PARSER_FINALIZE(name)
393
394 //\}
395
396 ///\name Parser fields
397 //\{
398
399 /** \brief Define normal parser field
400
401     The family of \ref SENF_PARSER_FIELD() macros is used to define standard fields of a composite
402     parser. Every field is accessed by an accessor method named after the \a name parameter. The
403     field will be parsed using the \a type parser which must be a valid packet parser. If the
404     current parser is defined as a fixed size parser, all sub parsers must also be fixed size,
405     otherwise dynamically sized parser (e.g. collection parsers) are Ok.
406
407     Defining a field will always define several members:
408
409     <dl><dt><em>return_type</em> <em>name</em><tt>()</tt> <tt>const</tt></dt><dd>The accessor member
410         will return the parsed value when called. For normal fields, <em>return_type</em> equals
411         <em>type</em>, the type of the sub parser. This allows to change the value via the returned
412         sub-parser. If the field is marked read-only (\ref SENF_PARSER_FIELD_RO()), the return type
413         will be <em>type</em>::<tt>value_type</tt>.</dd>
414
415     <dt><tt>typedef</tt> <em>type</em> <em>name</em><tt>_t</tt></dt><dd>This typedef symbol is an
416         alias for the fields type.</dd>
417
418     <dt><tt>size_type</tt> <tt>const</tt> <em>name</em><tt>_offset</tt></dt><dd>Defined only for
419         fixed size parsers, this gives the fixed starting offset of the field from the beginning of
420         the parser.</dd>
421
422     <dt><tt>size_type</tt> <em>name</em><tt>_offset() const</tt></dt><dd>Defined only for
423         dynamically sized parsers, this member function will return the dynamic offset of the field
424         from the beginning of the parser.</dd></dl>
425
426     \param[in] name field name
427     \param[in] type parser type
428
429     \see \ref SENF_PARSER_FIELD_RO(), \ref SENF_PARSER_PRIVATE_FIELD()
430     \hideinitializer
431  */
432 #define SENF_PARSER_FIELD(name, type)
433
434 /** \brief Define parser field (read-only)
435
436     Define read-only parser field. Read-only fields may only be defined for \a type's which are
437     value parsers: The parser \a type must have a \c value_type typedef member and a \c value()
438     member, which returns the current value of the field.
439
440     Defining such a field really defines \e two accessors: A read/write \e private field and a
441     read-only \e public accessor. The name of the private read/write field is given by adding a
442     trailing '_' to \a name. The read-only public accessor is called \a name.
443
444     \see SENF_PARSER_FIELD()
445     \hideinitializer
446 */
447 #define SENF_PARSER_FIELD_RO(name, type)
448
449 /** \brief Define parser field (private)
450
451     Define a parser field which is marked as \c private and may only be accessed from the parser
452     class itself.
453
454     \see SENF_PARSER_FIELD()
455     \hideinitializer
456  */
457 #define SENF_PARSER_PRIVATE_FIELD(name, type)
458
459 /** \brief Define custom field accessor
460
461     This macro is used to define a field using a custom access method:
462     \code
463     // The following is the same as SENF_PARSER_FIELD( xyz, senf::UInt16Parser )
464     // in a fixed size parser.
465
466     SENF_PARSER_CUSTOM_FIELD(xyz, senf::UInt16Parser, xyz_t::fixed_bytes) {
467         return parse<xyz_t>( xyz_offset );
468     }
469     \endcode
470
471     The macro defines the same auxiliary symbols defined by \ref SENF_PARSER_FIELD(\a name, \a
472     type), the accessor method however is provided by the user.
473
474     \a size depends on the type of parser being defined:
475
476     \li If defining a fixed parser, \a size is a single value \a bytes which must be a constant
477         integral expression giving the fixed size of the field.
478     \li If defining a dynamically sized parser, \a size is given by two parameters \a bytes and \a
479         init_bytes. \a bytes is an arbitrary (not necessarily constant) expression giving the
480         dynamic size of the field whereas \a init_bytes is the constant initial size assigned to the
481         field.
482
483     \param[in] name name of the field to define
484     \param[in] type return type of the accessor function
485     \param[in] size size of the field, either a single value \a bytes for fixed size parsers or two
486         separate arguments \a bytes and \a init_bytes for dynamically sized parsers
487  */
488 #define SENF_PARSER_CUSTOM_FIELD(name, type, size)
489
490 //\}
491
492 ///\name Bit fields
493 //\{
494
495 /** \brief Define bit-field
496
497     Bit fields are supported by a special family of parser macros. These macros simplify defining
498     fields using the senf::IntFieldParser, senf::UIntFieldParser and senf::FlagParser parsers by
499     keeping track of the current bit position and automatically creating the correct template
500     parameters.
501
502     The \a type parameter specifies the type of bitfield to define. This value is one of
503     \li \c signed, for signed bit fields (senf::IntFieldParser)
504     \li \c unsigned, for unsigned bit fields (senf::UIntFieldParser) or
505     \li \c bool, for single-bit flags (senf::FlagParser).
506
507     The \a bits parameter specifies the number of bits the field covers. For \c signed or \c
508     unsigned fields, this value may be any numeric value from 1 to 32, for \c bool fields, this
509     value \e must be 1.
510
511     For more information see \ref parsermacrosbitfields
512
513     \param[in] name name of the bit field
514     \param[in] bits number of bits
515     \param[in] type bit field type, one of \c signed, \c unsigned or \c bool
516
517     \see \ref SENF_PARSER_BITFIELD_RO(), \ref SENF_PARSER_PRIVATE_BITFIELD()
518     \hideinitializer
519  */
520 #define SENF_PARSER_BITFIELD(name, bits, type)
521
522 /** \brief Define bit-field (read-only)
523
524     Define read-only bit field. This is for bit-fields what \ref SENF_PARSER_FIELD_RO is for ordinary fields.
525
526     \see \ref SENF_PARSER_BITFIELD() \n \ref SENF_PARSER_FIELD_RO()
527     \hideinitializer
528  */
529 #define SENF_PARSER_BITFIELD_RO(name, bits, type)
530
531 /** \brief Define bit-field (private)
532
533     Define a bit field which is marked as \c private and may only be accessed from the parser class
534     itself.
535
536     \see \ref SENF_PARSER_BITFIELD()
537     \hideinitializer
538  */
539 #define SENF_PARSER_PRIVATE_BITFIELD(name, bits, type)
540
541 //\}
542
543 ///\name Current offset
544 //\{
545
546 /** \brief Skip bytes
547
548     Moves the offset by the given distance (which may be negative). \a skip depends on the type of
549     parser being defined and is either \a bytes or \a bytes, \a init_bytes.
550
551     \li If defining a fixed parser, \a bytes must be a constant integral expression which will be
552         added to the current offset
553     \li If defining a dynamically sized parser, the macro really takes two arguments, \a bytes and
554         \a init_bytes. \a bytes will adjust the current field offset whereas \a init_bytes will
555         adjust the parsers \c init_bytes value. \a bytes is allowed to be any integral expression,
556         and need \e not be constant. The second argument \a init_bytes on the other hand needs to be
557         a constant integral expression.
558
559     \param[in] bytes number of bytes to skip
560     \param[in] init_bytes only for dynamically sized parsers, value to adjust the \c init_bytes value
561         with.
562
563     \hideinitializer
564  */
565 #define SENF_PARSER_SKIP(skip)
566
567 /** \brief Skip bits within bitfield group
568
569     This command will skip the given number of bits within a bitfield group. This command does \e
570     only affect bitfield commands. Therefore, a SENF_PARSER_SKIP_BITS command which is not followed
571     by a bitfield command will be ignored.
572
573     \hideinitializer
574  */
575 #define SENF_PARSER_SKIP_BITS(bits)
576
577 /** \brief Change current offset
578
579     This command will change the current offset to the field or label \a name. Fields defined after
580     this command will start at that position and will therefore overlay any fields defined earlier
581     for these byte positions.
582
583     \ref SENF_PARSER_GOTO() does \e not take into account the current bit position within bit
584     fields. When passed the name of a field within a bit field group, this command will always jump
585     to the beginning of the \e complete group (\e not the field within the bit field), even if the
586     group covers multiple bytes before the bit field \a name.
587
588     \param[in] name field or label to jump to
589     \hideinitializer
590  */
591 #define SENF_PARSER_GOTO(name)
592
593 /** \brief Change current offset to explicit value
594
595     \ref SENF_PARSER_GOTO_OFFSET() allows to change the current offset manually to an arbitrary
596     value. The \a offset parameter depends on the type of field currently being defined.
597
598     \li If defining a <em>fixed size parser</em>, the \a offset argument is a single \a bytes value
599         which is an integral constant expression to which the offset will be set.
600     \li If defining a <em>dynamically sized parser</em>, the \a offset argument is given by two
601         parameters \a bytes and \a init_bytes. \a bytes can be any integral expression (not
602         necessarily constant) giving the new byte position. \a init_bytes must be a constant
603         integral expression and will set the current initial size of the packet to this value.
604
605     \param[in] offset Depending on the parser type, either single \a bytes value or two arguments \a
606         bytes and \a init_size.
607     \hideinitializer
608  */
609 #define SENF_PARSER_GOTO_OFFSET(offset)
610
611 /** \brief Define offset label
612
613     This command defines \a name as a label for the current offset. The member
614     <em>name</em><tt>_offset</tt> is defined (either as a constant for fixed size parsers or as a
615     member function for dynamically sized parsers) to return the position at the point of label
616     definition.
617
618     \ref SENF_PARSER_GOTO() can later be used to jump to a position which has previously been
619     labeled with \ref SENF_PARSER_LABEL()
620
621     \param[in] name label name
622     \hideinitializer
623  */
624 #define SENF_PARSER_LABEL(name)
625
626 /** \brief Get field offset
627
628     This macro will return the offset of the given field or label. This macro may only be used
629     while defining the parser, normally while defining inline functions.
630
631     This macro will return the correct value when defining fixed or dynamically sized parsers.
632
633     \param[in] name field or label name
634     \returns offset of the field from parsers start
635     \hideinitializer
636  */
637 #define SENF_PARSER_OFFSET(name)
638
639 /** \brief Get fixed field offset, if possible
640
641     This macro will return the fixed offset to the field \a name, a compile-time constant
642     expression. This is identical to \ref SENF_PARSER_OFFSET() when defining a fixed size parser.
643
644     Even in dynamically sized parsers this macro will work, if the field \a name is preceded by
645     fixed size fields only. This macro does \e not validate this condition, it will return an
646     arbitrary incorrect value otherwise.
647
648     \pre Field \a name preceded by fixed size fields only
649     \param[in] name field or label name
650     \returns compile-time constant offset of the field from parsers start
651     \hideinitializer
652  */
653 #define SENF_PARSER_FIXED_OFFSET(name)
654
655 /** \brief Get current fixed offset, if possible
656
657     This macro will return the current fixed offset, a compile-time constant expression. This is
658     always possible when defining a fixed size parser.
659
660     Even in dynamically sized parsers this macro will work, if all parser defined \e before the
661     current position are fixed-size parsers. This macro does \e not validate this condition, it will
662     return an arbitrary incorrect value otherwise.
663
664     \pre Current position preceded by fixed-size parsers only
665     \returns compile-time constant offset from parsers start
666     \hideinitializer
667  */
668 #define SENF_PARSER_CURRENT_FIXED_OFFSET()
669
670 //\}
671
672 #else
673
674 #define SENF_PARSER_INHERIT              BOOST_PP_CAT( SENF_PARSER_INHERIT_,              SENF_PARSER_TYPE )
675
676 #define SENF_PARSER_FIELD                BOOST_PP_CAT( SENF_PARSER_FIELD_,                SENF_PARSER_TYPE )
677 #define SENF_PARSER_FIELD_RO             BOOST_PP_CAT( SENF_PARSER_FIELD_RO_,             SENF_PARSER_TYPE )
678 #define SENF_PARSER_BITFIELD             BOOST_PP_CAT( SENF_PARSER_BITFIELD_,             SENF_PARSER_TYPE )
679 #define SENF_PARSER_BITFIELD_RO          BOOST_PP_CAT( SENF_PARSER_BITFIELD_RO_,          SENF_PARSER_TYPE )
680 #define SENF_PARSER_CUSTOM_FIELD         BOOST_PP_CAT( SENF_PARSER_CUSTOM_FIELD_,         SENF_PARSER_TYPE )
681
682 #define SENF_PARSER_PRIVATE_FIELD        BOOST_PP_CAT( SENF_PARSER_P_FIELD_,              SENF_PARSER_TYPE )
683 #define SENF_PARSER_PRIVATE_BITFIELD     BOOST_PP_CAT( SENF_PARSER_P_BITFIELD_,           SENF_PARSER_TYPE )
684
685 #define SENF_PARSER_SKIP                 BOOST_PP_CAT( SENF_PARSER_SKIP_,                 SENF_PARSER_TYPE )
686 #define SENF_PARSER_SKIP_BITS            BOOST_PP_CAT( SENF_PARSER_SKIP_BITS_,            SENF_PARSER_TYPE )
687 #define SENF_PARSER_GOTO                 BOOST_PP_CAT( SENF_PARSER_GOTO_,                 SENF_PARSER_TYPE )
688 #define SENF_PARSER_GOTO_OFFSET          BOOST_PP_CAT( SENF_PARSER_GOTO_OFFSET_,          SENF_PARSER_TYPE )
689 #define SENF_PARSER_LABEL                BOOST_PP_CAT( SENF_PARSER_LABEL_,                SENF_PARSER_TYPE )
690
691 #define SENF_PARSER_OFFSET               BOOST_PP_CAT( SENF_PARSER_OFFSET_,               SENF_PARSER_TYPE )
692 #define SENF_PARSER_FIXED_OFFSET         BOOST_PP_CAT( SENF_PARSER_FIXED_OFFSET_,         SENF_PARSER_TYPE )
693 #define SENF_PARSER_CURRENT_FIXED_OFFSET BOOST_PP_CAT( SENF_PARSER_CURRENT_FIXED_OFFSET_, SENF_PARSER_TYPE )
694
695 #define SENF_PARSER_FINALIZE             BOOST_PP_CAT( SENF_PARSER_FINALIZE_,             SENF_PARSER_TYPE )
696
697 #endif
698
699 //\}
700
701 //-/////////////////////////////////////////////////////////////////////////////////////////////////
702 #endif
703 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_ParseHelpers_i_)
704 #define HH_SENF_Packets_ParseHelpers_i_
705 //#include "ParseHelpers.cci"
706 //#include "ParseHelpers.ct"
707 //#include "ParseHelpers.cti"
708 #endif
709
710 \f
711 // Local Variables:
712 // mode: c++
713 // fill-column: 100
714 // comment-column: 40
715 // c-file-style: "senf"
716 // indent-tabs-mode: nil
717 // ispell-local-dictionary: "american"
718 // compile-command: "scons -u test"
719 // End: