Packets: Add parse helper SENF_PARSER_SKIP_BITS
[senf.git] / Packets / ParseHelpers.hh
1 // $Id$
2 //
3 // Copyright (C) 2007 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief ParseHelpers public header */
25
26 #ifndef HH_ParseHelpers_
27 #define HH_ParseHelpers_ 1
28
29 #ifndef HH_Packets_
30 #error "Don't include 'ParseHelpers.hh' directly, include 'Packets.hh'"
31 #endif
32
33 // Custom includes
34
35 //#include "ParseHelpers.mpp"
36 #include "ParseHelpers.ih"
37 ///////////////////////////////hh.p////////////////////////////////////////
38
39 /** \defgroup packetparsermacros Helper macros for defining new packet parsers
40
41     To simplify the definition of simple packet parsers, several macros are provided. Before
42     using these macros you should familiarize yourself with the packet parser interface as
43     described in senf::PacketParserBase.
44
45     These macros simplify providing the above defined interface. A typical packet declaration
46     using these macros has the following form (This is a concrete example from the definition of
47     the ethernet packet in <tt>DefaultBundle/EthernetPacket.hh</tt>)
48
49     \code
50     struct Parse_EthVLan : public PacketParserBase
51     {
52         typedef Parse_UIntField < 0,  3 > Parse_Priority;
53         typedef Parse_Flag          < 3 > Parse_CFI;
54         typedef Parse_UIntField < 4, 16 > Parse_VLanId;
55         typedef Parse_UInt16              Parse_Type;
56
57         SENF_PACKET_PARSER_INIT(Parse_EthVLan);
58
59         SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS(
60             ((OverlayField)( priority, Parse_Priority ))
61             ((OverlayField)( cfi,      Parse_CFI      ))
62             ((Field       )( vlanId,   Parse_VLanId   ))
63             ((Field       )( type,     Parse_Type     )) );
64     };
65     \endcode
66
67     The macros take care of the following:
68     \li They define the accessor functions returning parsers of the given type.
69     \li They automatically calculate the offset of the fields from the preceding fields.
70     \li The macros provide a definition for \c init() 
71     \li The macros define the \c bytes(), \c fixed_bytes and \c init_bytes members as needed.
72
73     You may define either a fixed or a dynamically sized parser. Fixed size parsers are defined
74     using \ref SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS, dynamically sized parsers are defined
75     using \ref SENF_PACKET_PARSER_DEFINE_FIELDS. The different members are implemented such
76     that:
77
78     \li The needed parser constructor is defined
79     \li \c init() calls \c defaultInit(). \c defaultInit() is defined to call \c init() on each
80         of the fields.
81     \li \c bytes() (on dynamically sized parser) respectively \c fixed_bytes (on fixed size
82         parsers) is defined to return the sum of the sizes of all fields.
83     \li On dynamically sized parsers, \c init_bytes is defined to return the sum of the
84         \c init_size's of all fields
85
86     The central definition macros are \ref SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS and \ref
87     SENF_PACKET_PARSER_DEFINE_FIELDS. The argument to both has the same structure. It is a
88     (boost preprocessor style) sequence of field definitions where each field definition
89     provides the builder macro to use and the name and type of the field to define:
90     \code
91       SENF_PACKET_PARSER_DEFINE[_FIXED]_FIELDS(
92           (( <builder> )( <name>, <type> ))
93           ...
94       )
95     \endcode
96
97     For each field, this command will define
98     \li A method \a name() returning an instance of the \a type parser
99     \li \a name<tt>_t</tt> as a typedef for \a type, the fields value
100     \li \a name<tt>_offset</tt> to give the offset of the field from the beginning of the
101         parser. If the parser is a fixed size parser, this will be a static constant, otherwise
102         it will be a method.
103
104     The \a builder argument selects, how the field is defined
105     \li <tt>Field</tt> defines a field and increments the current position by the size of the
106         field
107     \li <tt>OverlayField</tt> defines a field like <tt>Field</tt> but does \e not increment the
108         position. In the above example, this is used to overlay the different bitfield parsers:
109         All overlaying bitfield parser except the last one (the one with the highest bit
110         numbers) is marked as OverlayField.
111
112     The \a name argument defines the name of the accessor method.
113
114     The \a type argument is the parser to return for that field. Since none of the arguments may
115     contain a comma, <em>This argument cannot be a multi-parameter template</em>. Always use
116     typedefs to access templated parsers as shown above.
117
118     The \ref SENF_PACKET_PARSER_INIT macro defines the constructor and the \c init() member. If
119     you want to provide your own \c init() implementation, use \ref
120     SENF_PACKET_PARSER_NO_INIT. The first statement in your init method should probably to call
121     \c defaultInit(). This will call the \c init() member of all the fields. Afterwards you can
122     set up the field values as needed:
123     \code
124       struct SomePacket : public senf::PacketParserBase
125       {
126           SENF_PACKET_PARSER_NO_INIT(SomePacket);
127
128           typedef senf::Parse_UInt8 Parse_Type;
129           typedef senf::Parse_Vector< senf::Parse_UInt32,
130                                       senf::SimpleVectorSizer<senf::Parse_UInt16>
131                                     > Parse_Elements;
132
133           SENF_PACKET_PARSER_DEFINE_FIELDS(
134               ((Field)( type,     Parse_Type     ))
135               ((Field)( elements, Parse_Elements ))
136           );
137
138           void init() const {
139               defaultInit();
140               type() = 0x01;
141               elements().push_back(0x01020304u);
142           }
143       }
144     \endcode
145
146     \ingroup packetparser
147  */
148
149 #define SENF_FIXED_PARSER()     SENF_ABSOLUTE_INCLUDE_PATH(Packets/parse_fixed_setup.hh)
150 #define SENF_PARSER()           SENF_ABSOLUTE_INCLUDE_PATH(Packets/parse_setup.hh)
151
152 #define SENF_PARSER_INHERIT     BOOST_PP_CAT( SENF_PARSER_INHERIT_     , SENF_PARSER_TYPE )
153
154 #define SENF_PARSER_FIELD        BOOST_PP_CAT( SENF_PARSER_FIELD_        , SENF_PARSER_TYPE )
155 #define SENF_PARSER_FIELD_RO     BOOST_PP_CAT( SENF_PARSER_FIELD_RO_     , SENF_PARSER_TYPE )
156 #define SENF_PARSER_BITFIELD     BOOST_PP_CAT( SENF_PARSER_BITFIELD_     , SENF_PARSER_TYPE )
157 #define SENF_PARSER_BITFIELD_RO  BOOST_PP_CAT( SENF_PARSER_BITFIELD_RO_  , SENF_PARSER_TYPE )
158 #define SENF_PARSER_CUSTOM_FIELD BOOST_PP_CAT( SENF_PARSER_CUSTOM_FIELD_ , SENF_PARSER_TYPE )
159
160 #define SENF_PARSER_PRIVATE_FIELD        BOOST_PP_CAT( SENF_PARSER_P_FIELD_        , SENF_PARSER_TYPE )
161 #define SENF_PARSER_PRIVATE_FIELD_RO     BOOST_PP_CAT( SENF_PARSER_P_FIELD_RO_     , SENF_PARSER_TYPE )
162 #define SENF_PARSER_PRIVATE_BITFIELD     BOOST_PP_CAT( SENF_PARSER_P_BITFIELD_     , SENF_PARSER_TYPE )
163 #define SENF_PARSER_PRIVATE_BITFIELD_RO  BOOST_PP_CAT( SENF_PARSER_P_BITFIELD_RO_  , SENF_PARSER_TYPE )
164
165 #define SENF_PARSER_SKIP        BOOST_PP_CAT( SENF_PARSER_SKIP_        , SENF_PARSER_TYPE )
166 #define SENF_PARSER_SKIP_BITS   BOOST_PP_CAT( SENF_PARSER_SKIP_BITS_   , SENF_PARSER_TYPE )
167 #define SENF_PARSER_GOTO        BOOST_PP_CAT( SENF_PARSER_GOTO_        , SENF_PARSER_TYPE )
168 #define SENF_PARSER_GOTO_OFFSET BOOST_PP_CAT( SENF_PARSER_GOTO_OFFSET_ , SENF_PARSER_TYPE )
169 #define SENF_PARSER_LABEL       BOOST_PP_CAT( SENF_PARSER_LABEL_       , SENF_PARSER_TYPE )
170
171 #define SENF_PARSER_INIT()      void init(int)
172
173 #define SENF_PARSER_FINALIZE    BOOST_PP_CAT( SENF_PARSER_FINALIZE_    , SENF_PARSER_TYPE )
174
175 ///////////////////////////////hh.e////////////////////////////////////////
176 #endif
177 #if !defined(HH_Packets__decls_) && !defined(HH_ParseHelpers_i_)
178 #define HH_ParseHelpers_i_
179 //#include "ParseHelpers.cci"
180 //#include "ParseHelpers.ct"
181 //#include "ParseHelpers.cti"
182 #endif
183
184 \f
185 // Local Variables:
186 // mode: c++
187 // fill-column: 100
188 // comment-column: 40
189 // c-file-style: "senf"
190 // indent-tabs-mode: nil
191 // ispell-local-dictionary: "american"
192 // compile-command: "scons -u test"
193 // End: