4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
23 /** \page parsermacro_expand_example Example macro-expansion of packet parser helper macros
25 The following packet parser definition (taken from VariantParser.test.cc) has been subject to
26 macro-expansion (and a lot of reformatting) to show the inner workings of the packet parser
29 struct TestParser : public senf::PacketParserBase
31 # include SENF_PARSER()
33 SENF_PARSER_SKIP_BITS( 4 );
34 SENF_PARSER_BITFIELD_RO( type, 4, unsigned );
35 SENF_PARSER_PRIVATE_VARIANT( content_, type,
36 ( novalue( nocontent, key(10, senf::VoidPacketParser)) )
37 ( id( content, SubParser ) )
40 SENF_PARSER_FINALIZE(TestParser);
44 Here the reformated and sparsly commented expansion. I have left all the \c SENF_MPL_SLOT_ calls
45 unexpanded, otherwise the code would be absolutely unreadable. This is quite a lot of
46 source-code which however should create only a small amount of additional compiled code.
48 Also remember, that all this code is generated by C++ makros. Some detours are needed to work
49 around makro problems (e.g. templates with multiple arguments are parsed as seperate makro
50 arguments at each komma, inability to redefine a makro from another makro ...).
53 struct TestParser : public senf::PacketParserBase
55 // /////////////////////////////////////////////////////////////////////////
56 // #include SENF_PARSER()
59 SENF_MPL_SLOT_INIT_ZERO(index);
60 SENF_MPL_SLOT_INIT_ZERO(init_bytes);
61 SENF_MPL_SLOT_INIT_ZERO(bit);
62 SENF_MPL_SLOT_INIT_ZERO(bitfield_size);
63 SENF_MPL_SLOT_INIT_ZERO(group);
65 void init_chain (senf::mpl::rv <0> *) const {}
66 size_type field_offset_ (senf::mpl::rv <0> *) const { return 0; }
68 // /////////////////////////////////////////////////////////////////////////
69 // SENF_PARSER_SKIP_BITS( 4 );
71 SENF_MPL_SLOT_SET(bit, SENF_MPL_SLOT_GET(bit) + 4);
73 // /////////////////////////////////////////////////////////////////////////
74 // SENF_PARSER_BITFIELD_RO( type, 4, unsigned );
77 static size_type const type_bit = SENF_MPL_SLOT_GET(bit);
80 SENF_MPL_SLOT_SET(bit, type_bit + 4);
81 typedef senf::UIntFieldParser <type_bit, type_bit + 4> type_bit_t;
84 typedef type_bit_t type_t;
85 static size_type const type_index = SENF_MPL_SLOT_GET(index) + 1;
88 SENF_MPL_SLOT_SET(index, type_index);
89 void init_chain (senf::mpl::rv<type_index> *) const
91 init_chain (static_cast<senf::mpl::rv<type_index - 1> *>(0));
95 size_type type_offset () const
97 return field_offset_(static_cast<senf::mpl::rv<type_index - 1> *>(0)) -
98 SENF_MPL_SLOT_GET(bitfield_size);
100 static size_type const type_init_bytes =
101 SENF_MPL_SLOT_GET(init_bytes) - SENF_MPL_SLOT_GET(bitfield_size);
102 size_type type_next_offset () const
104 return type_offset() + type_t::fixed_bytes;
106 static size_type const type_next_init_bytes = type_init_bytes + type_t::fixed_bytes;
109 size_type field_offset_(senf::mpl::rv<type_index> *) const
111 return type_next_offset();
113 SENF_MPL_SLOT_SET(init_bytes, type_next_init_bytes);
114 static size_type const type_group = SENF_MPL_SLOT_GET(group) + 0;
115 SENF_MPL_SLOT_SET(group, type_group);
116 SENF_MPL_SLOT_SET(bitfield_size, type_t::fixed_bytes);
117 type_t type_ () const
119 return parse <type_bit_t> (type_offset ());
123 type_t::value_type type () const
128 // /////////////////////////////////////////////////////////////////////////
129 // SENF_PARSER_PRIVATE_VARIANT( content_, type,
130 // ( novalue( nocontent, key(10, senf::VoidPacketParser)) )
131 // ( id( content, SubParser ) )
135 typedef boost::mpl::vector <senf::VoidPacketParser, SubParser> content__parsers;
136 typedef type_t::value_type content__chooser_value_type;
137 static content__chooser_value_type content__key_0 ()
141 static content__chooser_value_type content__key_1 ()
145 template <content__chooser_value_type (*KeyFn) ()>
146 struct content__key_value_template
147 : public senf::detail::VariantKey<content__chooser_value_type, KeyFn> {};
148 template <class T, T (*K)()> friend class senf::detail::VariantKey;
149 typedef senf::detail::VariantKeyTransform<
150 content__chooser_value_type,
151 boost::mpl::vector< content__key_value_template<&content__key_0>,
152 content__key_value_template<&content__key_1> > >
154 typedef senf::detail::VariantParserTraits<content__parsers, content__transform>
157 // start SENF_PARSER_COLLECTION_I
158 static bool const content__aux_fixed = (SENF_MPL_SLOT_GET(group) - type_group) == 0;
159 typedef senf::detail::ParserAuxPolicySelect <
161 SENF_MPL_SLOT_GET(init_bytes) - type_init_bytes,
163 >::type content__aux_policy;
164 typedef content__traits::parser<content__aux_policy, senf::detail::auxtag::none>::type
165 content__collection_t;
166 SENF_MPL_SLOT_SET(bit, 0);
167 SENF_MPL_SLOT_SET(bitfield_size, 0);
168 typedef content__collection_t content__t;
169 static size_type const content__index = SENF_MPL_SLOT_GET(index) + 1;
170 SENF_MPL_SLOT_SET(index, content__index);
171 void init_chain (senf::mpl::rv<content__index> *) const
173 init_chain (static_cast<senf::mpl::rv<content__index - 1> *>(0));
176 size_type content__offset() const
178 return field_offset_ (static_cast<senf::mpl::rv<content__index - 1> *>(0));
180 static size_type const content__init_bytes = SENF_MPL_SLOT_GET(init_bytes);
181 size_type content__next_offset () const
183 return content__offset() + senf::bytes(content__());
185 static size_type const content__next_init_bytes =
186 content__init_bytes + senf::init_bytes<content__collection_t>::value;
187 size_type field_offset_(senf::mpl::rv<content__index> *) const
189 return content__next_offset();
191 SENF_MPL_SLOT_SET(init_bytes, content__next_init_bytes);
192 static size_type const content__group =
193 SENF_MPL_SLOT_GET(group) + (senf::is_fixed<content__collection_t>::value ? 0 : 1);
194 SENF_MPL_SLOET_SET(group, content__group);
196 T content__dispatch (boost::true_type) const
198 return parse<T>(content__offset());
201 T content__dispatch (boost::false_type) const
203 return parse<T>(type(), content__offset());
206 content__t content__() const
208 return content__dispatch<content__t>(
209 boost::integral_constant<bool, content__aux_fixed>());
211 content__t content_ () const
215 // end SENF_PARSER_COLLECTION_I
218 void nocontent() const
220 content_().init<0>();
222 typedef SubParser content_t;
223 SubParser content() const
225 return content_().get<1>();
227 void init_content() const
229 content_().init<1>();
231 bool has_content() const
233 return content_().variant() == 1;
236 // /////////////////////////////////////////////////////////////////////////
237 // SENF_PARSER_FINALIZE(TestParser);
239 void defaultInit () const
241 init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)> *>(0));
243 TestParser(data_iterator i, state_type s)
244 : parser_base_type (i, s)
259 size_type bytes() const
261 return field_offset_(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)> *>(0));
263 static size_type const init_bytes = SENF_MPL_SLOT_GET(init_bytes);
272 // comment-column: 40
273 // c-file-style: "senf"
274 // indent-tabs-mode: nil
275 // ispell-local-dictionary: "american"
276 // compile-command: "scons -u test"