31fa8b5e4a6c494d077d917d228153e060471535
[senf.git] / Packets / ParseHelpers.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
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 EthVLanPacketParser : 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, UInt16Parser );
59
60         SENF_PARSER_FINALIZE(EthVLanPacketParser);
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            , UInt8Parser   );
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  , UInt16Parser  );
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          , UInt8Parser   );
124         SENF_PARSER_FIELD    ( mac_addr_3          , UInt8Parser   );
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          , UInt8Parser   );
131         SENF_PARSER_FIELD    ( mac_addr_5          , UInt8Parser   );
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     There also some supplementary macros for defining fields of more complex composite types
218     (e.g. vectors). See the list of 'Defines' further down this page.
219
220     \subsection parsermacrosbitfields Bit-fields
221
222     \par "" 
223         \ref SENF_PARSER_BITFIELD(), \ref SENF_PARSER_BITFIELD_RO(), \ref
224         SENF_PARSER_PRIVATE_BITFIELD(), \ref SENF_PARSER_PRIVATE_BITFIELD_RO() \n
225
226     Bit-fields play a special role. They are quite frequent in packet definitions but don't fit into
227     the byte offset based parsing infrastructure defined so far. Since defining the correctly
228     parameterized senf::IntFieldParser, senf::UIntFieldParser and senf::FlagParser typedefs is quite
229     tedious, these helper macros are provided.
230
231     It is important to recognize, that the current offset does \e not include the current bit
232     position. The current offset after defining a bit-field will be the first complete byte after
233     that bit-field. Only the bit-field macros additionally take care of the current bit position
234     which is reset automatically by any intervening non-bitfield command.
235
236     So bit-field commands will come in groups. Any group of consecutive bitfield commands defines a
237     set of consecutive bits. The group as a whole will always be considered to cover a fixed number
238     of complete bytes. If the group does not cover those bytes completely (there are some bit's left
239     at the end), those bit's will be skipped.
240
241     Since consecutive bit-field commands are aggregated into a single bit-field group, the offset of
242     all these bit-fields will be the offset of the \e beginning of the group irrespective of the
243     number of bits parsed so far. Changing the offset to some bitfield using \ref SENF_PARSER_GOTO()
244     will therefore always go to the position at the beginning of this bitfield group. And since the
245     current offset does not include the bit position, the bit position will be 0, the first bit. You
246     may however break a bit-field group into two groups (at a byte boundary) by placing a \ref
247     SENF_PARSER_LABEL() command between the two groups.
248
249     The additional command \ref SENF_PARSER_SKIP_BITS() can be used to skip bit's between two
250     bit-fields.
251
252     \section parsermacrooffset Manipulating the current offset
253
254     \par ""
255         \ref SENF_PARSER_SKIP(), \ref SENF_PARSER_SKIP_BITS(), \ref SENF_PARSER_GOTO(), \ref
256         SENF_PARSER_GOTO_OFFSET(), \ref SENF_PARSER_LABEL()
257
258     To define more complex parsers, there are some macro commands which change the current offset. 
259
260     \ref SENF_PARSER_SKIP(\e bytes) will skip the given number of bytes. \ref
261     SENF_PARSER_SKIP_BITS(\e bits) will work within bitfield definition to skip that number of bits.
262
263     \ref SENF_PARSER_GOTO(\e label_or_field) will change the offset to the given field or label. The
264     following fields will therefore start at that offset and overlay any fields already defined.
265
266     \ref SENF_PARSER_GOTO_OFFSET(\e offset) will jump to the given byte offset from the start of the
267     parser.
268
269     \ref SENF_PARSER_LABEL(\e name) will define \e name as a label for the current offset which can
270     then later be referenced using \ref SENF_PARSER_GOTO(). This also defines
271     <em>name</em><tt>_offset</tt> as a constant or member (for fixed respectively dynamically sized
272     parsers).
273     
274     It is very important to recognize, that the size of the parser is defined by the current offset
275     <em>at the time \ref SENF_PARSER_FINALIZE() is called</em>. This allows to arbitrarily
276     manipulate the size of the parser by changing the current offset accordingly. For dynamically
277     sized parsers, the offset can even be any expression involving member function calls. See the
278     documentation of the respective macros for more details.
279
280     \ingroup packetparser
281  */
282 ///\ingroup packetparsermacros
283 ///\{
284
285 ///\name Control information
286 ///@{
287
288 /** \brief Define fixed size parser
289     
290     This macro must be called using \c \#include at the beginning of every fixed size parser using
291     the packet parser helper macros:
292
293     \code
294     struct SomeParser : public senf::PacketParserBase
295     {
296     #   include SENF_FIXED_PARSER()
297     \endcode
298
299     The parser must directly or indirectly inherit from senf::PacketParserBase
300
301     \hideinitializer
302  */
303 #define SENF_FIXED_PARSER()      SENF_ABSOLUTE_INCLUDE_PATH(Packets/parse_fixed_setup.hh)
304
305 /** \brief Define dynamically sized parser
306     
307     This macro must be called using \c \#include at the beginning of every dynamically sized parser
308     using the packet parser helper macros:
309
310     \code
311     struct SomeParser : public senf::PacketParserBase
312     {
313     #   include SENF_PARSER()
314     \endcode
315
316     The parser must directly or indirectly inherit from senf::PacketParserBase
317
318     \hideinitializer
319  */
320 #define SENF_PARSER()            SENF_ABSOLUTE_INCLUDE_PATH(Packets/parse_setup.hh)
321
322 /** \brief Define parser initialization routine
323
324     This macro allows to replace the default initialization code. The default \c init()
325     implementation will call \c defaultInit() which in turn will call \c init() of every field
326     defined before \ref SENF_PARSER_FINALIZE().
327
328     \ref SENF_PARSER_INIT() allows to replace \c init() with custom code:
329     \code
330     SENF_PARSER_INIT() {
331         defaultInit();
332         foo() = 2;
333     }
334     \endcode
335     Defining the initialization code manually skips the automatic call of defaultInit(), which may
336     be performed manually. Should the initialization code be more complex, it should be placed into
337     a non-inline private member which is called from \ref SENF_PARSER_INIT()
338
339     \hideinitializer
340  */
341 #define SENF_PARSER_INIT()       void init(int) const
342
343 #ifdef DOXYGEN
344
345 /** \brief Define parser inheritance
346
347     If the a parser does not directly inherit senf::PacketParserBase, \ref SENF_PARSER_INHERIT()
348     must be called to define the parser's base-class. This call will additionally move the current
349     offset to the end of the inherited parser so additional fields can be added.
350     \code
351     struct MyParser : public BaseParser
352     {
353     #   include SENF_FIXED_PARSER() // or SENF_PARSER()
354
355         SENF_PARSER_INHERIT(BaseParser)
356     \endcode
357
358     \param[in] base name of base class
359     \hideinitializer
360  */
361 #define SENF_PARSER_INHERIT(base)
362
363 /** \brief Generate parser control members
364
365     \ref SENF_PARSER_FINALIZE() will generate the necessary parser control members (default
366     constructor, parser size, parser initialization). \ref SENF_PARSER_FINALIZE() needs not be the
367     last macro command within the parser though it will often be the last command since \ref
368     SENF_PARSER_FINALIZE() does not account for fields defined later.
369     
370     \ref SENF_PARSER_FINALIZE() uses the information from \ref SENF_PARSER_INHERIT() to construct
371     the parsers base class (which must be a valid parser class). 
372
373     \c defaultInit() is defined to initialize all fields <em>defined before the call to \ref
374     SENF_PARSER_FINALIZE()</em>. Fields defined later will \e not be initialized. If \ref
375     SENF_PARSER_INIT() is not used, \c init() is defined to call \c defaultInit().
376
377     The parsers size (either \c fixed_bytes for fixed size parsers or \c bytes() and \c init_bytes
378     for dynamically sized parsers) is set to the current offset. By manipulating the current offset
379     before calling \ref SENF_PARSER_FINALIZE(), the parser size can therefore be arbitrarily
380     manipulated. E.g., using \ref SENF_PARSER_GOTO_OFFSET() allows to set the size to an arbitrary
381     value.
382
383     \param[in] name name of the parser class currently being defined
384  */
385 #define SENF_PARSER_FINALIZE(name)
386
387 ///@}
388
389 ///\name Parser fields
390 ///@{
391
392 /** \brief Define normal parser field
393
394     The family of \ref SENF_PARSER_FIELD() macros is used to define standard fields of a composite
395     parser. Every field is accessed by an accessor method named after the \a name parameter. The
396     field will be parsed using the \a type parser which must be a valid packet parser. If the
397     current parser is defined as a fixed size parser, all sub parsers must also be fixed size,
398     otherwise dynamically sized parser (e.g. collection parsers) are Ok.
399
400     Defining a field will always define several members:
401
402     <dl><dt><em>return_type</em> <em>name</em><tt>()</tt> <tt>const</tt></dt><dd>The accessor member
403         will return the parsed value when called. For normal fields, <em>return_type</em> equals
404         <em>type</em>, the type of the sub parser. This allows to change the value via the returned
405         sub-parser. If the field is marked read-only (\ref SENF_PARSER_FIELD_RO() or \ref
406         SENF_PARSER_PRIVATE_FIELD_RO()), the return type will be
407         <em>type</em>::<tt>value_type</tt>.</dd>
408
409     <dt><tt>typedef</tt> <em>type</em> <em>name</em><tt>_t</tt></dt><dd>This typedef symbol is an
410         alias for the fields type.</dd>
411
412     <dt><tt>size_type</tt> <tt>const</tt> <em>name</em><tt>_offset</tt></dt><dd>Defined only for
413         fixed size parsers, this gives the fixed starting offset of the field from the beginning of
414         the parser.</dd>
415
416     <dt><tt>size_type</tt> <em>name</em><tt>_offset() const</tt></dt><dd>Defined only for
417         dynamically sized parsers, this member function will return the dynamic offset of the field
418         from the beginning of the parser.</dd></dl>
419
420     \param[in] name field name
421     \param[in] type parser type
422
423     \see \ref SENF_PARSER_FIELD_RO(), \ref SENF_PARSER_PRIVATE_FIELD(), \ref
424         SENF_PARSER_PRIVATE_FIELD_RO()
425     \hideinitializer
426  */
427 #define SENF_PARSER_FIELD(name, type) 
428
429 /** \brief Define parser field (read-only)
430     
431     Define read-only parser field. Read-only fields may only be defined for \a type's which are
432     value parsers: The parser \a type must have a \c value_type typedef member and a \c value()
433     member, which returns the current value of the field.
434    
435     \see SENF_PARSER_FIELD() 
436     \hideinitializer
437 */
438 #define SENF_PARSER_FIELD_RO(name, type) 
439
440 /** \brief Define parser field (private)
441
442     Define a parser field which is marked as \c private and may only be accessed from the parser
443     class itself.
444
445     \see SENF_PARSER_FIELD()
446     \hideinitializer
447  */
448 #define SENF_PARSER_PRIVATE_FIELD(name, type) 
449
450 /** \brief Define parser field (private + read-only)
451
452     Define a read-only parser field which is marked as \c private and may only be accessed from the
453     parser class itself. Read-only fields may only be defined for \a type's which are value parsers:
454     The parser \a type must have a \c value_type typedef member and a \c value() member, which
455     returns the current value of the field.
456
457     \see SENF_PARSER_FIELD()
458     \hideinitializer
459  */
460 #define SENF_PARSER_PRIVATE_FIELD_RO(name, type) 
461
462 /** \brief Define custom field accessor
463
464     This macro is used to define a field using a custom access method:
465     \code
466     // The following is the same as SENF_PARSER_FIELD( xyz, senf::UInt16Parser )
467     // in a fixed size parser.
468
469     SENF_PARSER_CUSTOM_FIELD(xyz, senf::UInt16Parser, xyz_t::fixed_bytes) {
470         return parse<xyz_t>( xyz_offset );
471     }
472     \endcode
473     
474     The macro defines the same auxiliary symbols defined by \ref SENF_PARSER_FIELD(\a name, \a
475     type), the accessor method however is provided by the user.
476
477     \a size depends on the type of parser being defined: 
478
479     \li If defining a fixed parser, \a size is a single value \a bytes which must be a constant
480         integral expression giving the fixed size of the field.
481     \li If defining a dynamically sized parser, \a size is given by two parameters \a bytes and \a
482         init_bytes. \a bytes is an arbitrary (not necessarily constant) expression giving the
483         dynamic size of the field whereas \a init_bytes is the constant initial size assigned to the
484         field.
485
486     \param[in] name name of the field to define
487     \param[in] type return type of the accessor function
488     \param[in] size size of the field, either a single value \a bytes for fixed size parsers or two
489         separate arguments \a bytes and \a init_bytes for dynamically sized parsers
490  */
491 #define SENF_PARSER_CUSTOM_FIELD(name, type, size) 
492
493 ///@}
494
495 ///\name Bit fields
496 ///@{
497
498 /** \brief Define bit-field
499
500     Bit fields are supported by a special family of parser macros. These macros simplify defining
501     fields using the senf::Parse_Int, senf::Parse_UInt and senf::FlagParser parsers by keeping track
502     of the current bit position and automatically creating the correct template parameters.
503     
504     The \a type parameter specifies the type of bitfield to define. This value is one of
505     \li \c signed, for signed bit fields (senf::IntFieldParser)
506     \li \c unsigned, for unsigned bit fields (senf::UIntFieldParser) or 
507     \li \c bool, for single-bit flags (senf::FlagParser). 
508
509     The \a bits parameter specifies the number of bits the field covers. For \c signed or \c
510     unsigned fields, this value may be any numeric value from 1 to 32, for \c bool fields, this
511     value \e must be 1.
512
513     For more information see \ref parsermacrosbitfields
514
515     \param[in] name name of the bit field
516     \param[in] bits number of bits
517     \param[in] type bit field type, one of \c signed, \c unsigned or \c bool
518
519     \see \ref SENF_PARSER_BITFIELD_RO(), \ref SENF_PARSER_PRIVATE_BITFIELD(), \ref
520     SENF_PARSER_PRIVATE_BITFIELD_RO()
521
522     \hideinitializer
523  */
524 #define SENF_PARSER_BITFIELD(name, bits, type) 
525
526 /** \brief Define bit-field (read-only) 
527
528     Define read-only bit field.
529
530     \see \ref SENF_PARSER_BITFIELD()
531     \hideinitializer
532  */
533 #define SENF_PARSER_BITFIELD_RO(name, bits, type) 
534
535 /** \brief Define bit-field (private) 
536
537     Define a bit field which is marked as \c private and may only be accessed from the parser class
538     itself.
539
540     \see \ref SENF_PARSER_BITFIELD()
541     \hideinitializer
542  */
543 #define SENF_PARSER_PRIVATE_BITFIELD(name, bits, type) 
544
545 /** \brief Define bit-field (private + read-only) 
546
547     Define a read-only bit field which is marked as \c private and may only be accessed from the
548     parser class itself.
549
550     \see \ref SENF_PARSER_BITFIELD()
551     \hideinitializer
552  */
553 #define SENF_PARSER_PRIVATE_BITFIELD_RO(name, bits, type)
554
555 ///@}
556
557 ///\name Current offset
558 ///@{
559
560 /** \brief Skip bytes
561
562     Moves the offset by the given distance (which may be negative). \a skip depends on the type of
563     parser being defined and is either \a bytes or \a bytes, \a init_bytes.
564
565     \li If defining a fixed parser, \a bytes must be a constant integral expression which will be
566         added to the current offset
567     \li If defining a dynamically sized parser, the macro really takes two arguments, \a bytes and
568         \a init_bytes. \a bytes will adjust the current field offset whereas \a init_bytes will
569         adjust the parsers \c init_bytes value. \a bytes is allowed to be any integral expression,
570         and need \e not be constant. The second argument \a init_bytes on the other hand needs to be
571         a constant integral expression.
572
573     \param[in] bytes number of bytes to skip
574     \param[in] init_bytes only for dynamically sized parsers, value to adjust the \c init_bytes value
575         with.
576
577     \hideinitializer
578  */
579 #define SENF_PARSER_SKIP(skip)
580
581 /** \brief Skip bits within bitfield group
582
583     This command will skip the given number of bits within a bitfield group. This command does \e
584     only affect bitfield commands. Therefore, a SENF_PARSER_SKIP_BITS command which is not followed
585     by a bitfield command will be ignored.
586
587     \hideinitializer
588  */
589 #define SENF_PARSER_SKIP_BITS(bits)
590
591 /** \brief Change current offset
592
593     This command will change the current offset to the field or label \a name. Fields defined after
594     this command will start at that position and will therefore overlay any fields defined earlier
595     for these byte positions.
596
597     \ref SENF_PARSER_GOTO() does \e not take into account the current bit position within bit
598     fields. When passed the name of a field within a bit field group, this command will always jump
599     to the beginning of the \e complete group (\e not the field within the bit field), even if the
600     group covers multiple bytes before the bit field \a name.
601
602     \param[in] name field or label to jump to
603     \hideinitializer
604  */
605 #define SENF_PARSER_GOTO(name)
606
607 /** \brief Change current offset to explicit value
608
609     \ref SENF_PARSER_GOTO_OFFSET() allows to change the current offset manually to an arbitrary
610     value. The \a offset parameter depends on the type of field currently being defined. 
611    
612     \li If defining a <em>fixed size parser</em>, the \a offset argument is a single \a bytes value
613         which is an integral constant expression to which the offset will be set.
614     \li If defining a <em>dynamically sized parser</em>, the \a offset argument is given by two
615         parameters \a bytes and \a init_bytes. \a bytes can be any integral expression (not
616         necessarily constant) giving the new byte position. \a init_bytes must be a constant
617         integral expression and will set the current initial size of the packet to this value.
618
619     \param[in] offset Depending on the parser type, either single \a bytes value or two arguments \a
620         bytes and \a init_size.
621     \hideinitializer
622  */
623 #define SENF_PARSER_GOTO_OFFSET(offset)
624
625 /** \brief Define offset label
626
627     This command defines \a name as a label for the current offset. The member
628     <em>name</em><tt>_offset</tt> is defined (either as a constant for fixed size parsers or as a
629     member function for dynamically sized parsers) to return the position at the point of label
630     definition. 
631
632     \ref SENF_PARSER_GOTO() can later be used to jump to a position which has previously been
633     labeled with \ref SENF_PARSER_LABEL()
634
635     \param[in] name label name
636     \hideinitializer
637  */
638 #define SENF_PARSER_LABEL(name)
639
640 /** \brief Get field offset
641
642     This macro will return the offset of the given field or label. This macro may only be used
643     while defining the parser, normally while defining inline functions.
644
645     This macro will return the correct value when defining fixed or dynamically sized parsers.
646
647     \param[in] name field or label name
648     \returns offset of the field from parsers start
649     \hideinitializer
650  */
651 #define SENF_PARSER_OFFSET(name)
652
653 /** \brief Get fixed field offset, if possible
654
655     This macro will return the fixed offset to the field \a name, a compile-time constant
656     expression. This is identical to \ref SENF_PARSER_OFFSET() when defining a fixed size parser.
657
658     Even in dynamically sized parsers this macro will work, if the field \a name is preceded by
659     fixed size fields only. This macro does \e not validate this condition, it will return an
660     arbitrary incorrect value otherwise.
661
662     \pre Field \a name preceded by fixed size fields only
663     \param[in] name field or label name
664     \returns compile-time constant offset of the field from parsers start
665     \hideinitializer
666  */
667 #define SENF_PARSER_FIXED_OFFSET(name)
668
669 /** \brief Get current fixed offset, if possible
670  
671     This macro will return the current fixed offset, a compile-time constant expression. This is
672     always possible when defining a fixed size parser.
673
674     Even in dynamically sized parsers this macro will work, if all parser defined \e before the
675     current position are fixed-size parsers. This macro does \e not validate this condition, it will
676     return an arbitrary incorrect value otherwise.
677
678     \pre Current position preceded by fixed-size parsers only
679     \returns compile-time constant offset from parsers start
680     \hideinitializer
681  */
682 #define SENF_PARSER_CURRENT_FIXED_OFFSET()
683
684 ///@}
685
686 #else
687
688 #define SENF_PARSER_INHERIT      BOOST_PP_CAT(SENF_PARSER_INHERIT_,      SENF_PARSER_TYPE)
689
690 #define SENF_PARSER_FIELD        BOOST_PP_CAT(SENF_PARSER_FIELD_,        SENF_PARSER_TYPE)
691 #define SENF_PARSER_FIELD_RO     BOOST_PP_CAT(SENF_PARSER_FIELD_RO_,     SENF_PARSER_TYPE)
692 #define SENF_PARSER_BITFIELD     BOOST_PP_CAT(SENF_PARSER_BITFIELD_,     SENF_PARSER_TYPE)
693 #define SENF_PARSER_BITFIELD_RO  BOOST_PP_CAT(SENF_PARSER_BITFIELD_RO_,  SENF_PARSER_TYPE)
694 #define SENF_PARSER_CUSTOM_FIELD BOOST_PP_CAT(SENF_PARSER_CUSTOM_FIELD_, SENF_PARSER_TYPE)
695
696 #define SENF_PARSER_PRIVATE_FIELD       BOOST_PP_CAT(SENF_PARSER_P_FIELD_,       SENF_PARSER_TYPE)
697 #define SENF_PARSER_PRIVATE_FIELD_RO    BOOST_PP_CAT(SENF_PARSER_P_FIELD_RO_,    SENF_PARSER_TYPE)
698 #define SENF_PARSER_PRIVATE_BITFIELD    BOOST_PP_CAT(SENF_PARSER_P_BITFIELD_,    SENF_PARSER_TYPE)
699 #define SENF_PARSER_PRIVATE_BITFIELD_RO BOOST_PP_CAT(SENF_PARSER_P_BITFIELD_RO_, SENF_PARSER_TYPE)
700
701 #define SENF_PARSER_SKIP         BOOST_PP_CAT(SENF_PARSER_SKIP_,        SENF_PARSER_TYPE)
702 #define SENF_PARSER_SKIP_BITS    BOOST_PP_CAT(SENF_PARSER_SKIP_BITS_,   SENF_PARSER_TYPE)
703 #define SENF_PARSER_GOTO         BOOST_PP_CAT(SENF_PARSER_GOTO_,        SENF_PARSER_TYPE)
704 #define SENF_PARSER_GOTO_OFFSET  BOOST_PP_CAT(SENF_PARSER_GOTO_OFFSET_, SENF_PARSER_TYPE)
705 #define SENF_PARSER_LABEL        BOOST_PP_CAT(SENF_PARSER_LABEL_,       SENF_PARSER_TYPE)
706
707 #define SENF_PARSER_OFFSET       BOOST_PP_CAT(SENF_PARSER_OFFSET_,      SENF_PARSER_TYPE)
708 #define SENF_PARSER_FIXED_OFFSET BOOST_PP_CAT(SENF_PARSER_FIXED_OFFSET_,SENF_PARSER_TYPE)
709 #define SENF_PARSER_CURRENT_FIXED_OFFSET BOOST_PP_CAT(SENF_PARSER_CURRENT_FIXED_OFFSET_, SENF_PARSER_TYPE)
710
711 #define SENF_PARSER_FINALIZE     BOOST_PP_CAT(SENF_PARSER_FINALIZE_,    SENF_PARSER_TYPE)
712
713 #endif
714
715 ///\}
716
717 ///////////////////////////////hh.e////////////////////////////////////////
718 #endif
719 #if !defined(HH_Packets__decls_) && !defined(HH_ParseHelpers_i_)
720 #define HH_ParseHelpers_i_
721 //#include "ParseHelpers.cci"
722 //#include "ParseHelpers.ct"
723 //#include "ParseHelpers.cti"
724 #endif
725
726 \f
727 // Local Variables:
728 // mode: c++
729 // fill-column: 100
730 // comment-column: 40
731 // c-file-style: "senf"
732 // indent-tabs-mode: nil
733 // ispell-local-dictionary: "american"
734 // compile-command: "scons -u test"
735 // End: