4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 // Stefan Bund <stefan.bund@fokus.fraunhofer.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.
24 \brief ParseInt public header */
27 #define HH_ParseInt_ 1
31 #include <boost/cstdint.hpp>
32 #include <boost/static_assert.hpp>
33 #include <boost/integer/integer_mask.hpp>
34 #include "PacketParser.hh"
36 //#include "ParseInt.mpp"
37 ///////////////////////////////hh.p////////////////////////////////////////
38 #include "ParseInt.ih"
42 /** \defgroup parseint Integer parsers
44 Most packet fields will ultimately contain some type of integral number. The integer parsers
45 allow to parse arbitrary integers in network byte order from 1-32 bit, both signed and
46 unsigned. There are two types of integer parsers:
48 \li The normal integer parsers with interpret 1-4 byte integers (9, 16, 24, 32 bits) aligned
50 \li The bitfield parsers which parse integers with 1-32 bits aligned at any bit. A special
51 case is the single bit flag parser.
53 All fields are parsed in network byte order, the return value of all these parsers is the
54 value in host byte order.
56 The interface of all these parsers is the same (p is an arbitrary integer parser instance, v
57 is an integer constant):
59 \li <tt>p = v</tt>: Assigns the value to the packet field.
60 \li <tt>p.value(v)</tt>: same as above.
61 \li <tt>p.value()</tt>: Returns the fields value as an integer number.
62 \li Use of p like an integer in most contexts: <tt>p += v</tt>, <tt>p *= v</tt>, <tt>v = p +
63 1</tt> and so on. You will only need to use the explicit \c value() member in rare
64 circumstances when the automatic conversion is ambiguous or in some template contexts.
69 /** \brief Parse 8bit signed byte aligned integer
74 : public detail::packet::ParseIntOps<Parse_Int8,boost::int8_t>,
75 public PacketParserBase
77 Parse_Int8(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
79 ///////////////////////////////////////////////////////////////////////////
81 typedef boost::int8_t value_type;
82 static size_type const fixed_bytes = 1;
83 static value_type const min_value = -128;
84 static value_type const max_value = 127;
86 value_type value() const { return i()[0]; }
87 void value(value_type v) { i()[0] = v; }
88 Parse_Int8 const & operator= (value_type other) { value(other); return *this; }
90 /** \brief Write parsed value to stream
93 inline std::ostream & operator<<(std::ostream & os, Parse_Int8 const & i)
94 { os << i.value(); return os; }
96 /** \brief Parse 8bit unsigned byte aligned integer
101 : public detail::packet::ParseIntOps<Parse_UInt8,boost::uint8_t>,
102 public PacketParserBase
104 Parse_UInt8(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
106 ///////////////////////////////////////////////////////////////////////////
108 typedef boost::uint8_t value_type;
109 static size_type const fixed_bytes = 1;
110 static value_type const min_value = 0u;
111 static value_type const max_value = 255u;
113 value_type value() const { return i()[0]; }
114 void value(value_type v) { i()[0] = v; }
115 Parse_UInt8 const & operator= (value_type other) { value(other); return *this; }
117 /** \brief Write parsed value to stream
120 inline std::ostream & operator<<(std::ostream & os, Parse_UInt8 const & i)
121 { os << i.value(); return os; }
123 /** \brief Parse 16bit signed byte aligned integer
128 : public detail::packet::ParseIntOps<Parse_Int16,boost::int16_t>,
129 public PacketParserBase
131 Parse_Int16(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
133 ///////////////////////////////////////////////////////////////////////////
135 typedef boost::int16_t value_type;
136 static size_type const fixed_bytes = 2;
137 static value_type const min_value = -32768;
138 static value_type const max_value = 32767;
141 value_type value() const { return detail::packet::parse_uint16(i()); }
142 void value(value_type v) { detail::packet::write_uint16(i(),v); }
143 Parse_Int16 const & operator= (value_type other) { value(other); return *this; }
145 /** \brief Write parsed value to stream
148 inline std::ostream & operator<<(std::ostream & os, Parse_Int16 const & i)
149 { os << i.value(); return os; }
151 /** \brief Parse 16bit unsigned byte aligned integer
156 : public detail::packet::ParseIntOps<Parse_UInt16,boost::uint16_t>,
157 public PacketParserBase
159 Parse_UInt16(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
161 ///////////////////////////////////////////////////////////////////////////
163 typedef boost::uint16_t value_type;
164 static size_type const fixed_bytes = 2;
165 static value_type const min_value = 0u;
166 static value_type const max_value = 65535u;
168 value_type value() const { return detail::packet::parse_uint16(i()); }
169 void value(value_type v) { detail::packet::write_uint16(i(),v); }
170 Parse_UInt16 const & operator= (value_type other) { value(other); return *this; }
172 /** \brief Write parsed value to stream
173 \related Parse_UInt16
175 inline std::ostream & operator<<(std::ostream & os, Parse_UInt16 const & i)
176 { os << i.value(); return os; }
178 /** \brief Parse 24bit signed byte aligned integer
183 : public detail::packet::ParseIntOps<Parse_Int24,boost::int32_t>,
184 public PacketParserBase
186 Parse_Int24(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
188 ///////////////////////////////////////////////////////////////////////////
190 typedef boost::int32_t value_type;
191 static size_type const fixed_bytes = 3;
192 static value_type const min_value = -8388608;
193 static value_type const max_value = 8388607;
195 value_type value() const {
196 value_type v (detail::packet::parse_uint24(i())); return v&0x800000 ? v|0xff000000 : v; }
197 void value(value_type v) { detail::packet::write_uint24(i(),v); }
198 Parse_Int24 const & operator= (value_type other) { value(other); return *this; }
200 /** \brief Write parsed value to stream
203 inline std::ostream & operator<<(std::ostream & os, Parse_Int24 const & i)
204 { os << i.value(); return os; }
206 /** \brief Parse 24bit unsigned byte aligned integer
211 : public detail::packet::ParseIntOps<Parse_UInt24,boost::uint32_t>,
212 public PacketParserBase
214 Parse_UInt24(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
216 ///////////////////////////////////////////////////////////////////////////
218 typedef boost::uint32_t value_type;
219 static size_type const fixed_bytes = 3;
220 static value_type const min_value = 0u;
221 static value_type const max_value = 16777215u;
223 value_type value() const { return detail::packet::parse_uint24(i()); }
224 void value(value_type v) { detail::packet::write_uint24(i(),v); }
225 Parse_UInt24 const & operator= (value_type other) { value(other); return *this; }
227 /** \brief Write parsed value to stream
228 \related Parse_UInt24
230 inline std::ostream & operator<<(std::ostream & os, Parse_UInt24 const & i)
231 { os << i.value(); return os; }
233 /** \brief Parse 32bit signed byte aligned integer
238 : public detail::packet::ParseIntOps<Parse_Int32,boost::int32_t>,
239 public PacketParserBase
241 Parse_Int32(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
243 ///////////////////////////////////////////////////////////////////////////
245 typedef boost::int32_t value_type;
246 static size_type const fixed_bytes = 4;
247 static value_type const min_value = -2147483647 - 1;
248 static value_type const max_value = 2147483647;
250 value_type value() const { return detail::packet::parse_uint32(i()); }
251 void value(value_type v) { detail::packet::write_uint32(i(),v); }
252 Parse_Int32 const & operator= (value_type other) { value(other); return *this; }
254 /** \brief Write parsed value to stream
257 inline std::ostream & operator<<(std::ostream & os, Parse_Int32 const & i)
258 { os << i.value(); return os; }
260 /** \brief Parse 32bit unsigned byte aligned integer
265 : public detail::packet::ParseIntOps<Parse_UInt32,boost::uint32_t>,
266 public PacketParserBase
268 Parse_UInt32(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
270 ///////////////////////////////////////////////////////////////////////////
272 typedef boost::uint32_t value_type;
273 static size_type const fixed_bytes = 4;
274 static value_type const min_value = 0u;
275 static value_type const max_value = 4294967295u;
277 value_type value() const { return detail::packet::parse_uint32(i()); }
278 void value(value_type v) { detail::packet::write_uint32(i(),v); }
279 Parse_UInt32 const & operator= (value_type other) { value(other); return *this; }
281 /** \brief Write parsed value to stream
282 \related Parse_UInt32
284 inline std::ostream & operator<<(std::ostream & os, Parse_UInt32 const & i)
285 { os << i.value(); return os; }
287 /** \brief Parse signed bitfield with up to 32bit's
289 This parser will parse a bitfield beginning at the bit \a Start and ending \e before \a
290 End. Bits are numbered <em>most significant bit first</em> as this is the customary
291 numbering used when defining packet data structures. \a Start and \a End can be \e
292 arbitrary as long as the field is between 1 and 32 bits in size. In other words, \c
293 Parse_IntField<53,81> is a valid 30 bit field.
295 When defining a compound parser with several bit fields, you need to take care of the fact,
296 that several integer field parsers will interpret the same data \e bytes (but not the same
297 \e bits). It is customary for several integer field parsers to start at the same byte offset
298 with ever increasing bit offsets.
302 \implementation The integer field parser is highly optimized. Since the bit positions are
303 compile-time constants, the compiler will create optimized bit-masks to directly access
304 the value. The parser is also optimized to access the minimum number of data bytes
309 template <unsigned Start, unsigned End>
310 struct Parse_IntField
311 : public detail::packet::ParseIntOps<Parse_IntField<Start,End>,boost::int32_t>,
312 public PacketParserBase
314 Parse_IntField(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
316 ///////////////////////////////////////////////////////////////////////////
318 typedef boost::int32_t value_type;
319 static size_type const start_bit = Start;
320 static size_type const end_bit = End;
321 static size_type const fixed_bytes = (End-1)/8+1;
322 static value_type const max_value = boost::low_bits_mask_t<End-Start-1>::sig_bits;
323 static value_type const min_value = - max_value - 1;
326 value_type value() const {
327 value_type v (detail::packet::parse_bitfield<Start,End>::parse(i()));
328 return v&boost::high_bit_mask_t<End-Start-1>::high_bit ?
329 v | ~boost::low_bits_mask_t<End-Start>::sig_bits : v;
331 void value(value_type v) { detail::packet::parse_bitfield<Start,End>::write(i(),v); }
332 Parse_IntField const & operator= (value_type other) { value(other); return *this; }
335 BOOST_STATIC_ASSERT( Start<End );
336 BOOST_STATIC_ASSERT( End-Start<=32 );
338 /** \brief Write parsed value to stream
339 \related Parse_IntField
341 template <unsigned Start, unsigned End>
342 inline std::ostream & operator<<(std::ostream & os, Parse_IntField<Start,End> const & i)
343 { os << i.value(); return os; }
345 /** \brief Parse unsigned bitfield with up to 32bit's
347 This parser will parse a bitfield beginning at the bit \a Start and ending \e before \a
348 End. Bits are numbered <em>most significant bit first</em> as this is the customary
349 numbering used when defining packet data structures. \a Start and \a End can be \e
350 arbitrary as long as the field is between 1 and 32 bits in size. In other words, \c
351 Parse_IntField<53,81> is a valid 30 bit field.
353 When defining a compound parser with several bit fields, you need to take care of the fact,
354 that several integer field parsers will interpret the same data \e bytes (but not the same
355 \e bits). It is customary for several integer field parsers to start at the same byte offset
356 with ever increasing bit offsets.
360 \implementation The integer field parser is highly optimized. Since the bit positions are
361 compile-time constants, the compiler will create optimized bit-masks to directly access
362 the value. The parser is also optimized to access the minimum number of data bytes
367 template <unsigned Start, unsigned End>
368 struct Parse_UIntField
369 : public detail::packet::ParseIntOps<Parse_UIntField<Start,End>,boost::uint32_t>,
370 public PacketParserBase
372 Parse_UIntField(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
374 ///////////////////////////////////////////////////////////////////////////
376 typedef boost::uint32_t value_type;
377 static size_type const start_bit = Start;
378 static size_type const end_bit = End;
379 static size_type const fixed_bytes = (End-1)/8+1;
380 static value_type const min_value = 0u;
381 static value_type const max_value = boost::low_bits_mask_t<End-Start>::sig_bits;
383 value_type value() const { return detail::packet::parse_bitfield<Start,End>::parse(i()); }
384 void value(value_type v) { detail::packet::parse_bitfield<Start,End>::write(i(),v); }
385 Parse_UIntField const & operator= (value_type other) { value(other); return *this; }
388 BOOST_STATIC_ASSERT( Start<End );
389 BOOST_STATIC_ASSERT( End-Start<=32 );
391 /** \brief Write parsed value to stream
392 \related Parse_UIntField
394 template <unsigned Start, unsigned End>
395 inline std::ostream & operator<<(std::ostream & os, Parse_UIntField<Start,End> const & i)
396 { os << i.value(); return os; }
398 /** \brief Parse single-bit flag
400 This parser will parse a single bit as True/False value. Bits are numbered <em>most
401 significant bit first</em> as this is the customary numbering used when defining packet data
402 structures. \a Bit can be arbitrary, \c Parse_Flag<75> is a valid flag parser.
404 When defining a compound parser with several bit fields, you need to take care of the fact,
405 that several integer field parsers will interpret the same data \e bytes (but not the same
406 \e bits). It is customary for several integer field parsers to start at the same byte offset
407 with ever increasing bit offsets.
412 template <unsigned Bit>
414 : public detail::packet::ParseIntOps<Parse_Flag<Bit>,bool>,
415 public PacketParserBase
417 Parse_Flag(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
419 ///////////////////////////////////////////////////////////////////////////
421 typedef bool value_type;
422 static size_type const bit = Bit;
423 static size_type const fixed_bytes = Bit/8+1;
424 static value_type const min_value = 0;
425 static value_type const max_value = 1;
427 value_type value() const { return i()[Bit/8] & (1<<(7-(Bit%8))); }
428 void value(value_type v) {
429 if (v) i()[0] |= 1<<(7-(Bit%8));
430 else i()[0] &= ~(1<<(7-(Bit%8)));
432 Parse_Flag const & operator= (value_type other) { value(other); return *this; }
434 /** \brief Write parsed value to stream
437 template <unsigned Bit>
438 inline std::ostream & operator<<(std::ostream & os, Parse_Flag<Bit> const & i)
439 { os << i.value(); return os; }
443 ///////////////////////////////hh.e////////////////////////////////////////
445 #if !defined(HH_Packets__decls_) && !defined(HH_ParseInt_i_)
446 #define HH_ParseInt_i_
447 //#include "ParseInt.cci"
448 //#include "ParseInt.ct"
449 //#include "ParseInt.cti"
456 // c-file-style: "senf"
457 // indent-tabs-mode: nil
458 // ispell-local-dictionary: "american"
459 // compile-command: "scons -u test"
460 // comment-column: 40