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