Move include files in debian packge into 'senf' subdirectory
[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>Value parsers</em> provide the lowest level parsers (e.g. senf::Parse_UInt16 which
67         returns an integer value).
68     \li <em>Collection parsers</em> are parsers which model a collection of sub-elements like
69         senf::Parse_List or senf::Parse_Vector.
70     \li <em>Composite parsers</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>Packet parsers</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     polcies.
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  */
145
146 #ifndef HH_PacketParser_
147 #define HH_PacketParser_ 1
148
149 // Custom includes
150 #include <boost/utility/enable_if.hpp>
151 #include <boost/type_traits.hpp>
152 #include <boost/optional.hpp>
153 #include "../Utils/SafeBool.hh"
154 #include "PacketTypes.hh"
155 #include "PacketData.hh"
156
157 #include "PacketParser.mpp"
158 ///////////////////////////////hh.p////////////////////////////////////////
159
160 namespace senf {
161     
162     /** \brief Parser Base class
163
164         Parsers come in two flavors: fixed and dynamically sized parsers. A <em>fixed size
165         parser</em> has a constant size, it will always parse a fixed number of bytes. The low-level
166         'final'  parsers (like the integer parsers) are fixed size parsers as are composite parsers
167         built up only of fixed-size fields.
168
169         A <em>dynamically sized</em> parser on the other hand infers it's size from the contents of
170         the data parsed. Any parser containing at least one dynamically sized sub-parser will itself
171         be dynamically sized.
172         
173         Both kinds of parser need to derive from PacketParserBase and implement several required
174         members. Which members to implement depends on the parsers flavor. There are two ways how to
175         do this.
176         \li If the parser just consists of a simple sequence of consecutive fields (sub-parsers),
177             the \ref SENF_PACKET_PARSER_DEFINE_FIELDS and \ref
178             SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS macros provide a simple and convenient way to
179             define the packet
180         \li In more complex cases, you need to implement the necessary members manually.
181
182         This documentation is about the manual implementation. You should nevertheless read through
183         this to understand, what above macros are doing.
184
185         The following example documents the interface (which must be) provided by a parser:
186         \code
187           struct FooParser : public PacketParserBase
188           {
189               FooParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
190
191               // If this parser has a fixed size, you must define this size here This definition
192               // allows the parser to be used within the list, vector and array parsers static
193               static const size_type fixed_bytes = some_constant_size;
194
195               // If the parser does not have a fixed size, you must implement the bytes() member to
196               // return the size. ONLY EVER DEFINE ONE OF fixed_bytes OR bytes().
197               size_type bytes() const;
198
199               // If you define bytes(), you also need to define the init_bytes. This is the number
200               // of bytes to allocate when creating a new object
201               static const size_type init_bytes = some_constant_size;
202
203               // You also may define an init() member. This will be called to initialize a newly
204               // created data object. The default implementation just does nothing.
205               void init() const;
206
207               // ////////////////////////////////////////////////////////////////////////
208
209               // Add here members returning (sub-)parsers for the fields. The 'parse' member is 
210               // used to construct the sub-parsers. This member either takes an iterator to the
211               // data to be parsed or just an offset in bytes.
212
213               senf::Parse_UInt16 type() const { return parse<Parse_UInt16>( 0 ); }
214               senf::Parse_UInt16 size() const { return parse<Parse_UInt16>( 2 ); }
215           };
216         \endcode
217         
218         You should never call the \c bytes() member of a parser directly. Instead you should use the
219         freestanding senf::bytes() function. This function will return the correct size irrespective
220         of the parsers flavor. You may access \c fixed_bytes directly, however be aware that this
221         will restrict your code to fixed size parsers (which depending on the circumstances may be
222         exactly what you want).
223
224         In the same way, don't access \c init_bytes directly, always use the senf::init_bytes
225         meta-function class which correctly supports fixed size parsers.
226
227         \ingroup packetparser
228       */
229     class PacketParserBase
230     {
231     public:
232         ///////////////////////////////////////////////////////////////////////////
233         // Types
234
235         typedef detail::packet::iterator data_iterator; ///< Raw data iterator type
236         typedef detail::packet::size_type size_type; ///< Unsigned integral type
237         typedef detail::packet::difference_type difference_type; ///< Signed integral type
238         typedef detail::packet::byte byte; ///< Unsigned 8bit value, the raw value type
239         typedef PacketData * state_type; ///< Type of the 'state' parameter
240
241         ///////////////////////////////////////////////////////////////////////////
242         ///\name Structors and default members
243         ///@{
244
245         // no default constructor
246         // default copy
247         // default destructor
248         // no conversion constructors
249
250         ///@}
251         ///////////////////////////////////////////////////////////////////////////
252
253         data_iterator i() const;        ///< Return beginning of data to parse
254                                         /**< The parser is expected to interpret the data beginning
255                                              here. The size of the interpreted is given by
256                                              <tt>senf::bytes(</tt><em>parser
257                                              instance</em><tt>)</tt>. */
258         state_type state() const;       ///< Return state of this parser
259                                         /**< The value returned should be interpreted as an opaque
260                                              value provided just to be forwarded to other
261                                              parsers. */
262         PacketData & data() const;      ///< Access the packets raw data container
263                                         /**< This member will return the raw data container holding
264                                              the data which is parsed by \c this parser. */
265
266         void init() const;              ///< Default implementation
267                                         /**< This is just an empty default
268                                              implementation. Re-implement this member in your own
269                                              parsers if needed. */
270
271     protected:
272         PacketParserBase(data_iterator i, state_type s); ///< Standard constructor
273                                         /**< This is the constructor used by most parsers. The
274                                              parameters are just forwarded from the derived classes
275                                              constructor parameters. */
276         PacketParserBase(data_iterator i, state_type s, size_type size); 
277                                         ///< Size checking constructor
278                                         /**< In addition to the standard constructor, this
279                                              constructor will validate, that there is enough data in
280                                              the raw data container to parse \a size bytes after \a
281                                              i.
282
283                                              This constructor is called by all 'final' parsers
284                                              (e.g. the integer parsers) and \e only by those
285                                              parsers. Most parsers do \e not check the validity of
286                                              the iterator, this is delayed until the very last
287                                              parser. This allows to partial parse truncated
288                                              packets.
289
290                                              \throw TruncatedPacketException if the raw data
291                                                  container does not hold at least \a size bytes
292                                                  beginning at \a i. */
293
294         bool check(size_type size);     ///< Check size of data container
295                                         /**< \returns \c true, if the data container holds at least
296                                              \a size beginning at i(), \c false otherwise. */
297         void validate(size_type size);  ///< Validate size of data container
298                                         /**< \throws TruncatedPacketException if the raw data
299                                              container does not hold at least \a size bytes
300                                              beginning at i(). */
301
302         template <class Parser> Parser parse(data_iterator i) const; ///< Create sub-parser
303                                         /**< Creates a new instance of \a Parser to parse data
304                                              beginning at \a i. Automatically passes \a state() to
305                                              the new parser. */
306         template <class Parser> Parser parse(size_type n) const; ///< Create sub-parser
307                                         /**< Creates a new instance of \a Parser to parse data
308                                          * beginning at i()<tt> + </tt>\a n. Automatically passes \a
309                                              state() to the new parser. */
310
311         void defaultInit() const;       ///< Default implementation
312                                         /**< This is just an empty default
313                                              implementation. Re-implement this member in your own
314                                              parsers if needed. */
315
316     private:
317         data_iterator end();
318
319         data_iterator i_;
320         PacketData * data_;
321
322         template <class Parser> friend class SafePacketParser;
323     };
324
325     /** \brief Return raw size parsed by the given parser object
326         
327         This function will either call <tt>p.bytes()</tt> or return <tt>Parser::fixed_bytes</tt>
328         depending on the type of parser.
329
330         The value returned does \e not take into account the amount of data actually available. So
331         you always need to validate this value against the packet size if you directly access the
332         data. The standard low-level parses all do this check automatically to guard against
333         malformed packets.
334
335         \param[in] p Parser object to check
336         \returns number of bytes this parser expects to parser
337         \ingroup packetparser
338      */
339     template <class Parser>
340     PacketParserBase::size_type bytes(Parser p);
341     
342     namespace detail { template <class Parser> class ParserInitBytes; }
343
344     /** \brief Return number of bytes to allocate to new object of given type
345
346         This meta-function is called like
347         \code
348             senf::init_bytes<SomeParser>::value
349         \endcode
350
351         This expression evaluates to a compile-time constant integral expression of type
352         senf::PacketParserBase::size_type. This meta-function will return \c Parser::fixed_bytes or
353         \c Parser::init_bytes depending on the type of parser.
354
355         \param[in] Parser The Parser to return init_bytes for
356         \returns Number of bytes to allocate to the new object
357         \ingroup packetparser
358      */
359     template <class Parser>
360     struct init_bytes : public detail::ParserInitBytes<Parser>
361     {};
362
363 #   ifndef DOXYGEN
364     template <class Parser>
365     typename boost::enable_if< 
366         boost::is_base_of<PacketParserBase, Parser>,
367         Parser >::type
368     operator<<(Parser target, Parser source);
369 #   else
370     /** \brief Generic parser copying
371
372         This operator allows to copy the values of identical parsers. This operation does \e not
373         depend on the parsers detailed implementation, it will just replace the data bytes of the
374         target parser with those from the source parser. This allows to easily copy around complex
375         packet substructures.
376
377         This operation is different from the ordinary assignment operator: It does not change the \a
378         target parser, it changes the data referenced by the \a target parser.
379
380         \ingroup packetparser
381      */
382     template <class Parser>
383     Parser operator<<(Parser target, Parser source);
384 #   endif
385
386 #   ifndef DOXYGEN
387     template <class Parser, class Value>
388     typename boost::enable_if_c < 
389         boost::is_base_of<PacketParserBase, Parser>::value 
390             && ! boost::is_base_of<PacketParserBase, Value>::value,
391         Parser >::type
392     operator<<(Parser target, Value const & value);
393 #   else 
394     /** \brief Generic parser value assignment
395
396         This operator allows to assign a value to parsers which implement a <tt>value(</tt>\a
397         value<tt>)</tt> member. This operator allows to use a common syntax for assigning values or
398         parsers to a parser. 
399
400         \ingroup packetparser
401      */
402     template <class Parser, class Value>
403     Parser operator<<(Parser target, Value const & value);
404 #   endif
405
406     /** \defgroup packetparsermacros Helper macros for defining new packet parsers
407         
408         To simplify the definition of simple packet parsers, several macros are provided. Before
409         using these macros you should familiarize yourself with the packet parser interface as
410         described in senf::PacketParserBase.
411
412         These macros simplify providing the above defined interface. A typical packet declaration
413         using these macros has the following form (This is a concrete example from the definition of
414         the ethernet packet in <tt>DefaultBundle/EthernetPacket.hh</tt>)
415     
416         \code
417         struct Parse_EthVLan : public PacketParserBase
418         {
419             typedef Parse_UIntField < 0,  3 > Parse_Priority;
420             typedef Parse_Flag          < 3 > Parse_CFI;
421             typedef Parse_UIntField < 4, 16 > Parse_VLanId;
422             typedef Parse_UInt16              Parse_Type;
423
424             SENF_PACKET_PARSER_INIT(Parse_EthVLan);
425
426             SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS(
427                 ((OverlayField)( priority, Parse_Priority ))
428                 ((OverlayField)( cfi,      Parse_CFI      ))
429                 ((Field       )( vlanId,   Parse_VLanId   ))
430                 ((Field       )( type,     Parse_Type     )) );
431         };
432         \endcode
433         
434         The macros take care of the following:
435         \li They define the accessor functions returning parsers of the given type.
436         \li They automatically calculate the offset of the fields from the preceding fields.
437         \li The macros provide a definition for \c init() 
438         \li The macros define the \c bytes(), \c fixed_bytes and \c init_bytes members as needed.
439
440         You may define either a fixed or a dynamically sized parser. Fixed size parsers are defined
441         using \ref SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS, dynamically sized parsers are defined
442         using \ref SENF_PACKET_PARSER_DEFINE_FIELDS. The different members are implemented such
443         that:
444         
445         \li The needed parser constructor is defined
446         \li \c init() calls \c defaultInit(). \c defaultInit() is defined to call \c init() on each
447             of the fields.
448         \li \c bytes() (on dynamically sized parser) respectively \c fixed_bytes (on fixed size
449             parsers) is defined to return the sum of the sizes of all fields.
450         \li On dynamically sized parsers, \c init_bytes is defined to return the sum of the
451             \c init_size's of all fields
452
453         The central definition macros are \ref SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS and \ref
454         SENF_PACKET_PARSER_DEFINE_FIELDS. The argument to both has the same structure. It is a
455         (boost preprocessor style) sequence of field definitions where each field definition
456         provides the builder macro to use and the name and type of the field to define:
457         \code
458           SENF_PACKET_PARSER_DEFINE[_FIXED]_FIELDS(
459               (( <builder> )( <name>, <type> ))
460               ...
461           )
462         \endcode
463         
464         For each field, this command will define
465         \li A method \a name() returning an instance of the \a type parser
466         \li \a name<tt>_t</tt> as a typedef for \a type, the fields value
467         \li \a name<tt>_offset</tt> to give the offset of the field from the beginning of the
468             parser. If the parser is a fixed size parser, this will be a static constant, otherwise
469             it will be a method.
470
471         The \a builder argument selects, how the field is defined
472         \li <tt>Field</tt> defines a field and increments the current position by the size of the
473             field
474         \li <tt>OverlayField</tt> defines a field like <tt>Field</tt> but does \e not increment the
475             position. In the above example, this is used to overlay the different bitfield parsers:
476             All overlaying bitfield parser except the last one (the one with the highest bit
477             numbers) is marked as OverlayField.
478
479         The \a name argument defines the name of the accessor method.
480
481         The \a type argument is the parser to return for that field. Since none of the arguments may
482         contain a comma, <em>This argument cannot be a multi-parameter template</em>. Always use
483         typedefs to access templated parsers as shown above.
484
485         The \ref SENF_PACKET_PARSER_INIT macro defines the constructor and the \c init() member. If
486         you want to provide your own \c init() implementation, use \ref
487         SENF_PACKET_PARSER_NO_INIT. The first statement in your init method should probably to call
488         \c defaultInit(). This will call the \c init() member of all the fields. Afterwards you can
489         set up the field values as needed:
490         \code
491           struct SomePacket : public senf::PacketParserBase
492           {
493               SENF_PACKET_PARSER_NO_INIT(SomePacket);
494         
495               typedef senf::Parse_UInt8 Parse_Type;
496               typedef senf::Parse_Vector< senf::Parse_UInt32,
497                                           senf::SimpleVectorSizer<senf::Parse_UInt16>
498                                         > Parse_Elements;
499
500               SENF_PACKET_PARSER_DEFINE_FIELDS(
501                   ((Field)( type,     Parse_Type     ))
502                   ((Field)( elements, Parse_Elements ))
503               );
504
505               void init() const {
506                   defaultInit();
507                   type() = 0x01;
508                   elements().push_back(0x01020304u);
509               }
510           }
511         \endcode
512         
513         \ingroup packetparser
514      */
515
516     /** \brief Define initialization members of a parser
517         
518         This macro defines the packet parser constructor and the \c init() member. \c init() is
519         defined to just call \c defaultInit() which is defined by the other macros to call \c init()
520         on each of the parsers fields.
521
522         \ingroup packetparsermacros
523         \hideinitializer
524      */
525 #   define SENF_PACKET_PARSER_INIT(name)                                                          \
526     name(data_iterator i, state_type s) : senf::PacketParserBase(i,s) {}                          \
527     void init() const { defaultInit(); }
528
529     /** \brief Define initialization members of a parser except init()
530         
531         This macro is like SENF_PACKET_PARSER_INIT but does \e not define \c init(). This allows you
532         to provide your own implementation. You should call \c defaultInit() first before
533         initializing your data fields.
534
535         \ingroup packetparsermacros
536         \hideinitializer
537      */
538 #   define SENF_PACKET_PARSER_NO_INIT(name)                                                       \
539     name(data_iterator i, state_type s) : senf::PacketParserBase(i,s) {}
540
541     /** \brief Define fields for a dynamically sized parser
542
543         Define the fields as specified in \a fields. This macro supports dynamically sized
544         subfields, the resulting parser will be dynamically sized.
545
546         \ingroup packetparsermacros
547         \hideinitializer
548      */
549 #   define SENF_PACKET_PARSER_DEFINE_FIELDS(fields)                                               \
550     SENF_PACKET_PARSER_I_DEFINE_FIELDS(0,fields)
551         
552     /** \brief Define fields for a dynamically sized parser (with offset)
553
554         Define the fields as specified in \a fields. This macro supports dynamically sized
555         subfields, the resulting parser will be dynamically sized.
556
557         The \a offset argument gives the byte offset at which to start parsing the fields. This
558         helps defining extended parser deriving from a base parser:
559         \code
560            struct ExtendedParser : public BaseParser
561            {
562                ExtendedParser(data_iterator i, state_type s) : BaseParser(i,s) {}
563         
564                SENF_PACKET_PARSER_DEFINE_FIELDS_OFFSET(senf::bytes(BaseParser(*this)),
565                  ( ... fields ... ) );
566
567                void init() {
568                    BaseParser::init();
569                    defaultInit();
570                    // other init code
571                }
572            }
573         \endcode
574
575         \ingroup packetparsermacros
576         \hideinitializer
577      */
578 #   define SENF_PACKET_PARSER_DEFINE_FIELDS_OFFSET(offset,fields)                                 \
579     SENF_PACKET_PARSER_I_DEFINE_FIELDS(offset,fields)
580
581     /** \brief Define fields for a fixed size parser
582
583         Define the fields as specified in \a fields. This macro only supports fixed size
584         subfields, the resulting parser will also be a fixed size parser.
585
586         \ingroup packetparsermacros
587         \hideinitializer
588      */
589 #   define SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS(fields)                                         \
590     SENF_PACKET_PARSER_I_DEFINE_FIXED_FIELDS(0,fields)
591
592     /** \brief Define fields for a fixed size parser
593
594         Define the fields as specified in \a fields. This macro only supports fixed size
595         subfields, the resulting parser will also be a fixed size parser.
596
597         The \a offset argument gives the byte offset at which to start parsing the fields. This
598         helps defining extended parser deriving from a base parser:
599         \code
600            struct ExtendedParser : public BaseParser
601            {
602                ExtendedParser(data_iterator i, state_type s) : BaseParser(i,s) {}
603
604                SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS_OFFSET(BaseParser::fixed_bytes,
605                  ( ... fields ... ) );
606
607                void init() {
608                    BaseParser::init();
609                    defaultInit();
610                    // other init code
611                }
612            }
613         \endcode
614
615         \ingroup packetparsermacros
616         \hideinitializer
617      */
618 #   define SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS_OFFSET(offset,fields)                           \
619     SENF_PACKET_PARSER_I_DEFINE_FIXED_FIELDS(offset,fields)
620
621     /** \brief Default parser parsing nothing
622      */
623     struct VoidPacketParser 
624         : public PacketParserBase
625     {
626         SENF_PACKET_PARSER_INIT(VoidPacketParser);
627     };
628
629     /** \brief Iterator re-validating Parser wrapper
630
631         An ordinary parser will be invalidated whenever the raw data container's size is
632         changed. This can complicate some algorithms considerably.
633
634         This wrapper will update the parsers iterator (the value returned by the i() member) on
635         every access. This ensures that the iterator will stay valid.
636
637         \attention Beware however, if you insert or remove data before the safe wrapper, the
638             location will \e not be updated accordingly and therefore the parser will be
639             invalid.
640
641         Additionally a SafePacketParser has an uninitialized state. The only allowed operations in
642         this state are the boolean test for validity and assigning another parser.
643
644         \ingroup packetparser
645       */
646     template <class Parser>
647     class SafePacketParser
648         : public SafeBool< SafePacketParser<Parser> >
649     {
650     public:
651         ///////////////////////////////////////////////////////////////////////////
652         // Types
653
654         ///////////////////////////////////////////////////////////////////////////
655         ///\name Structors and default members
656         ///@{
657
658         // default copy constructor
659         // default copy assignment
660         // default destructor
661         SafePacketParser();             ///< Create an empty uninitialized SafePacketParser
662
663         // conversion constructors
664         SafePacketParser(Parser parser); ///< Initialize SafePacketParser from \a parser
665
666         SafePacketParser & operator=(Parser parser); ///< Assign \a parser to \c this
667
668         ///@}
669         ///////////////////////////////////////////////////////////////////////////
670
671         Parser operator*() const;       ///< Access the stored parser
672                                         /**< On every access, the stored parsers iterator will be
673                                              updated / re-validated. */
674         Parser const * operator->() const; ///< Access the stored parser
675                                         /**< On every access, the stored parsers iterator will be
676                                              updated / re-validated. */
677         bool boolean_test() const;      ///< Check validity
678
679     protected:
680
681     private:
682         mutable boost::optional<Parser> parser_;
683         senf::safe_data_iterator i_;
684     };
685
686 }
687
688 ///////////////////////////////hh.e////////////////////////////////////////
689 #endif
690 #if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketParser_i_)
691 #define HH_PacketParser_i_
692 #include "PacketParser.cci"
693 #include "PacketParser.ct"
694 #include "PacketParser.cti"
695 #endif
696
697 \f
698 // Local Variables:
699 // mode: c++
700 // fill-column: 100
701 // c-file-style: "senf"
702 // indent-tabs-mode: nil
703 // ispell-local-dictionary: "american"
704 // compile-command: "scons -u test"
705 // comment-column: 40
706 // End:
707