senfscons: Fix 'Object' build helper to work with empty source list in SCons 0.96.1
[senf.git] / Packets / PacketParser.hh
1 // Copyright (C) 2007 
2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 //     Stefan Bund <g0dil@berlios.be>
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 /** \file
22     \brief PacketParser public header */
23
24 /** \defgroup packetparser The PacketParser facility
25     
26     The PacketParser facility provides a framework to implement very lightweight classes which parse
27     the raw content of a packet into meaningful values. PacketParsers are always passed around
28     <em>by value</em>, they can be understood as pointers into the packet data with added type
29     information providing parsing functions.
30
31     Packet parsers are \e only used within the packet framework. You should never allocate a new
32     parser instance directly, you should the Packet library let that do for you (either by having
33     the parser as a packet parser in a packet type or by having a member in the packet parser which
34     allocates the parser as a sub-parser).
35
36     Parsers are built hierarchically. A high-level parser will return other parsers when accessing
37     an element (Example: Asking an EthernetParser for the ethertype field by calling the parsers \c
38     type() member will return an \c UInt16 parser). The lowest level building blocks then return the
39     values. This hierarchical structure greatly simplifies building complex parsers.
40
41     Since parsers are very lightweight and are passed by value, packet fields are accessed using the
42     corresponding accessor method:
43     \code
44       SomePacket p (...)
45       SomePacket q (...)
46
47       // Assign new value to an integer parser
48       p->someField() = 10;
49
50       // Write out above value
51       std::cerr << p->someField() << "\n";
52
53       // Use the generic parser-assignment operator '<<' to copy field values
54       p->someVector()[1].someOtherField() << q->someField();
55       p->someVector() << q->someVector()
56     \endcode
57
58     Here \c someField(), \c someOtherField() and \c someVector() are accessor methods named after
59     the field name. Each returns a parser object. Simple parsers can be used like their
60     corresponding basic type (e.g. a Parse_UInt16 field can be used like an unsigned integer), more
61     complex parsers provide type specific access members. Assigning a value to a parser will change
62     the underlying representation (the packet data). 
63
64     Parsers can be grouped into several categories. These categories are not all defined rigorously
65     but are nevertheless helpful when working with the parsers:
66     \li <em>\ref parserimpl_value</em> provide the lowest level parsers (e.g. senf::Parse_UInt16 which
67         returns an integer value).
68     \li <em>\ref parserimpl_collection</em> are parsers which model a collection of sub-elements like
69         senf::Parse_List or senf::Parse_Vector.
70     \li <em>\ref parserimpl_composite</em> collect several fields of arbitrary type into a new
71         parser. Parsers defined using the \ref packetparsermacros fall under this category.
72     \li <em>\ref parserimpl_packet</em> are used to define a packet type.
73
74     \warning Parsers are like iterators: They are invalidated <em>whenever the size of the packet's
75     data is changed</em>. You should not store a parser anywhere. If you want to keep a parser
76     reference, use the senf::SafePacketParser wrapper. You still will need to take extra care to
77     ensure the parser is not invalidated.
78
79     \section parserimpl Packet parser categories
80
81     Every parser is derived from senf::PacketParserBase. This class provides the necessary
82     housekeeping information and provides the parsers with access to the data. You may in principle
83     define arbitrary methods as parser members (e.g. methods to calculate a checksum, methods
84     processing fields in some way and so on). You should however be very wary to access data outside
85     the range assigned to the packet (the range starting at \c i() and with a size of senf::bytes()
86     bytes).
87     
88     Each parser type has specific features
89
90     \subsection parserimpl_value Value parsers
91
92     For a parser \a SomeParser to be a value parser, the following expressions must be valid:
93     \code
94     // SomeParser must have a 'value_type', The 'value_type' must be default constructible, copy
95     // constructible and assignable
96     SomeParser::value_type v; 
97
98     // An instance of 'SomeParser' must have a 'value' member which returns a value which may be
99     // assigned to a variable of type 'value_type'
100     v = p.someParserField().value()
101
102     // It must be possible to assign a new value using the 'value' member
103     p.someParserField().value(v)
104     \endcode
105
106     If at all possible, the 'value_type' should not reference the packet data using iterators or
107     pointers, it should hold a copy of the value (it's Ok for \c value() to return such a reference
108     as long as assigning it to a \c value_type variable will copy the value).
109
110     \subsection parserimpl_collection Collection parsers
111
112     A collection parser \a SomeParser should model STL containers. The parsers themselves will
113     probably only // provide a reduced interface, but the collection parser should have a \c
114     collection member which is a wrapper providing the full interface.
115     \code
116     SomeParser::container c (p.someParserField());
117     \endcode
118
119     You will probably only very seldom need to implement a completely new collection
120     parser. Instead, you can rely on senf::Parse_Vector or senf::Parse_List and implement new
121     policies.
122
123     \subsection parserimpl_composite Composite parsers
124     
125     If possible, composite parsers should be implemented using the \ref packetparsermacros. In
126     addition to the normal parser requirements, these macros ensure, that for each field,
127     <em>fieldname</em><tt>_t</tt> is a typedef for the fields parser and
128     <em>fieldname</em><tt>_offset</tt> is the offset of the field in bytes from the beginning of the
129     parser (either a constant for fixed size parsers or a member function for dynamically sized
130     parsers). When defining composite parsers without the help of the \ref packetparsermacros, you
131     should provide those same members.
132
133     \subsection parserimpl_packet Packet parsers
134
135     Packet parsers are composite parsers with relaxed requirements. Since a packet parser will never
136     be used as a sub-parser (it will not be used within another composite parser or as value type in
137     a collection parser), the value returned by senf::bytes for this parser must not necessarily
138     cover the complete packet (e.g. if the packet has a trailer, the trailer will live outside the
139     range given by senf::bytes). You may define any member you want to have in your packets field
140     interface. These members may access the packet data in any way. You just need to ensure, that
141     the integration into the packet-type is correct (the senf::PacketTypeMixin will by default use
142     senf::bytes() to find the end of the header).
143
144     <hr>
145  */
146
147 #ifndef HH_PacketParser_
148 #define HH_PacketParser_ 1
149
150 // Custom includes
151 #include <boost/utility/enable_if.hpp>
152 #include <boost/type_traits.hpp>
153 #include <boost/optional.hpp>
154 #include "../Utils/SafeBool.hh"
155 #include "PacketTypes.hh"
156 #include "PacketData.hh"
157
158 #include "PacketParser.mpp"
159 ///////////////////////////////hh.p////////////////////////////////////////
160
161 namespace senf {
162
163     class Packet;
164     
165     /** \brief Parser Base class
166
167         Parsers come in two flavors: fixed and dynamically sized parsers. A <em>fixed size
168         parser</em> has a constant size, it will always parse a fixed number of bytes. The low-level
169         'final'  parsers (like the integer parsers) are fixed size parsers as are composite parsers
170         built up only of fixed-size fields.
171
172         A <em>dynamically sized</em> parser on the other hand infers it's size from the contents of
173         the data parsed. Any parser containing at least one dynamically sized sub-parser will itself
174         be dynamically sized.
175         
176         Both kinds of parser need to derive from PacketParserBase and implement several required
177         members. Which members to implement depends on the parsers flavor. There are two ways how to
178         do this.
179         \li If the parser just consists of a simple sequence of consecutive fields (sub-parsers),
180             the \ref SENF_PACKET_PARSER_DEFINE_FIELDS and \ref
181             SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS macros provide a simple and convenient way to
182             define the packet
183         \li In more complex cases, you need to implement the necessary members manually.
184
185         This documentation is about the manual implementation. You should nevertheless read through
186         this to understand, what above macros are doing.
187
188         The following example documents the interface (which must be) provided by a parser:
189         \code
190           struct FooParser : public PacketParserBase
191           {
192               FooParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
193
194               // If this parser has a fixed size, you must define this size here This definition
195               // allows the parser to be used within the list, vector and array parsers static
196               static const size_type fixed_bytes = some_constant_size;
197
198               // If the parser does not have a fixed size, you must implement the bytes() member to
199               // return the size. ONLY EVER DEFINE ONE OF fixed_bytes OR bytes().
200               size_type bytes() const;
201
202               // If you define bytes(), you also need to define the init_bytes. This is the number
203               // of bytes to allocate when creating a new object
204               static const size_type init_bytes = some_constant_size;
205
206               // You also may define an init() member. This will be called to initialize a newly
207               // created data object. The default implementation just does nothing.
208               void init() const;
209
210               // ////////////////////////////////////////////////////////////////////////
211
212               // Add here members returning (sub-)parsers for the fields. The 'parse' member is 
213               // used to construct the sub-parsers. This member either takes an iterator to the
214               // data to be parsed or just an offset in bytes.
215
216               senf::Parse_UInt16 type() const { return parse<Parse_UInt16>( 0 ); }
217               senf::Parse_UInt16 size() const { return parse<Parse_UInt16>( 2 ); }
218           };
219         \endcode
220         
221         You should never call the \c bytes() member of a parser directly. Instead you should use the
222         freestanding senf::bytes() function. This function will return the correct size irrespective
223         of the parsers flavor. You may access \c fixed_bytes directly, however be aware that this
224         will restrict your code to fixed size parsers (which depending on the circumstances may be
225         exactly what you want).
226
227         In the same way, don't access \c init_bytes directly, always use the senf::init_bytes
228         meta-function class which correctly supports fixed size parsers.
229
230         \ingroup packetparser
231       */
232     class PacketParserBase
233     {
234     public:
235         ///////////////////////////////////////////////////////////////////////////
236         // Types
237
238         typedef detail::packet::iterator data_iterator; ///< Raw data iterator type
239         typedef detail::packet::size_type size_type; ///< Unsigned integral type
240         typedef detail::packet::difference_type difference_type; ///< Signed integral type
241         typedef detail::packet::byte byte; ///< Unsigned 8bit value, the raw value type
242         typedef PacketData * state_type; ///< Type of the 'state' parameter
243
244         ///////////////////////////////////////////////////////////////////////////
245         ///\name Structors and default members
246         ///@{
247
248         // no default constructor
249         // default copy
250         // default destructor
251         // no conversion constructors
252
253         ///@}
254         ///////////////////////////////////////////////////////////////////////////
255
256         data_iterator i() const;        ///< Return beginning of data to parse
257                                         /**< The parser is expected to interpret the data beginning
258                                              here. The size of the interpreted is given by
259                                              <tt>senf::bytes(</tt><em>parser
260                                              instance</em><tt>)</tt>. */
261         state_type state() const;       ///< Return state of this parser
262                                         /**< The value returned should be interpreted as an opaque
263                                              value provided just to be forwarded to other
264                                              parsers. */
265         PacketData & data() const;      ///< Access the packets raw data container
266                                         /**< This member will return the raw data container holding
267                                              the data which is parsed by \c this parser. */
268
269         void init() const;              ///< Default implementation
270                                         /**< This is just an empty default
271                                              implementation. Re-implement this member in your own
272                                              parsers if needed. */
273
274     protected:
275         PacketParserBase(data_iterator i, state_type s); ///< Standard constructor
276                                         /**< This is the constructor used by most parsers. The
277                                              parameters are just forwarded from the derived classes
278                                              constructor parameters. */
279         PacketParserBase(data_iterator i, state_type s, size_type size); 
280                                         ///< Size checking constructor
281                                         /**< In addition to the standard constructor, this
282                                              constructor will validate, that there is enough data in
283                                              the raw data container to parse \a size bytes after \a
284                                              i.
285
286                                              This constructor is called by all 'final' parsers
287                                              (e.g. the integer parsers) and \e only by those
288                                              parsers. Most parsers do \e not check the validity of
289                                              the iterator, this is delayed until the very last
290                                              parser. This allows to partial parse truncated
291                                              packets.
292
293                                              \throw TruncatedPacketException if the raw data
294                                                  container does not hold at least \a size bytes
295                                                  beginning at \a i. */
296
297         bool check(size_type size) const; ///< Check size of data container
298                                         /**< \returns \c true, if the data container holds at least
299                                              \a size beginning at i(), \c false otherwise. */
300         void validate(size_type size) const; ///< Validate size of data container
301                                         /**< \throws TruncatedPacketException if the raw data
302                                              container does not hold at least \a size bytes
303                                              beginning at i(). */
304
305         template <class Parser> Parser parse(data_iterator i) const; ///< Create sub-parser
306                                         /**< Creates a new instance of \a Parser to parse data
307                                              beginning at \a i. Automatically passes \a state() to
308                                              the new parser. */
309         template <class Parser> Parser parse(size_type n) const; ///< Create sub-parser
310                                         /**< Creates a new instance of \a Parser to parse data
311                                          * beginning at i()<tt> + </tt>\a n. Automatically passes \a
312                                              state() to the new parser. */
313
314         void defaultInit() const;       ///< Default implementation
315                                         /**< This is just an empty default
316                                              implementation. Re-implement this member in your own
317                                              parsers if needed. */
318
319         Packet packet() const;          ///< Get packet this parser is parsing from
320                                         /**< \important This member should only be used from packet
321                                              parsers when access to previous or following packets is
322                                              needed e.g. for calculating checksums etc. */
323
324     private:
325         data_iterator end() const;
326
327         data_iterator i_;
328         PacketData * data_;
329
330         template <class Parser> friend class SafePacketParser;
331     };
332
333     /** \brief Return raw size parsed by the given parser object
334         
335         This function will either call <tt>p.bytes()</tt> or return <tt>Parser::fixed_bytes</tt>
336         depending on the type of parser.
337
338         The value returned does \e not take into account the amount of data actually available. So
339         you always need to validate this value against the packet size if you directly access the
340         data. The standard low-level parses all do this check automatically to guard against
341         malformed packets.
342
343         \param[in] p Parser object to check
344         \returns number of bytes this parser expects to parser
345         \ingroup packetparser
346      */
347     template <class Parser>
348     PacketParserBase::size_type bytes(Parser p);
349     
350     namespace detail { template <class Parser> class ParserInitBytes; }
351
352     /** \brief Return number of bytes to allocate to new object of given type
353
354         This meta-function is called like
355         \code
356             senf::init_bytes<SomeParser>::value
357         \endcode
358
359         This expression evaluates to a compile-time constant integral expression of type
360         senf::PacketParserBase::size_type. This meta-function will return \c Parser::fixed_bytes or
361         \c Parser::init_bytes depending on the type of parser.
362
363         \param[in] Parser The Parser to return init_bytes for
364         \returns Number of bytes to allocate to the new object
365         \ingroup packetparser
366      */
367     template <class Parser>
368     struct init_bytes : public detail::ParserInitBytes<Parser>
369     {};
370
371 #   ifndef DOXYGEN
372     template <class Parser>
373     typename boost::enable_if< 
374         boost::is_base_of<PacketParserBase, Parser>,
375         Parser >::type
376     operator<<(Parser target, Parser source);
377 #   else
378     /** \brief Generic parser copying
379
380
381         This operator allows to copy the values of identical parsers. This operation does \e not
382         depend on the parsers detailed implementation, it will just replace the data bytes of the
383         target parser with those from the source parser. This allows to easily copy around complex
384         packet substructures.
385
386         This operation is different from the ordinary assignment operator: It does not change the \a
387         target parser, it changes the data referenced by the \a target parser.
388
389         \ingroup packetparser
390      */
391     template <class Parser>
392     Parser operator<<(Parser target, Parser source);
393 #   endif
394
395 #   ifndef DOXYGEN
396     template <class Parser, class Value>
397     typename boost::enable_if_c < 
398         boost::is_base_of<PacketParserBase, Parser>::value 
399             && ! boost::is_base_of<PacketParserBase, Value>::value,
400         Parser >::type
401     operator<<(Parser target, Value const & value);
402 #   else 
403     /** \brief Generic parser value assignment
404
405         This operator allows to assign a value to parsers which implement a <tt>value(</tt>\a
406         value<tt>)</tt> member. This operator allows to use a common syntax for assigning values or
407         parsers to a parser. 
408
409         \ingroup packetparser
410      */
411     template <class Parser, class Value>
412     Parser operator<<(Parser target, Value const & value);
413 #   endif
414
415 #   ifndef DOXYGEN
416     template <class Parser, class Value>
417     typename boost::enable_if_c < 
418         boost::is_base_of<PacketParserBase, Parser>::value 
419             && ! boost::is_base_of<PacketParserBase, Value>::value,
420         Parser >::type
421     operator<<(Parser target, boost::optional<Value> const & value);
422 #   else 
423     /** \brief Generic parser value assignment
424
425         This operator allows to assign a value to parsers which implement a <tt>value(</tt>\a
426         value<tt>)</tt> member. This special version allows to assign optional values: IF the
427         optional value is not set, the assignment will be skipped. 
428
429         This operator allows to use a common syntax for assigning values or parsers to a parser.
430
431         \ingroup packetparser
432      */
433     template <class Parser, class Value>
434     Parser operator<<(Parser target, boost::optional<Value> const & value);
435 #   endif
436
437     /** \defgroup packetparsermacros Helper macros for defining new packet parsers
438         
439         To simplify the definition of simple packet parsers, several macros are provided. Before
440         using these macros you should familiarize yourself with the packet parser interface as
441         described in senf::PacketParserBase.
442
443         These macros simplify providing the above defined interface. A typical packet declaration
444         using these macros has the following form (This is a concrete example from the definition of
445         the ethernet packet in <tt>DefaultBundle/EthernetPacket.hh</tt>)
446     
447         \code
448         struct Parse_EthVLan : public PacketParserBase
449         {
450             typedef Parse_UIntField < 0,  3 > Parse_Priority;
451             typedef Parse_Flag          < 3 > Parse_CFI;
452             typedef Parse_UIntField < 4, 16 > Parse_VLanId;
453             typedef Parse_UInt16              Parse_Type;
454
455             SENF_PACKET_PARSER_INIT(Parse_EthVLan);
456
457             SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS(
458                 ((OverlayField)( priority, Parse_Priority ))
459                 ((OverlayField)( cfi,      Parse_CFI      ))
460                 ((Field       )( vlanId,   Parse_VLanId   ))
461                 ((Field       )( type,     Parse_Type     )) );
462         };
463         \endcode
464         
465         The macros take care of the following:
466         \li They define the accessor functions returning parsers of the given type.
467         \li They automatically calculate the offset of the fields from the preceding fields.
468         \li The macros provide a definition for \c init() 
469         \li The macros define the \c bytes(), \c fixed_bytes and \c init_bytes members as needed.
470
471         You may define either a fixed or a dynamically sized parser. Fixed size parsers are defined
472         using \ref SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS, dynamically sized parsers are defined
473         using \ref SENF_PACKET_PARSER_DEFINE_FIELDS. The different members are implemented such
474         that:
475         
476         \li The needed parser constructor is defined
477         \li \c init() calls \c defaultInit(). \c defaultInit() is defined to call \c init() on each
478             of the fields.
479         \li \c bytes() (on dynamically sized parser) respectively \c fixed_bytes (on fixed size
480             parsers) is defined to return the sum of the sizes of all fields.
481         \li On dynamically sized parsers, \c init_bytes is defined to return the sum of the
482             \c init_size's of all fields
483
484         The central definition macros are \ref SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS and \ref
485         SENF_PACKET_PARSER_DEFINE_FIELDS. The argument to both has the same structure. It is a
486         (boost preprocessor style) sequence of field definitions where each field definition
487         provides the builder macro to use and the name and type of the field to define:
488         \code
489           SENF_PACKET_PARSER_DEFINE[_FIXED]_FIELDS(
490               (( <builder> )( <name>, <type> ))
491               ...
492           )
493         \endcode
494         
495         For each field, this command will define
496         \li A method \a name() returning an instance of the \a type parser
497         \li \a name<tt>_t</tt> as a typedef for \a type, the fields value
498         \li \a name<tt>_offset</tt> to give the offset of the field from the beginning of the
499             parser. If the parser is a fixed size parser, this will be a static constant, otherwise
500             it will be a method.
501
502         The \a builder argument selects, how the field is defined
503         \li <tt>Field</tt> defines a field and increments the current position by the size of the
504             field
505         \li <tt>OverlayField</tt> defines a field like <tt>Field</tt> but does \e not increment the
506             position. In the above example, this is used to overlay the different bitfield parsers:
507             All overlaying bitfield parser except the last one (the one with the highest bit
508             numbers) is marked as OverlayField.
509
510         The \a name argument defines the name of the accessor method.
511
512         The \a type argument is the parser to return for that field. Since none of the arguments may
513         contain a comma, <em>This argument cannot be a multi-parameter template</em>. Always use
514         typedefs to access templated parsers as shown above.
515
516         The \ref SENF_PACKET_PARSER_INIT macro defines the constructor and the \c init() member. If
517         you want to provide your own \c init() implementation, use \ref
518         SENF_PACKET_PARSER_NO_INIT. The first statement in your init method should probably to call
519         \c defaultInit(). This will call the \c init() member of all the fields. Afterwards you can
520         set up the field values as needed:
521         \code
522           struct SomePacket : public senf::PacketParserBase
523           {
524               SENF_PACKET_PARSER_NO_INIT(SomePacket);
525         
526               typedef senf::Parse_UInt8 Parse_Type;
527               typedef senf::Parse_Vector< senf::Parse_UInt32,
528                                           senf::SimpleVectorSizer<senf::Parse_UInt16>
529                                         > Parse_Elements;
530
531               SENF_PACKET_PARSER_DEFINE_FIELDS(
532                   ((Field)( type,     Parse_Type     ))
533                   ((Field)( elements, Parse_Elements ))
534               );
535
536               void init() const {
537                   defaultInit();
538                   type() = 0x01;
539                   elements().push_back(0x01020304u);
540               }
541           }
542         \endcode
543         
544         \ingroup packetparser
545      */
546
547     /** \brief Define initialization members of a parser
548         
549         This macro defines the packet parser constructor and the \c init() member. \c init() is
550         defined to just call \c defaultInit() which is defined by the other macros to call \c init()
551         on each of the parsers fields.
552
553         \ingroup packetparsermacros
554         \hideinitializer
555      */
556 #   define SENF_PACKET_PARSER_INIT(name)                                                          \
557     name(data_iterator i, state_type s) : senf::PacketParserBase(i,s) {}                          \
558     void init() const { defaultInit(); }
559
560     /** \brief Define initialization members of a parser except init()
561         
562         This macro is like SENF_PACKET_PARSER_INIT but does \e not define \c init(). This allows you
563         to provide your own implementation. You should call \c defaultInit() first before
564         initializing your data fields.
565
566         \ingroup packetparsermacros
567         \hideinitializer
568      */
569 #   define SENF_PACKET_PARSER_NO_INIT(name)                                                       \
570     name(data_iterator i, state_type s) : senf::PacketParserBase(i,s) {}
571
572     /** \brief Define fields for a dynamically sized parser
573
574         Define the fields as specified in \a fields. This macro supports dynamically sized
575         subfields, the resulting parser will be dynamically sized.
576
577         \ingroup packetparsermacros
578         \hideinitializer
579      */
580 #   define SENF_PACKET_PARSER_DEFINE_FIELDS(fields)                                               \
581     SENF_PACKET_PARSER_I_DEFINE_FIELDS(0,fields)
582         
583     /** \brief Define fields for a dynamically sized parser (with offset)
584
585         Define the fields as specified in \a fields. This macro supports dynamically sized
586         subfields, the resulting parser will be dynamically sized.
587
588         The \a offset argument gives the byte offset at which to start parsing the fields. This
589         helps defining extended parser deriving from a base parser:
590         \code
591            struct ExtendedParser : public BaseParser
592            {
593                ExtendedParser(data_iterator i, state_type s) : BaseParser(i,s) {}
594         
595                SENF_PACKET_PARSER_DEFINE_FIELDS_OFFSET(senf::bytes(BaseParser(*this)),
596                  ( ... fields ... ) );
597
598                void init() {
599                    BaseParser::init();
600                    defaultInit();
601                    // other init code
602                }
603            }
604         \endcode
605
606         \ingroup packetparsermacros
607         \hideinitializer
608      */
609 #   define SENF_PACKET_PARSER_DEFINE_FIELDS_OFFSET(offset,fields)                                 \
610     SENF_PACKET_PARSER_I_DEFINE_FIELDS(offset,fields)
611
612     /** \brief Define fields for a fixed size parser
613
614         Define the fields as specified in \a fields. This macro only supports fixed size
615         subfields, the resulting parser will also be a fixed size parser.
616
617         \ingroup packetparsermacros
618         \hideinitializer
619      */
620 #   define SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS(fields)                                         \
621     SENF_PACKET_PARSER_I_DEFINE_FIXED_FIELDS(0,fields)
622
623     /** \brief Define fields for a fixed size parser
624
625         Define the fields as specified in \a fields. This macro only supports fixed size
626         subfields, the resulting parser will also be a fixed size parser.
627
628         The \a offset argument gives the byte offset at which to start parsing the fields. This
629         helps defining extended parser deriving from a base parser:
630         \code
631            struct ExtendedParser : public BaseParser
632            {
633                ExtendedParser(data_iterator i, state_type s) : BaseParser(i,s) {}
634
635                SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS_OFFSET(BaseParser::fixed_bytes,
636                  ( ... fields ... ) );
637
638                void init() {
639                    BaseParser::init();
640                    defaultInit();
641                    // other init code
642                }
643            }
644         \endcode
645
646         \ingroup packetparsermacros
647         \hideinitializer
648      */
649 #   define SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS_OFFSET(offset,fields)                           \
650     SENF_PACKET_PARSER_I_DEFINE_FIXED_FIELDS(offset,fields)
651
652     /** \brief Default parser parsing nothing
653      */
654     struct VoidPacketParser 
655         : public PacketParserBase
656     {
657         SENF_PACKET_PARSER_INIT(VoidPacketParser);
658     };
659
660     /** \brief Iterator re-validating Parser wrapper
661
662         An ordinary parser will be invalidated whenever the raw data container's size is
663         changed. This can complicate some algorithms considerably.
664
665         This wrapper will update the parsers iterator (the value returned by the i() member) on
666         every access. This ensures that the iterator will stay valid.
667
668         \attention Beware however, if you insert or remove data before the safe wrapper, the
669             location will \e not be updated accordingly and therefore the parser will be
670             invalid.
671
672         Additionally a SafePacketParser has an uninitialized state. The only allowed operations in
673         this state are the boolean test for validity and assigning another parser.
674
675         \ingroup packetparser
676       */
677     template <class Parser>
678     class SafePacketParser
679         : public SafeBool< SafePacketParser<Parser> >
680     {
681     public:
682         ///////////////////////////////////////////////////////////////////////////
683         // Types
684
685         ///////////////////////////////////////////////////////////////////////////
686         ///\name Structors and default members
687         ///@{
688
689         // default copy constructor
690         // default copy assignment
691         // default destructor
692         SafePacketParser();             ///< Create an empty uninitialized SafePacketParser
693
694         // conversion constructors
695         SafePacketParser(Parser parser); ///< Initialize SafePacketParser from \a parser
696
697         SafePacketParser & operator=(Parser parser); ///< Assign \a parser to \c this
698
699         ///@}
700         ///////////////////////////////////////////////////////////////////////////
701
702         Parser operator*() const;       ///< Access the stored parser
703                                         /**< On every access, the stored parsers iterator will be
704                                              updated / re-validated. */
705         Parser const * operator->() const; ///< Access the stored parser
706                                         /**< On every access, the stored parsers iterator will be
707                                              updated / re-validated. */
708         bool boolean_test() const;      ///< Check validity
709
710     protected:
711
712     private:
713         mutable boost::optional<Parser> parser_;
714         senf::safe_data_iterator i_;
715     };
716
717 }
718
719 ///////////////////////////////hh.e////////////////////////////////////////
720 #endif
721 #if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketParser_i_)
722 #define HH_PacketParser_i_
723 #include "PacketParser.cci"
724 #include "PacketParser.ct"
725 #include "PacketParser.cti"
726 #endif
727
728 \f
729 // Local Variables:
730 // mode: c++
731 // fill-column: 100
732 // c-file-style: "senf"
733 // indent-tabs-mode: nil
734 // ispell-local-dictionary: "american"
735 // compile-command: "scons -u test"
736 // comment-column: 40
737 // End:
738