Packets: Small bugfix to parser macros
[senf.git] / Packets / ParseHelpers.ih
1 # // Copyright (C) 2007
2 # // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 # // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 # //     Stefan Bund <g0dil@berlios.de>
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 ParseHelpers internal header */
23 #
24 # if !defined(IH_ParseHelpers_)
25 # define IH_ParseHelpers_ 1
26 #
27 # // Custom includes
28 # include <boost/preprocessor/cat.hpp>
29 # include "../Utils/mpl.hh"
30 #
31 # ////////////////////////////////ih.p///////////////////////////////////////
32 #
33 # ///////////////////////////////////////////////////////////////////////////
34 # // SENF_PARSER_INITIALIZE
35 #
36 # define SENF_PARSER_INITIALIZE  BOOST_PP_CAT( SENF_PARSER_INITIALIZE_ , SENF_PARSER_TYPE )
37 #
38 # define SENF_PARSER_INITIALIZE_fix()                                                             \
39     private:                                                                                      \
40         SENF_MPL_SLOT_DEF_ZERO(index);                                                            \
41         SENF_MPL_SLOT_DEF_ZERO(offset);                                                           \
42         SENF_MPL_SLOT_DEF_ZERO(bit);                                                              \
43         SENF_MPL_SLOT_DEF_ZERO(bitfield_size);                                                    \
44         void init_chain(senf::mpl::rv<0>*) {}                                                     \
45     public:
46 #
47 # define SENF_PARSER_INITIALIZE_var()                                                             \
48     private:                                                                                      \
49         SENF_MPL_SLOT_DEF_ZERO(index);                                                            \
50         SENF_MPL_SLOT_DEF_ZERO(init_bytes);                                                       \
51         SENF_MPL_SLOT_DEF_ZERO(bit);                                                              \
52         SENF_MPL_SLOT_DEF_ZERO(bitfield_size);                                                    \
53         void init_chain(senf::mpl::rv<0>*) {}                                                     \
54         size_type field_offset_(senf::mpl::rv<0>*) const { return 0; }                            \
55     public:
56 #
57 # ///////////////////////////////////////////////////////////////////////////
58 # // SENF_PARSER_INHERIT_*
59 #
60 # define SENF_PARSER_INHERIT_var(name)                                                            \
61         typedef name parser_base_type;                                                            \
62     private:                                                                                      \
63         SENF_MPL_SLOT_SET(index, 1);                                                              \
64         SENF_MPL_SLOT_SET(init_bytes, senf::init_bytes<name>::value);                             \
65         size_type field_offset_(senf::mpl::rv<1>*) const {                                        \
66             return senf::bytes( *static_cast<name const*>(this) );                                \
67         }                                                                                         \
68         void init_chain(senf::mpl::rv<1>*) {                                                      \
69             name::init();                                                                         \
70         }                                                                                         \
71     public:
72 #
73 # define SENF_PARSER_INHERIT_fix(name)                                                            \
74         typedef name parser_base_type;                                                            \
75     private:                                                                                      \
76         SENF_MPL_SLOT_SET(offset, name::fixed_bytes);                                             \
77         SENF_MPL_SLOT_SET(index, 1);                                                              \
78         void init_chain(senf::mpl::rv<1>*) {                                                      \
79             name::init();                                                                         \
80         }                                                                                         \
81     public:
82 #
83 # ///////////////////////////////////////////////////////////////////////////
84 # // SENF_PARSER_FIELD*
85 # // SENF_PARSER_P_FIELD_*
86 #
87 # define SENF_PARSER_FIELD_var(name, type)    SENF_PARSER_FIELD_I(name, type, var, rw, public)
88 # define SENF_PARSER_FIELD_RO_var(name, type) SENF_PARSER_FIELD_I(name, type, var, ro, public)
89 # define SENF_PARSER_FIELD_fix(name, type)    SENF_PARSER_FIELD_I(name, type, fix, rw, public)
90 # define SENF_PARSER_FIELD_RO_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, ro, public)
91 #
92 # define SENF_PARSER_P_FIELD_var(name, type)    SENF_PARSER_FIELD_I(name, type, var, rw, private)
93 # define SENF_PARSER_P_FIELD_RO_var(name, type) SENF_PARSER_FIELD_I(name, type, var, ro, private)
94 # define SENF_PARSER_P_FIELD_fix(name, type)    SENF_PARSER_FIELD_I(name, type, fix, rw, private)
95 # define SENF_PARSER_P_FIELD_RO_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, ro, private)
96 #
97 # define SENF_PARSER_FIELD_I(name, type, ofstype, rwtype, access)                                 \
98     access:                                                                                       \
99         SENF_PARSER_I_BITFIELD_RESET()                                                            \
100         SENF_PARSER_I_FIELD_INTRO(name, type, access)                                             \
101         BOOST_PP_CAT(SENF_PARSER_I_FIELD_INIT_, rwtype) (name, type, access)                      \
102         BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                      \
103         BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (                                       \
104             name, type,                                                                           \
105             BOOST_PP_CAT(SENF_PARSER_I_SIZE_, ofstype) (name, type),                              \
106             BOOST_PP_CAT(SENF_PARSER_I_INITBYTES_, ofstype) (name, type),                         \
107             access )                                                                              \
108         BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access)                       \
109     public:
110 #
111 # ////////////////////////////////////////
112 # // SENF_PARSER_I_FIELD_INTRO
113 #
114 # define SENF_PARSER_I_FIELD_INTRO(name, type, access)                                            \
115         typedef type BOOST_PP_CAT(name, _t);                                                      \
116         static size_type const BOOST_PP_CAT(name,_index) = SENF_MPL_SLOT_GET(index)+1;            \
117     private:                                                                                      \
118         SENF_MPL_SLOT_SET(index, BOOST_PP_CAT(name,_index));                                      \
119     access:
120 #
121 # ////////////////////////////////////////
122 # // SENF_PARSER_I_FIELD_INIT_*
123 #
124 # define SENF_PARSER_I_FIELD_INIT_rw(name, type, access)                                                  \
125     private:                                                                                      \
126         void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) {                              \
127             init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));              \
128             name().init();                                                                        \
129         }                                                                                         \
130     access:
131 #
132 # define SENF_PARSER_I_FIELD_INIT_ro(name, type, access)                                                  \
133     private:                                                                                      \
134         void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) {                              \
135             init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));              \
136         }                                                                                         \
137     access:
138 #
139 # ////////////////////////////////////////
140 # // SENF_PARSER_I_FIELD_OFS_*
141 #
142 # define SENF_PARSER_I_FIELD_OFS_var(name, type, access)                                          \
143         size_type BOOST_PP_CAT(name,_offset)() const {                                            \
144             return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0));    \
145         }
146 #
147 # define SENF_PARSER_I_FIELD_OFS_fix(name, type, access)                                          \
148         static size_type const BOOST_PP_CAT(name, _offset) = SENF_MPL_SLOT_GET(offset);
149 #
150 # ////////////////////////////////////////
151 # // SENF_PARSER_I_ADVANCE_OFS_*
152 #
153 # // Can't call 'name()' here if 'name' is an ro field ...
154 # define SENF_PARSER_I_SIZE_var(name, type) senf::bytes(parse<type>(BOOST_PP_CAT(name,_offset)()))
155 # define SENF_PARSER_I_INITBYTES_var(name, type) senf::init_bytes<type>::value
156 #
157 # define SENF_PARSER_I_SIZE_fix(name, type) type::fixed_bytes
158 # define SENF_PARSER_I_INITBYTES_fix(name, type) void
159 #
160 # define SENF_PARSER_I_ADVANCE_OFS_var(name, type, size, isize, access)                           \
161         size_type BOOST_PP_CAT(name, _next_offset)() const {                                      \
162             return BOOST_PP_CAT(name,_offset)() + size;                                           \
163         }                                                                                         \
164         static size_type const BOOST_PP_CAT(name, _init_bytes) = SENF_MPL_SLOT_GET(init_bytes);   \
165         static size_type const BOOST_PP_CAT(name, _next_init_bytes) =                             \
166             BOOST_PP_CAT(name, _init_bytes) + isize;                                              \
167     private:                                                                                      \
168         size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {                \
169             return BOOST_PP_CAT(name, _next_offset)();                                            \
170         }                                                                                         \
171         SENF_MPL_SLOT_SET(init_bytes, BOOST_PP_CAT(name,_next_init_bytes));                       \
172     access:
173 #
174 # define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize, access)                           \
175         static size_type const BOOST_PP_CAT(name, _next_offset) =                                 \
176             BOOST_PP_CAT(name, _offset) + size;                                                   \
177     private:                                                                                      \
178         SENF_MPL_SLOT_SET(offset, BOOST_PP_CAT(name, _next_offset));                              \
179     access:
180 #
181 # ////////////////////////////////////////
182 # // SENF_PARSER_I_FIELD_VAL_*
183 #
184 # define SENF_PARSER_I_FIELD_VAL_rw(name, type, access)                                           \
185         BOOST_PP_CAT(name, _t) name() const {                                                     \
186             return parse<type>( SENF_PARSER_OFFSET(name) );                                       \
187         }
188 #
189 # define SENF_PARSER_I_FIELD_VAL_ro(name, type, access)                                           \
190         BOOST_PP_CAT(name, _t)::value_type name() const {                                         \
191             return parse<type>( SENF_PARSER_OFFSET(name) ).value();                               \
192         }
193 #
194 # ///////////////////////////////////////////////////////////////////////////
195 # // SENF_PARSER_CUSTOM_FIELD_*
196 #
197 # define SENF_PARSER_CUSTOM_FIELD_var(name, type, size, isize)                                     \
198       SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, var)
199 # define SENF_PARSER_CUSTOM_FIELD_fix(name, type, size)                                            \
200       SENF_PARSER_CUSTOM_FIELD_I(name, type, size, size, fix)
201 #
202 # define SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, ofstype)                             \
203         SENF_PARSER_I_BITFIELD_RESET()                                                            \
204         SENF_PARSER_I_FIELD_INTRO(name, type, public)                                             \
205         SENF_PARSER_I_FIELD_INIT_ro(name, type, public)                                           \
206         BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, public)                      \
207         BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize, public)       \
208         BOOST_PP_CAT(name, _t) name() const
209 #
210 # ///////////////////////////////////////////////////////////////////////////
211 # // SENF_PARSER_BITFIELD_*
212 # // SENF_PARSER_P_BITFIELD_*
213 #
214 # define SENF_PARSER_BITFIELD_var(name, bits, type)                                                \
215       SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, public)
216 # define SENF_PARSER_BITFIELD_RO_var(name, bits, type)                                             \
217       SENF_PARSER_BITFIELD_I(name, bits, type, var, ro, public)
218 # define SENF_PARSER_BITFIELD_fix(name, bits, type)                                                \
219       SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, public)
220 # define SENF_PARSER_BITFIELD_RO_fix(name, bits, type)                                             \
221       SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro, public)
222 #
223 # define SENF_PARSER_P_BITFIELD_var(name, bits, type)                                              \
224       SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, private)
225 # define SENF_PARSER_P_BITFIELD_RO_var(name, bits, type)                                           \
226       SENF_PARSER_BITFIELD_I(name, bits, type, var, ro, private)
227 # define SENF_PARSER_P_BITFIELD_fix(name, bits, type)                                              \
228       SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, private)
229 # define SENF_PARSER_P_BITFIELD_RO_fix(name, bits, type)                                           \
230       SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro, private)
231 #
232 # ////////////////////////////////////////
233 # // SENF_PARSER_BITFIELD_I
234 #
235 # define SENF_PARSER_BITFIELD_TYPE_signed(start, bits)   senf::Parse_IntField<start, start+bits>
236 # define SENF_PARSER_BITFIELD_TYPE_unsigned(start, bits) senf::Parse_UIntField<start, start+bits>
237 # define SENF_PARSER_BITFIELD_TYPE_bool(start, bits)     senf::Parse_Flag<start>
238 #
239 # define SENF_PARSER_BITFIELD_I(name, bits, type, ofstype, rwtype, access)                        \
240     access:                                                                                       \
241         static size_type const BOOST_PP_CAT(name, _bit) = SENF_MPL_SLOT_GET(bit);                 \
242     private:                                                                                      \
243         SENF_MPL_SLOT_SET(bit, BOOST_PP_CAT(name, _bit) + bits);                                  \
244         typedef BOOST_PP_CAT(SENF_PARSER_BITFIELD_TYPE_, type)( BOOST_PP_CAT(name, _bit), bits )  \
245              BOOST_PP_CAT(name,_bit_t );                                                          \
246     access:                                                                                       \
247         SENF_PARSER_BITFIELD_II( name, bits, BOOST_PP_CAT(name, _bit_t), ofstype, rwtype, access) \
248     public:
249 #
250 # define SENF_PARSER_BITFIELD_II(name, bits, type, ofstype, rwtype, access)                       \
251          SENF_PARSER_I_FIELD_INTRO(name, type, access)                                            \
252          SENF_PARSER_I_FIELD_INIT_ro(name, type, access)                                          \
253          BOOST_PP_CAT(SENF_PARSER_I_BITFIELD_OFS_, ofstype) (name, type, access)                  \
254          BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (                                      \
255              name, type,                                                                          \
256              BOOST_PP_CAT(name, _t)::fixed_bytes, BOOST_PP_CAT(name, _t)::fixed_bytes,            \
257              access)                                                                              \
258     private:                                                                                      \
259          SENF_MPL_SLOT_SET(bitfield_size, BOOST_PP_CAT(name, _t)::fixed_bytes);                   \
260     access:                                                                                       \
261          BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access)                      \
262     public:
263 #
264 # ////////////////////////////////////////
265 # // SENF_PARSER_I_BITFIELD_OFS_*
266 #
267 # define SENF_PARSER_I_BITFIELD_OFS_var(name, type, access)                                       \
268         size_type BOOST_PP_CAT(name,_offset)() const {                                            \
269             return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0))     \
270                 - SENF_MPL_SLOT_GET(bitfield_size);                                               \
271         }
272 #
273 # define SENF_PARSER_I_BITFIELD_OFS_fix(name, type, access)                                       \
274         static size_type const BOOST_PP_CAT(name, _offset) = SENF_MPL_SLOT_GET(offset)            \
275             - SENF_MPL_SLOT_GET(bitfield_size);
276 #
277 # ////////////////////////////////////////
278 # // SENF_PARSER_I_BITFIELD_RESET
279 #
280 # define SENF_PARSER_I_BITFIELD_RESET()                                                           \
281         SENF_MPL_SLOT_SET(bit, 0);                                                                \
282         SENF_MPL_SLOT_SET(bitfield_size, 0);
283 #
284 # ///////////////////////////////////////////////////////////////////////////
285 # // SENF_PARSER_SKIP_*
286 #
287 # define SENF_PARSER_SKIP_var(bytes, ibytes)                                                      \
288       SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, ibytes, var)
289 #
290 # define SENF_PARSER_SKIP_fix(bytes)                                                              \
291       SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, bytes, fix)
292 #
293 # define SENF_PARSER_I_SKIP(name, bytes, ibytes, ofstype)                                         \
294     private:                                                                                      \
295           SENF_PARSER_I_BITFIELD_RESET()                                                          \
296           SENF_PARSER_I_FIELD_INTRO(name, void, private)                                          \
297           SENF_PARSER_I_FIELD_INIT_ro(name, void, private)                                        \
298           BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                    \
299           BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, bytes, ibytes, private)  \
300     public:
301 #
302 # ///////////////////////////////////////////////////////////////////////////
303 # // SENF_PARSER_SKIP_BITS_*
304 #
305 # define SENF_PARSER_SKIP_BITS_var(bits) SENF_PARSER_I_SKIP_BITS(bits, var)
306 # define SENF_PARSER_SKIP_BITS_fix(bits) SENF_PARSER_I_SKIP_BITS(bits, fix)
307 #
308 # define SENF_PARSER_I_SKIP_BITS(bits, ofstype)                                                   \
309       SENF_MPL_SLOT_SET(bit, SENF_MPL_SLOT_GET(bit) + bits)
310 #
311 # ///////////////////////////////////////////////////////////////////////////
312 # // SENF_PARSER_GOTO_*
313 #
314 # define SENF_PARSER_GOTO_var(name)                                                               \
315       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__),                                     \
316                           BOOST_PP_CAT(name, _offset)(),                                          \
317                           BOOST_PP_CAT(name, _init_bytes),                                        \
318                           var )
319 #
320 # define SENF_PARSER_GOTO_fix(name)                                                               \
321       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__),                                     \
322                           BOOST_PP_CAT(name, _offset),                                            \
323                           BOOST_PP_CAT(name, _offset),                                            \
324                           fix )
325 #
326 # define SENF_PARSER_GOTO_OFFSET_var(offset, isize)                                               \
327       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, isize, var )
328 #
329 # define SENF_PARSER_GOTO_OFFSET_fix(offset)                                                      \
330       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, offset, fix )
331 #
332 # define SENF_PARSER_I_GOTO(name, offset, initsize, ofstype)                                      \
333       private:                                                                                    \
334           SENF_PARSER_I_BITFIELD_RESET()                                                          \
335           SENF_PARSER_I_FIELD_INTRO(name, void, private)                                          \
336           SENF_PARSER_I_FIELD_INIT_ro(name, void, private)                                        \
337           BOOST_PP_CAT( SENF_PARSER_I_GOTO_SET_OFS_, ofstype ) (name, offset, initsize)            \
338       public:
339 #
340 # define SENF_PARSER_I_GOTO_SET_OFS_var(name, offs, initsize)                                      \
341           size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {              \
342               return offs;                                                                        \
343           }                                                                                       \
344           SENF_MPL_SLOT_SET(init_bytes, initsize);
345 #
346 # define SENF_PARSER_I_GOTO_SET_OFS_fix(name, offs, initsize)                                      \
347           SENF_MPL_SLOT_SET(offset, offs);
348 #
349 # ///////////////////////////////////////////////////////////////////////////
350 # // SENF_PARSER_LABEL_*
351 #
352 # define SENF_PARSER_LABEL_var(name) SENF_PARSER_I_LABEL( name, var, public )
353 # define SENF_PARSER_LABEL_fix(name) SENF_PARSER_I_LABEL( name, fix, public )
354 #
355 # define SENF_PARSER_I_LABEL(name, ofstype, access)                                               \
356       access:                                                                                     \
357           SENF_PARSER_I_BITFIELD_RESET()                                                          \
358           SENF_PARSER_I_FIELD_INTRO(name, void, access)                                           \
359           SENF_PARSER_I_FIELD_INIT_ro(name, void, access)                                         \
360           BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                    \
361           BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, 0, 0,access)             \
362       public:
363 #
364 # ///////////////////////////////////////////////////////////////////////////
365 # // SENF_PARSER_OFFSET_*
366 #
367 # define SENF_PARSER_OFFSET_fix(name) BOOST_PP_CAT(name, _offset)
368 # define SENF_PARSER_OFFSET_var(name) BOOST_PP_CAT(name, _offset)()
369 #
370 # ///////////////////////////////////////////////////////////////////////////
371 # // SENF_PARSER_FINALIZE_*
372 #
373 # define SENF_PARSER_FINALIZE_var(name)                                                           \
374     SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
375     size_type bytes() const {                                                                     \
376         return field_offset_(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));           \
377     }                                                                                             \
378     static size_type const init_bytes = SENF_MPL_SLOT_GET(init_bytes)
379 #
380 # define SENF_PARSER_FINALIZE_fix(name)                                                           \
381     SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
382     static size_type const fixed_bytes = SENF_MPL_SLOT_GET(offset);
383 #
384 # define SENF_PARSER_FINALIZE_GENERIC(name)                                                       \
385          void defaultInit() {                                                                     \
386              init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));                \
387          }                                                                                        \
388          name(data_iterator i, state_type s) : parser_base_type(i,s) {}                           \
389     private:                                                                                      \
390          template <class T> void init(T) { defaultInit(); }                                       \
391     public:                                                                                       \
392          void init() { init(0); }
393 #
394 # ////////////////////////////////ih.e///////////////////////////////////////
395 # endif
396 #
397 #
398 # // Local Variables:
399 # // mode: c++
400 # // fill-column: 100
401 # // c-file-style: "senf"
402 # // indent-tabs-mode: nil
403 # // ispell-local-dictionary: "american"
404 # // compile-command: "scons -u test"
405 # // End: