Packets: Add parse helper SENF_PARSER_SKIP_BITS
[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, ofstype, 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_MAYBECALL_var() ()
185 # define SENF_PARSER_I_MAYBECALL_fix()
186 #
187 # define SENF_PARSER_I_FIELD_VAL_rw(name, type, ofstype, access)                                  \
188         BOOST_PP_CAT(name, _t) name() const {                                                     \
189             return parse<type>(                                                                   \
190                 BOOST_PP_CAT(name,_offset) BOOST_PP_CAT(SENF_PARSER_I_MAYBECALL_, ofstype)());    \
191         }
192 #
193 # define SENF_PARSER_I_FIELD_VAL_ro(name, type, ofstype, access)                                  \
194         BOOST_PP_CAT(name, _t)::value_type name() const {                                         \
195             return parse<type>(                                                                   \
196                 BOOST_PP_CAT(name,_offset) BOOST_PP_CAT(SENF_PARSER_I_MAYBECALL_, ofstype)())     \
197                     .value();                                                                     \
198         }
199 #
200 # ///////////////////////////////////////////////////////////////////////////
201 # // SENF_PARSER_CUSTOM_FIELD_*
202 #
203 # define SENF_PARSER_CUSTOM_FIELD_var(name, type, size, isize)                                     \
204       SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, var)
205 # define SENF_PARSER_CUSTOM_FIELD_fix(name, type, size)                                            \
206       SENF_PARSER_CUSTOM_FIELD_I(name, type, size, size, fix)
207 #
208 # define SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, ofstype)                             \
209         SENF_PARSER_I_BITFIELD_RESET()                                                            \
210         SENF_PARSER_I_FIELD_INTRO(name, type, public)                                             \
211         SENF_PARSER_I_FIELD_INIT_ro(name, type, public)                                           \
212         BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, public)                      \
213         BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize, public)       \
214         BOOST_PP_CAT(name, _t) name() const
215 #
216 # ///////////////////////////////////////////////////////////////////////////
217 # // SENF_PARSER_BITFIELD_*
218 # // SENF_PARSER_P_BITFIELD_*
219 #
220 # define SENF_PARSER_BITFIELD_var(name, bits, type)                                                \
221       SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, public)
222 # define SENF_PARSER_BITFIELD_RO_var(name, bits, type)                                             \
223       SENF_PARSER_BITFIELD_I(name, bits, type, var, ro, public)
224 # define SENF_PARSER_BITFIELD_fix(name, bits, type)                                                \
225       SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, public)
226 # define SENF_PARSER_BITFIELD_RO_fix(name, bits, type)                                             \
227       SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro, public)
228 #
229 # define SENF_PARSER_P_BITFIELD_var(name, bits, type)                                              \
230       SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, private)
231 # define SENF_PARSER_P_BITFIELD_RO_var(name, bits, type)                                           \
232       SENF_PARSER_BITFIELD_I(name, bits, type, var, ro, private)
233 # define SENF_PARSER_P_BITFIELD_fix(name, bits, type)                                              \
234       SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, private)
235 # define SENF_PARSER_P_BITFIELD_RO_fix(name, bits, type)                                           \
236       SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro, private)
237 #
238 # ////////////////////////////////////////
239 # // SENF_PARSER_BITFIELD_I
240 #
241 # define SENF_PARSER_BITFIELD_TYPE_signed(start, bits)   senf::Parse_IntField<start, start+bits>
242 # define SENF_PARSER_BITFIELD_TYPE_unsigned(start, bits) senf::Parse_UIntField<start, start+bits>
243 # define SENF_PARSER_BITFIELD_TYPE_bool(start, bits)     senf::Parse_Flag<start>
244 #
245 # define SENF_PARSER_BITFIELD_I(name, bits, type, ofstype, rwtype, access)                        \
246     access:                                                                                       \
247         static size_type const BOOST_PP_CAT(name, _bit) = SENF_MPL_SLOT_GET(bit);                 \
248     private:                                                                                      \
249         SENF_MPL_SLOT_SET(bit, BOOST_PP_CAT(name, _bit) + bits);                                  \
250         typedef BOOST_PP_CAT(SENF_PARSER_BITFIELD_TYPE_, type)( BOOST_PP_CAT(name, _bit), bits )  \
251              BOOST_PP_CAT(name,_bit_t );                                                          \
252     access:                                                                                       \
253         SENF_PARSER_BITFIELD_II( name, bits, BOOST_PP_CAT(name, _bit_t), ofstype, rwtype, access) \
254     public:
255 #
256 # define SENF_PARSER_BITFIELD_II(name, bits, type, ofstype, rwtype, access)                       \
257          SENF_PARSER_I_FIELD_INTRO(name, type, access)                                            \
258          SENF_PARSER_I_FIELD_INIT_ro(name, type, access)                                          \
259          BOOST_PP_CAT(SENF_PARSER_I_BITFIELD_OFS_, ofstype) (name, type, access)                  \
260          BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (                                      \
261              name, type,                                                                          \
262              BOOST_PP_CAT(name, _t)::fixed_bytes, BOOST_PP_CAT(name, _t)::fixed_bytes,            \
263              access)                                                                              \
264     private:                                                                                      \
265          SENF_MPL_SLOT_SET(bitfield_size, BOOST_PP_CAT(name, _t)::fixed_bytes);                   \
266     access:                                                                                       \
267          BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, ofstype, access)             \
268     public:
269 #
270 # ////////////////////////////////////////
271 # // SENF_PARSER_I_BITFIELD_OFS_*
272 #
273 # define SENF_PARSER_I_BITFIELD_OFS_var(name, type, access)                                       \
274         size_type BOOST_PP_CAT(name,_offset)() const {                                            \
275             return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0))     \
276                 - SENF_MPL_SLOT_GET(bitfield_size);                                               \
277         }
278 #
279 # define SENF_PARSER_I_BITFIELD_OFS_fix(name, type, access)                                       \
280         static size_type const BOOST_PP_CAT(name, _offset) = SENF_MPL_SLOT_GET(offset)            \
281             - SENF_MPL_SLOT_GET(bitfield_size);
282 #
283 # ////////////////////////////////////////
284 # // SENF_PARSER_I_BITFIELD_RESET
285 #
286 # define SENF_PARSER_I_BITFIELD_RESET()                                                           \
287         SENF_MPL_SLOT_SET(bit, 0);                                                                \
288         SENF_MPL_SLOT_SET(bitfield_size, 0);
289 #
290 # ///////////////////////////////////////////////////////////////////////////
291 # // SENF_PARSER_FINALIZE_*
292 #
293 # define SENF_PARSER_FINALIZE_var(name)                                                           \
294     SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
295     size_type bytes() const {                                                                     \
296         return field_offset_(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));           \
297     }                                                                                             \
298     static size_type const init_bytes = SENF_MPL_SLOT_GET(init_bytes)
299 #
300 # define SENF_PARSER_FINALIZE_fix(name)                                                           \
301     SENF_PARSER_FINALIZE_GENERIC(name)                                                            \
302     static size_type const fixed_bytes = SENF_MPL_SLOT_GET(offset);
303 #
304 # define SENF_PARSER_FINALIZE_GENERIC(name)                                                       \
305          void defaultInit() {                                                                     \
306              init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0));                \
307          }                                                                                        \
308          name(data_iterator i, state_type s) : parser_base_type(i,s) {}                           \
309     private:                                                                                      \
310          template <class T> void init(T) { defaultInit(); }                                       \
311     public:                                                                                       \
312          void init() { init(0); }
313 #
314 # ///////////////////////////////////////////////////////////////////////////
315 # // SENF_PARSER_SKIP_*
316 #
317 # define SENF_PARSER_SKIP_var(bytes, ibytes)                                                      \
318       SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, ibytes, var)
319 #
320 # define SENF_PARSER_SKIP_fix(bytes)                                                              \
321       SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, bytes, fix)
322 #
323 # define SENF_PARSER_I_SKIP(name, bytes, ibytes, ofstype)                                         \
324     private:                                                                                      \
325           SENF_PARSER_I_BITFIELD_RESET()                                                          \
326           SENF_PARSER_I_FIELD_INTRO(name, void, private)                                          \
327           SENF_PARSER_I_FIELD_INIT_ro(name, void, private)                                        \
328           BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                    \
329           BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, bytes, ibytes, private)  \
330     public:
331 #
332 # ///////////////////////////////////////////////////////////////////////////
333 # // SENF_PARSER_SKIP_BITS_*
334 #
335 # define SENF_PARSER_SKIP_BITS_var(bits) SENF_PARSER_I_SKIP_BITS(bits, var)
336 # define SENF_PARSER_SKIP_BITS_fix(bits) SENF_PARSER_I_SKIP_BITS(bits, fix)
337 #
338 # define SENF_PARSER_I_SKIP_BITS(bits, ofstype)                                                   \
339       SENF_MPL_SLOT_SET(bit, SENF_MPL_SLOT_GET(bit) + bits)
340 #
341 # ///////////////////////////////////////////////////////////////////////////
342 # // SENF_PARSER_GOTO_*
343 #
344 # define SENF_PARSER_GOTO_var(name)                                                               \
345       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__),                                     \
346                           BOOST_PP_CAT(name, _offset)(),                                          \
347                           BOOST_PP_CAT(name, _init_bytes),                                        \
348                           var )
349 #
350 # define SENF_PARSER_GOTO_fix(name)                                                               \
351       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__),                                     \
352                           BOOST_PP_CAT(name, _offset),                                            \
353                           BOOST_PP_CAT(name, _offset),                                            \
354                           fix )
355 #
356 # define SENF_PARSER_GOTO_OFFSET_var(offset, isize)                                               \
357       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, isize, var )
358 #
359 # define SENF_PARSER_GOTO_OFFSET_fix(offset)                                                      \
360       SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, offset, fix )
361 #
362 # define SENF_PARSER_I_GOTO(name, offset, initsize, ofstype)                                      \
363       private:                                                                                    \
364           SENF_PARSER_I_BITFIELD_RESET()                                                          \
365           SENF_PARSER_I_FIELD_INTRO(name, void, private)                                          \
366           SENF_PARSER_I_FIELD_INIT_ro(name, void, private)                                        \
367           BOOST_PP_CAT( SENF_PARSER_I_GOTO_SET_OFS_, ofstype ) (name, offset, initsize)            \
368       public:
369 #
370 # define SENF_PARSER_I_GOTO_SET_OFS_var(name, offs, initsize)                                      \
371           size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const {              \
372               return offs;                                                                        \
373           }                                                                                       \
374           SENF_MPL_SLOT_SET(init_bytes, initsize);
375 #
376 # define SENF_PARSER_I_GOTO_SET_OFS_fix(name, offs, initsize)                                      \
377           SENF_MPL_SLOT_SET(offset, offs);
378 #
379 # ///////////////////////////////////////////////////////////////////////////
380 # // SENF_PARSER_LABEL_*
381 #
382 # define SENF_PARSER_LABEL_var(name) SENF_PARSER_I_LABEL( name, var, public )
383 # define SENF_PARSER_LABEL_fix(name) SENF_PARSER_I_LABEL( name, fix, public )
384 #
385 # define SENF_PARSER_I_LABEL(name, ofstype, access)                                               \
386       access:                                                                                     \
387           SENF_PARSER_I_BITFIELD_RESET()                                                          \
388           SENF_PARSER_I_FIELD_INTRO(name, void, access)                                           \
389           SENF_PARSER_I_FIELD_INIT_ro(name, void, access)                                         \
390           BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access)                    \
391           BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, 0, 0,access)             \
392       public:
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: