00001 # // Copyright (C) 2007 00002 # // Fraunhofer (FOKUS) 00003 # // Competence Center NETwork research (NET), St. Augustin, GERMANY 00004 # // Stefan Bund <g0dil@berlios.de> 00005 # // 00006 # // This program is free software; you can redistribute it and/or modify 00007 # // it under the terms of the GNU General Public License as published by 00008 # // the Free Software Foundation; either version 2 of the License, or 00009 # // (at your option) any later version. 00010 # // 00011 # // This program is distributed in the hope that it will be useful, 00012 # // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 # // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 # // GNU General Public License for more details. 00015 # // 00016 # // You should have received a copy of the GNU General Public License 00017 # // along with this program; if not, write to the 00018 # // Free Software Foundation, Inc., 00019 # // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00020 # 00021 # 00023 # 00024 # if !defined(IH_ParseHelpers_) 00025 # define IH_ParseHelpers_ 1 00026 # 00027 # // Custom includes 00028 # include <boost/preprocessor/cat.hpp> 00029 # include <boost/preprocessor/if.hpp> 00030 # include <boost/preprocessor/expand.hpp> 00031 # include <boost/preprocessor/facilities/is_empty.hpp> 00032 # include <boost/preprocessor/punctuation/comma.hpp> 00033 # include "../Utils/preprocessor.hh" 00034 # include "../Utils/mpl.hh" 00035 # 00036 # //- 00037 # 00038 # //- 00039 # // SENF_PARSER_INITIALIZE 00040 # 00041 # define SENF_PARSER_INITIALIZE BOOST_PP_CAT( SENF_PARSER_INITIALIZE_ , SENF_PARSER_TYPE ) 00042 # 00043 # define SENF_PARSER_INITIALIZE_fix() \ 00044 private: \ 00045 SENF_MPL_SLOT_DEF_ZERO(index); \ 00046 SENF_MPL_SLOT_DEF_ZERO(offset); \ 00047 SENF_MPL_SLOT_DEF_ZERO(bit); \ 00048 SENF_MPL_SLOT_DEF_ZERO(bitfield_size); \ 00049 void init_chain(senf::mpl::rv<0>*) const {} \ 00050 public: 00051 # 00052 # define SENF_PARSER_INITIALIZE_var() \ 00053 private: \ 00054 SENF_MPL_SLOT_DEF_ZERO(index); \ 00055 SENF_MPL_SLOT_DEF_ZERO(init_bytes); \ 00056 SENF_MPL_SLOT_DEF_ZERO(bit); \ 00057 SENF_MPL_SLOT_DEF_ZERO(bitfield_size); \ 00058 SENF_MPL_SLOT_DEF_ZERO(group); \ 00059 void init_chain(senf::mpl::rv<0>*) const {} \ 00060 size_type field_offset_(senf::mpl::rv<0>*) const { return 0; } \ 00061 public: 00062 # 00063 # //- 00064 # // SENF_PARSER_INHERIT_* 00065 # 00066 # define SENF_PARSER_INHERIT_var(name) \ 00067 typedef name parser_base_type; \ 00068 private: \ 00069 SENF_MPL_SLOT_SET(index, 1); \ 00070 SENF_MPL_SLOT_SET(init_bytes, senf::init_bytes<name>::value); \ 00071 size_type field_offset_(senf::mpl::rv<1>*) const { \ 00072 return senf::bytes( *static_cast<name const*>(this) ); \ 00073 } \ 00074 void init_chain(senf::mpl::rv<1>*) const { \ 00075 name::init(); \ 00076 } \ 00077 public: 00078 # 00079 # define SENF_PARSER_INHERIT_fix(name) \ 00080 typedef name parser_base_type; \ 00081 private: \ 00082 SENF_MPL_SLOT_SET(offset, name::fixed_bytes); \ 00083 SENF_MPL_SLOT_SET(index, 1); \ 00084 void init_chain(senf::mpl::rv<1>*) const { \ 00085 name::init(); \ 00086 } \ 00087 public: 00088 # 00089 # //- 00090 # // SENF_PARSER_FIELD* 00091 # // SENF_PARSER_P_FIELD_* 00092 # 00093 # define SENF_PARSER_FIELD_var(name, type) SENF_PARSER_FIELD_I(name, type, var, rw, public) 00094 # define SENF_PARSER_FIELD_RO_var(name, type) SENF_PARSER_FIELD_I(name, type, var, ro, public) 00095 # define SENF_PARSER_FIELD_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, rw, public) 00096 # define SENF_PARSER_FIELD_RO_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, ro, public) 00097 # 00098 # define SENF_PARSER_P_FIELD_var(name, type) SENF_PARSER_FIELD_I(name, type, var, rw, protected) 00099 # define SENF_PARSER_P_FIELD_fix(name, type) SENF_PARSER_FIELD_I(name, type, fix, rw, protected) 00100 # 00101 # define SENF_PARSER_FIELD_I(name, type, ofstype, rwtype, access) \ 00102 access: \ 00103 SENF_PARSER_FIELD_SETUP_I(name, type, ofstype, rwtype, access) \ 00104 BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access) \ 00105 public: 00106 # 00107 # define SENF_PARSER_FIELD_SETUP_I(name, type, ofstype, rwtype, access) \ 00108 SENF_PARSER_I_BITFIELD_RESET() \ 00109 SENF_PARSER_I_FIELD_INTRO(name, type, access) \ 00110 BOOST_PP_CAT(SENF_PARSER_I_FIELD_INIT_, rwtype) (name, type, access) \ 00111 BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access) \ 00112 BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) ( \ 00113 name, type, \ 00114 BOOST_PP_CAT(SENF_PARSER_I_SIZE_, ofstype) (name, type), \ 00115 BOOST_PP_CAT(SENF_PARSER_I_INITBYTES_, ofstype) (name, type), \ 00116 BOOST_PP_CAT(SENF_PARSER_I_ISVAR_, ofstype) (name, type), \ 00117 access ) 00118 # 00119 # //- 00120 # // SENF_PARSER_I_FIELD_INTRO 00121 # 00122 # define SENF_PARSER_I_FIELD_INTRO(name, type, access) \ 00123 typedef type BOOST_PP_CAT(name, _t); \ 00124 static size_type const BOOST_PP_CAT(name,_index) = SENF_MPL_SLOT_GET(index)+1; \ 00125 private: \ 00126 SENF_MPL_SLOT_SET(index, BOOST_PP_CAT(name,_index)); \ 00127 access: 00128 # 00129 # //- 00130 # // SENF_PARSER_I_FIELD_INIT_* 00131 # 00132 # define SENF_PARSER_I_FIELD_INIT_rw(name, type, access) \ 00133 private: \ 00134 void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const { \ 00135 init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0)); \ 00136 name().init(); \ 00137 } \ 00138 access: 00139 # 00140 # define SENF_PARSER_I_FIELD_INIT_ro(name, type, access) \ 00141 private: \ 00142 void init_chain(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const { \ 00143 init_chain(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0)); \ 00144 } \ 00145 access: 00146 # 00147 # //- 00148 # // SENF_PARSER_I_FIELD_OFS_* 00149 # 00150 # define SENF_PARSER_I_FIELD_OFS_var(name, type, access) \ 00151 protected: \ 00152 size_type BOOST_PP_CAT(name,_offset)() const { \ 00153 return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0)); \ 00154 } \ 00155 static size_type const BOOST_PP_CAT(name, _init_bytes) = \ 00156 SENF_MPL_SLOT_GET(init_bytes); \ 00157 private: 00158 # 00159 # define SENF_PARSER_I_FIELD_OFS_fix(name, type, access) \ 00160 protected: \ 00161 static size_type const BOOST_PP_CAT(name, _offset) = \ 00162 SENF_MPL_SLOT_GET(offset); \ 00163 private: 00164 # 00165 # //- 00166 # // SENF_PARSER_I_ADVANCE_OFS_* 00167 # 00168 # define SENF_PARSER_I_SIZE_var(name, type) senf::bytes(BOOST_PP_CAT(name, _)()) 00169 # define SENF_PARSER_I_INITBYTES_var(name, type) senf::init_bytes<type>::value 00170 # 00171 # define SENF_PARSER_I_SIZE_fix(name, type) type::fixed_bytes 00172 # define SENF_PARSER_I_INITBYTES_fix(name, type) void 00173 # 00174 # define SENF_PARSER_I_ISVAR_fix(name, type) 0 00175 # define SENF_PARSER_I_ISVAR_var(name, type) (senf::is_fixed<type>::value?0:1) 00176 # 00177 # define SENF_PARSER_I_ADVANCE_OFS_var(name, type, size, isize, isvar, access) \ 00178 size_type BOOST_PP_CAT(name, _next_offset)() const { \ 00179 return BOOST_PP_CAT(name,_offset)() + size; \ 00180 } \ 00181 static size_type const BOOST_PP_CAT(name, _next_init_bytes) = \ 00182 BOOST_PP_CAT(name, _init_bytes) + isize; \ 00183 private: \ 00184 size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const { \ 00185 return BOOST_PP_CAT(name, _next_offset)(); \ 00186 } \ 00187 SENF_MPL_SLOT_SET(init_bytes, BOOST_PP_CAT(name,_next_init_bytes)); \ 00188 protected: \ 00189 static size_type const BOOST_PP_CAT(name, _group) = SENF_MPL_SLOT_GET(group) + isvar; \ 00190 private: \ 00191 SENF_MPL_SLOT_SET(group, BOOST_PP_CAT(name, _group)); \ 00192 access: 00193 # 00194 # define SENF_PARSER_I_ADVANCE_OFS_fix(name, type, size, isize, isvar, access) \ 00195 static size_type const BOOST_PP_CAT(name, _next_offset) = \ 00196 BOOST_PP_CAT(name, _offset) + size; \ 00197 private: \ 00198 SENF_MPL_SLOT_SET(offset, BOOST_PP_CAT(name, _next_offset)); \ 00199 access: 00200 # 00201 # //- 00202 # // SENF_PARSER_I_FIELD_VAL_* 00203 # 00204 # define SENF_PARSER_I_FIELD_VAL_rw(name, type, access) \ 00205 protected: \ 00206 BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const { \ 00207 return parse<type>( SENF_PARSER_OFFSET(name) ); \ 00208 } \ 00209 access: \ 00210 BOOST_PP_CAT(name, _t) name() const { \ 00211 return BOOST_PP_CAT(name,_)(); \ 00212 } 00213 # 00214 # define SENF_PARSER_I_FIELD_VAL_ro(name, type, access) \ 00215 protected: \ 00216 BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const { \ 00217 return parse<type>( SENF_PARSER_OFFSET(name) ); \ 00218 } \ 00219 access: \ 00220 BOOST_PP_CAT(name, _t)::value_type name() const { \ 00221 return BOOST_PP_CAT(name,_)(); \ 00222 } 00223 # 00224 # //- 00225 # // SENF_PARSER_CUSTOM_FIELD_* 00226 # 00227 # define SENF_PARSER_CUSTOM_FIELD_var(name, type, size, isize) \ 00228 SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, var) 00229 # define SENF_PARSER_CUSTOM_FIELD_fix(name, type, size) \ 00230 SENF_PARSER_CUSTOM_FIELD_I(name, type, size, size, fix) 00231 # 00232 # define SENF_PARSER_CUSTOM_FIELD_I(name, type, size, isize, ofstype) \ 00233 SENF_PARSER_I_BITFIELD_RESET() \ 00234 SENF_PARSER_I_FIELD_INTRO(name, type, public) \ 00235 SENF_PARSER_I_FIELD_INIT_ro(name, type, public) \ 00236 BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, public) \ 00237 BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, type, size, isize, 1, public) \ 00238 BOOST_PP_CAT(name, _t) name() const 00239 # 00240 # //- 00241 # // SENF_PARSER_BITFIELD_* 00242 # // SENF_PARSER_P_BITFIELD_* 00243 # 00244 # define SENF_PARSER_BITFIELD_var(name, bits, type) \ 00245 SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, public) 00246 # define SENF_PARSER_BITFIELD_RO_var(name, bits, type) \ 00247 SENF_PARSER_BITFIELD_I(name, bits, type, var, ro, public) 00248 # define SENF_PARSER_BITFIELD_fix(name, bits, type) \ 00249 SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, public) 00250 # define SENF_PARSER_BITFIELD_RO_fix(name, bits, type) \ 00251 SENF_PARSER_BITFIELD_I(name, bits, type, fix, ro, public) 00252 # 00253 # define SENF_PARSER_P_BITFIELD_var(name, bits, type) \ 00254 SENF_PARSER_BITFIELD_I(name, bits, type, var, rw, protected) 00255 # define SENF_PARSER_P_BITFIELD_fix(name, bits, type) \ 00256 SENF_PARSER_BITFIELD_I(name, bits, type, fix, rw, protected) 00257 # 00258 # //- 00259 # // SENF_PARSER_BITFIELD_I 00260 # 00261 # define SENF_PARSER_BITFIELD_TYPE_signed(start, bits) senf::IntFieldParser<start, start+bits> 00262 # define SENF_PARSER_BITFIELD_TYPE_unsigned(start, bits) senf::UIntFieldParser<start, start+bits> 00263 # define SENF_PARSER_BITFIELD_TYPE_bool(start, bits) senf::FlagParser<start> 00264 # 00265 # define SENF_PARSER_BITFIELD_I(name, bits, type, ofstype, rwtype, access) \ 00266 access: \ 00267 static size_type const BOOST_PP_CAT(name, _bit) = SENF_MPL_SLOT_GET(bit); \ 00268 private: \ 00269 SENF_MPL_SLOT_SET(bit, BOOST_PP_CAT(name, _bit) + bits); \ 00270 typedef BOOST_PP_CAT(SENF_PARSER_BITFIELD_TYPE_, type)( BOOST_PP_CAT(name, _bit), bits ) \ 00271 BOOST_PP_CAT(name,_bit_t ); \ 00272 access: \ 00273 SENF_PARSER_BITFIELD_II( name, bits, BOOST_PP_CAT(name, _bit_t), ofstype, rwtype, access) \ 00274 public: 00275 # 00276 # define SENF_PARSER_BITFIELD_II(name, bits, type, ofstype, rwtype, access) \ 00277 SENF_PARSER_I_FIELD_INTRO(name, type, access) \ 00278 SENF_PARSER_I_FIELD_INIT_ro(name, type, access) \ 00279 BOOST_PP_CAT(SENF_PARSER_I_BITFIELD_OFS_, ofstype) (name, type, access) \ 00280 BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) ( \ 00281 name, type, \ 00282 BOOST_PP_CAT(name, _t)::fixed_bytes, BOOST_PP_CAT(name, _t)::fixed_bytes, \ 00283 0, \ 00284 access) \ 00285 private: \ 00286 SENF_MPL_SLOT_SET(bitfield_size, BOOST_PP_CAT(name, _t)::fixed_bytes); \ 00287 access: \ 00288 BOOST_PP_CAT(SENF_PARSER_I_FIELD_VAL_, rwtype) (name, type, access) \ 00289 public: 00290 # 00291 # //- 00292 # // SENF_PARSER_I_BITFIELD_OFS_* 00293 # 00294 # define SENF_PARSER_I_BITFIELD_OFS_var(name, type, access) \ 00295 size_type BOOST_PP_CAT(name,_offset)() const { \ 00296 return field_offset_(static_cast<senf::mpl::rv<BOOST_PP_CAT(name,_index)-1>*>(0)) \ 00297 - SENF_MPL_SLOT_GET(bitfield_size); \ 00298 } \ 00299 static size_type const BOOST_PP_CAT(name, _init_bytes) = \ 00300 SENF_MPL_SLOT_GET(init_bytes) - SENF_MPL_SLOT_GET(bitfield_size); 00301 # 00302 # define SENF_PARSER_I_BITFIELD_OFS_fix(name, type, access) \ 00303 static size_type const BOOST_PP_CAT(name, _offset) = \ 00304 SENF_MPL_SLOT_GET(offset) - SENF_MPL_SLOT_GET(bitfield_size); 00305 # 00306 # //- 00307 # // SENF_PARSER_I_BITFIELD_RESET 00308 # 00309 # define SENF_PARSER_I_BITFIELD_RESET() \ 00310 SENF_MPL_SLOT_SET(bit, 0); \ 00311 SENF_MPL_SLOT_SET(bitfield_size, 0); 00312 # 00313 # //- 00314 # // SENF_PARSER_SKIP_* 00315 # 00316 # define SENF_PARSER_SKIP_var(bytes, ibytes) \ 00317 SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, ibytes, var) 00318 # 00319 # define SENF_PARSER_SKIP_fix(bytes) \ 00320 SENF_PARSER_I_SKIP( BOOST_PP_CAT(senf_anon_, __LINE__), bytes, bytes, fix) 00321 # 00322 # define SENF_PARSER_I_SKIP(name, bytes, ibytes, ofstype) \ 00323 private: \ 00324 SENF_PARSER_I_BITFIELD_RESET() \ 00325 SENF_PARSER_I_FIELD_INTRO(name, void, private) \ 00326 SENF_PARSER_I_FIELD_INIT_ro(name, void, private) \ 00327 BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access) \ 00328 BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, bytes, ibytes, 1, \ 00329 private) \ 00330 public: 00331 # 00332 # //- 00333 # // SENF_PARSER_SKIP_BITS_* 00334 # 00335 # define SENF_PARSER_SKIP_BITS_var(bits) SENF_PARSER_I_SKIP_BITS(bits, var) 00336 # define SENF_PARSER_SKIP_BITS_fix(bits) SENF_PARSER_I_SKIP_BITS(bits, fix) 00337 # 00338 # define SENF_PARSER_I_SKIP_BITS(bits, ofstype) \ 00339 private: \ 00340 SENF_MPL_SLOT_SET(bit, SENF_MPL_SLOT_GET(bit) + bits); \ 00341 public: 00342 # 00343 # //- 00344 # // SENF_PARSER_GOTO_* 00345 # 00346 # define SENF_PARSER_GOTO_var(name) \ 00347 SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), \ 00348 BOOST_PP_CAT(name, _offset)(), \ 00349 BOOST_PP_CAT(name, _init_bytes), \ 00350 var ) 00351 # 00352 # define SENF_PARSER_GOTO_fix(name) \ 00353 SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), \ 00354 BOOST_PP_CAT(name, _offset), \ 00355 BOOST_PP_CAT(name, _offset), \ 00356 fix ) 00357 # 00358 # define SENF_PARSER_GOTO_OFFSET_var(offset, isize) \ 00359 SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, isize, var ) 00360 # 00361 # define SENF_PARSER_GOTO_OFFSET_fix(offset) \ 00362 SENF_PARSER_I_GOTO( BOOST_PP_CAT(senf_anon_, __LINE__), offset, offset, fix ) 00363 # 00364 # define SENF_PARSER_I_GOTO(name, offset, initsize, ofstype) \ 00365 private: \ 00366 SENF_PARSER_I_BITFIELD_RESET() \ 00367 SENF_PARSER_I_FIELD_INTRO(name, void, private) \ 00368 SENF_PARSER_I_FIELD_INIT_ro(name, void, private) \ 00369 BOOST_PP_CAT( SENF_PARSER_I_GOTO_SET_OFS_, ofstype ) (name, offset, initsize) \ 00370 public: 00371 # 00372 # define SENF_PARSER_I_GOTO_SET_OFS_var(name, offs, initsize) \ 00373 size_type field_offset_(senf::mpl::rv<BOOST_PP_CAT(name,_index)>*) const { \ 00374 return offs; \ 00375 } \ 00376 SENF_MPL_SLOT_SET(init_bytes, initsize); 00377 # 00378 # define SENF_PARSER_I_GOTO_SET_OFS_fix(name, offs, initsize) \ 00379 SENF_MPL_SLOT_SET(offset, offs); 00380 # 00381 # //- 00382 # // SENF_PARSER_LABEL_* 00383 # 00384 # define SENF_PARSER_LABEL_var(name) SENF_PARSER_I_LABEL( name, var, public ) 00385 # define SENF_PARSER_LABEL_fix(name) SENF_PARSER_I_LABEL( name, fix, public ) 00386 # 00387 # define SENF_PARSER_I_LABEL(name, ofstype, access) \ 00388 access: \ 00389 SENF_PARSER_I_BITFIELD_RESET() \ 00390 SENF_PARSER_I_FIELD_INTRO(name, void, access) \ 00391 SENF_PARSER_I_FIELD_INIT_ro(name, void, access) \ 00392 BOOST_PP_CAT(SENF_PARSER_I_FIELD_OFS_, ofstype) (name, type, access) \ 00393 BOOST_PP_CAT(SENF_PARSER_I_ADVANCE_OFS_, ofstype) (name, void, 0, 0, 0, access) \ 00394 public: 00395 # 00396 # //- 00397 # // SENF_PARSER_OFFSET_* 00398 # 00399 # define SENF_PARSER_OFFSET_fix(name) BOOST_PP_CAT(name, _offset) 00400 # define SENF_PARSER_OFFSET_var(name) BOOST_PP_CAT(name, _offset)() 00401 # 00402 # //- 00403 # // SENF_PARSER_FIXED_OFFSET_* 00404 # 00405 # define SENF_PARSER_FIXED_OFFSET_fix(name) BOOST_PP_CAT(name, _offset) 00406 # define SENF_PARSER_FIXED_OFFSET_var(name) BOOST_PP_CAT(name, _init_bytes) 00407 # 00408 # //- 00409 # // SENF_PARSER_CURRENT_FIXED_OFFSET_* 00410 # 00411 # define SENF_PARSER_CURRENT_FIXED_OFFSET_fix() SENF_MPL_SLOT_GET(offset) 00412 # define SENF_PARSER_CURRENT_FIXED_OFFSET_var() SENF_MPL_SLOT_GET(init_bytes) 00413 # 00414 # //- 00415 # // SENF_PARSER_FINALIZE_* 00416 # 00417 # define SENF_PARSER_FINALIZE_var(name) \ 00418 SENF_PARSER_FINALIZE_GENERIC(name) \ 00419 size_type bytes() const { \ 00420 return field_offset_(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0)); \ 00421 } \ 00422 static size_type const init_bytes = SENF_MPL_SLOT_GET(init_bytes) 00423 # 00424 # define SENF_PARSER_FINALIZE_fix(name) \ 00425 SENF_PARSER_FINALIZE_GENERIC(name) \ 00426 static size_type const fixed_bytes = SENF_MPL_SLOT_GET(offset); 00427 # 00428 # define SENF_PARSER_FINALIZE_GENERIC(name) \ 00429 void defaultInit() const { \ 00430 init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)>*>(0)); \ 00431 } \ 00432 name(data_iterator i, state_type s) : parser_base_type(i,s) {} \ 00433 private: \ 00434 template <class T> void init(T) const { defaultInit(); } \ 00435 public: \ 00436 void init() const { init(0); } 00437 # 00438 # //- 00439 # // SENF_PARSER_REQUIRE_VAR 00440 # 00441 # define SENF_PARSER_REQUIRE_VAR(description) \ 00442 BOOST_PP_CAT(SENF_PARSER_REQUIRE_VAR_, SENF_PARSER_TYPE)(description) 00443 # 00444 # define SENF_PARSER_REQUIRE_VAR_var(description) 00445 # 00446 # define SENF_PARSER_REQUIRE_VAR_fix(description) \ 00447 typedef BOOST_PP_CAT( PARSER_ERROR__, \ 00448 BOOST_PP_CAT(description, _not_allowed_in_fixed_parser) ) \ 00449 BOOST_PP_CAT(errsym_, __LINE__); 00450 # 00451 # //- 00452 # // SENF_PARSER_COLLECTION_I 00453 # 00454 # ifndef DOXYGEN 00455 # 00456 namespace senf { namespace detail { namespace auxtag { 00457 struct none {}; } } } 00458 namespace senf { namespace detail { namespace auxtag { 00459 struct bytes {}; } } } 00460 namespace senf { namespace detail { namespace auxtag { 00461 template <class Transform, class Tag> 00462 struct transform {}; } } } 00463 namespace senf { namespace detail { namespace auxtag { 00464 struct packetSize {}; } } } 00465 # 00466 # endif 00467 # 00468 # // Each tag is implemented by defining the following macros. If the Tag is <name>(<args>): 00469 # // SENF_PARSER_COLLECTION_TAG_GOBBLE__<name>(<args>) 00470 # // gobble the tag, that is expand to nothing 00471 # // SENF_PARSER_COLLECTION_TAG__<name>(<args>) 00472 # // return an intermediate tag. This tag will be used with the next macro to get the aux tag 00473 # // this indirection is needed since the tag may include templates with more than one 00474 # // argument which cannot be passed through macros ... Ugh ... 00475 # // SENF_PARSER_COLLECTION_TAG_EXPAND__<tag>(<tag args>) 00476 # // expand to the real tag type 00477 # // SENF_PARSER_COLLECTION_TAG_GETAUX__<name>(<args>) 00478 # // return the real aux field. More specifically, this is the aux argument to the aux expand 00479 # // macro 00480 # // SENF_PARSER_COLLECTION_TAG_AUXTYPE__<name>(<args>) 00481 # // return an identifier selecting the aux type macro to use. If the expansion of this macro 00482 # // is <auxtag>, the macro will be called SENF_PARSER_COLLECTION_TAG_AUXDEF__<auxtag> 00483 # // SENF_PARSER_COLLECTION_TAG_AUXDEF__<auxtag>(<name>,<auxarg>) 00484 # // this command must declare the typedef <fieldname>_aux_type to the base aux policy 00485 # 00486 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__bytes(x) 00487 # define SENF_PARSER_COLLECTION_TAG__bytes(x) bytes() 00488 # define SENF_PARSER_COLLECTION_TAG_EXPAND__bytes() senf::detail::auxtag::bytes 00489 # define SENF_PARSER_COLLECTION_TAG_GETAUX__bytes(x) x 00490 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE__bytes(x) auxField 00491 # 00492 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__transform(x,y) 00493 # define SENF_PARSER_COLLECTION_TAG__transform(x,y) \ 00494 transform(x, SENF_PARSER_COLLECTION_TAG_RECURS1(y)) 00495 # define SENF_PARSER_COLLECTION_TAG_EXPAND__transform(x,y) \ 00496 senf::detail::auxtag::transform< \ 00497 x, \ 00498 SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_EXPAND__, y)> 00499 # define SENF_PARSER_COLLECTION_TAG_GETAUX__transform(x,y) \ 00500 SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(y) 00501 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE__transform(x,y) \ 00502 SENF_PARSER_COLLECTION_TAG_AUXTYPE_RECURS1(y) 00503 # 00504 # define SENF_PARSER_COLLECTION_TAG_GOBBLE__packetSize() 00505 # define SENF_PARSER_COLLECTION_TAG__packetSize() packetSize() 00506 # define SENF_PARSER_COLLECTION_TAG_EXPAND__packetSize() senf::detail::auxtag::bytes 00507 # define SENF_PARSER_COLLECTION_TAG_GETAUX__packetSize() _ 00508 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE__packetSize() packetSize 00509 # 00510 # define SENF_PARSER_COLLECTION_TAG_EXPAND__none() senf::detail::auxtag::none 00511 # 00512 # define SENF_PARSER_COLLECTION_TAG_RECURS1(aux) \ 00513 BOOST_PP_IF( \ 00514 SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \ 00515 BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG__, aux), \ 00516 none() ) 00517 # 00518 # define SENF_PARSER_COLLECTION_TAG_GETAUX_RECURS1(aux) \ 00519 BOOST_PP_IF( \ 00520 SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \ 00521 BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux), \ 00522 aux) 00523 # 00524 # define SENF_PARSER_COLLECTION_TAG_AUXTYPE_RECURS1(aux) \ 00525 BOOST_PP_IF( \ 00526 SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \ 00527 BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_AUXTYPE__, aux), \ 00528 auxField) 00529 # 00530 # define SENF_PARSER_COLLECTION_HAS_KEYWORD(x) \ 00531 BOOST_PP_IS_EMPTY( SENF_CAT_RECURS1(SENF_PARSER_COLLECTION_TAG_GOBBLE__, x) ) 00532 # 00533 # define SENF_PARSER_COLLECTION_GETAUX(aux) \ 00534 BOOST_PP_IF( SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \ 00535 SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux), \ 00536 aux ) 00537 00538 # define SENF_PARSER_COLLECTION_I(access, name, aux, traits) \ 00539 BOOST_PP_EXPAND( \ 00540 SENF_PARSER_COLLECTION_II \ 00541 BOOST_PP_IF( \ 00542 SENF_PARSER_COLLECTION_HAS_KEYWORD(aux), \ 00543 ( access, \ 00544 name, \ 00545 SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_AUXTYPE__, aux), \ 00546 SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG_GETAUX__, aux), \ 00547 SENF_CAT_RECURS2(SENF_PARSER_COLLECTION_TAG__, aux), \ 00548 traits ), \ 00549 ( access, \ 00550 name, \ 00551 auxField, \ 00552 aux, \ 00553 none(), \ 00554 traits ) )) 00555 # 00556 # define SENF_PARSER_COLLECTION_II(access, name, auxtype, aux, tag, traits) \ 00557 private: \ 00558 BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_AUXDEF__, auxtype)(name, aux) \ 00559 typedef traits::parser< \ 00560 BOOST_PP_CAT(name,_aux_policy), \ 00561 BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_EXPAND__, tag) \ 00562 >::type BOOST_PP_CAT(name, _collection_t); \ 00563 access: \ 00564 SENF_PARSER_FIELD_SETUP_I( name, \ 00565 BOOST_PP_CAT(name, _collection_t), \ 00566 SENF_PARSER_TYPE, \ 00567 rw, \ 00568 access ) \ 00569 BOOST_PP_CAT(SENF_PARSER_COLLECTION_TAG_VAL__, auxtype)(name, aux, access) \ 00570 public: 00571 # 00572 # define SENF_PARSER_COLLECTION_TAG_AUXDEF__auxField(name, aux) \ 00573 BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUXTYPE_, SENF_PARSER_TYPE)(name, aux) \ 00574 typedef BOOST_PP_CAT(SENF_PARSER_COLLECTION_AUX_I_, SENF_PARSER_TYPE)(name, aux) \ 00575 BOOST_PP_CAT(name,_aux_policy); 00576 # 00577 # define SENF_PARSER_COLLECTION_AUXTYPE_var(name, aux) \ 00578 static bool const BOOST_PP_CAT(name, _aux_fixed) = \ 00579 (SENF_MPL_SLOT_GET(group) - BOOST_PP_CAT(aux, _group) == 0); 00580 # 00581 # define SENF_PARSER_COLLECTION_AUXTYPE_fix(name, aux) 00582 # 00583 # ifndef DOXYGEN 00584 # 00585 namespace senf { namespace detail { 00586 template <class Parser> struct DynamicAuxParserPolicy; 00587 template <class Parser, unsigned offset> struct FixedAuxParserPolicy; 00588 template <class Parser, unsigned fixedOffset, bool fixedDelta> 00589 struct ParserAuxPolicySelect 00590 { typedef senf::detail::DynamicAuxParserPolicy<Parser> type; }; 00591 template <class Parser, unsigned fixedOffset> 00592 struct ParserAuxPolicySelect<Parser, fixedOffset, true> 00593 { typedef senf::detail::FixedAuxParserPolicy<Parser, fixedOffset> type; }; 00594 }}; 00595 # 00596 # endif 00597 # 00598 # define SENF_PARSER_COLLECTION_AUX_I_var(name, aux) \ 00599 senf::detail::ParserAuxPolicySelect< BOOST_PP_CAT(aux, _t), \ 00600 SENF_PARSER_CURRENT_FIXED_OFFSET() \ 00601 - SENF_PARSER_FIXED_OFFSET(aux), \ 00602 BOOST_PP_CAT(name, _aux_fixed) >::type 00603 # 00604 # define SENF_PARSER_COLLECTION_AUX_I_fix(name, aux) \ 00605 senf::detail::FixedAuxParserPolicy< BOOST_PP_CAT(aux, _t), \ 00606 SENF_PARSER_CURRENT_FIXED_OFFSET() \ 00607 - SENF_PARSER_FIXED_OFFSET(aux) > 00608 # 00609 # define SENF_PARSER_COLLECTION_TAG_AUXDEF__packetSize(name, aux) \ 00610 typedef senf::detail::PacketSizeAuxParserPolicy BOOST_PP_CAT(name, _aux_policy); 00611 # 00612 # define SENF_PARSER_COLLECTION_TAG_VAL__auxField(name, aux, access) \ 00613 BOOST_PP_CAT(SENF_PARSER_COLLECTION_VAL_, SENF_PARSER_TYPE)(name, aux, access) 00614 # 00615 # define SENF_PARSER_COLLECTION_VAL_var(name,aux,access) \ 00616 private: \ 00617 template <class T> T BOOST_PP_CAT(name, _dispatch)(boost::true_type) const \ 00618 { return parse<T>( SENF_PARSER_OFFSET(name) ); } \ 00619 template <class T> T BOOST_PP_CAT(name, _dispatch)(boost::false_type) const \ 00620 { return parse<T>( BOOST_PP_CAT(aux,_)(), SENF_PARSER_OFFSET(name) ); } \ 00621 BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const \ 00622 { return BOOST_PP_CAT(name, _dispatch) <BOOST_PP_CAT(name, _t)>( \ 00623 boost::integral_constant<bool, BOOST_PP_CAT(name, _aux_fixed)>()); } \ 00624 access: \ 00625 BOOST_PP_CAT(name, _t) name() const \ 00626 { return BOOST_PP_CAT(name, _)(); } 00627 # 00628 # define SENF_PARSER_COLLECTION_VAL_fix(name,aux,access) \ 00629 private: \ 00630 BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const \ 00631 { return parse<BOOST_PP_CAT(name, _t)>( SENF_PARSER_OFFSET(name) ); } \ 00632 access: \ 00633 BOOST_PP_CAT(name, _t) name() const \ 00634 { return BOOST_PP_CAT(name, _)(); } 00635 # 00636 # define SENF_PARSER_COLLECTION_TAG_VAL__packetSize(name, aux, access) \ 00637 private: \ 00638 BOOST_PP_CAT(name, _t) BOOST_PP_CAT(name, _)() const \ 00639 { return parse<BOOST_PP_CAT(name, _t)>( SENF_PARSER_OFFSET(name) ); } \ 00640 access: \ 00641 BOOST_PP_CAT(name, _t) name() const \ 00642 { return BOOST_PP_CAT(name, _)(); } 00643 # 00644 # //- 00645 # endif 00646 # 00647 # 00648 # // Local Variables: 00649 # // mode: c++ 00650 # // fill-column: 100 00651 # // c-file-style: "senf" 00652 # // indent-tabs-mode: nil 00653 # // ispell-local-dictionary: "american" 00654 # // compile-command: "scons -u test" 00655 # // End: