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.
24 \brief IntParser public header */
26 #ifndef HH_SENF_Packets_IntParser_
27 #define HH_SENF_Packets_IntParser_ 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 "IntParser.mpp"
37 ///////////////////////////////hh.p////////////////////////////////////////
38 #include "IntParser.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::IntParserOps<Int8Parser,boost::int8_t>,
75 public PacketParserBase
77 Int8Parser(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 Int8Parser const & operator= (value_type other) { value(other); return *this; }
90 /** \brief Write parsed value to stream
93 inline std::ostream & operator<<(std::ostream & os, Int8Parser const & i)
94 { os << i.value(); return os; }
96 /** \brief Parse 8bit unsigned byte aligned integer
101 : public detail::packet::IntParserOps<UInt8Parser,boost::uint8_t>,
102 public PacketParserBase
104 UInt8Parser(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 UInt8Parser const & operator= (value_type other) { value(other); return *this; }
117 /** \brief Write parsed value to stream
120 inline std::ostream & operator<<(std::ostream & os, UInt8Parser const & i)
121 { os << i.value(); return os; }
123 /** \brief Parse 16bit signed byte aligned integer
128 : public detail::packet::IntParserOps<Int16Parser,boost::int16_t>,
129 public PacketParserBase
131 Int16Parser(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 Int16Parser const & operator= (value_type other) { value(other); return *this; }
145 /** \brief Write parsed value to stream
148 inline std::ostream & operator<<(std::ostream & os, Int16Parser const & i)
149 { os << i.value(); return os; }
151 /** \brief Parse 16bit signed byte aligned integer LSB
155 struct Int16LSBParser
156 : public detail::packet::IntParserOps<Int16LSBParser,boost::int16_t>,
157 public PacketParserBase
159 Int16LSBParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
161 ///////////////////////////////////////////////////////////////////////////
163 typedef boost::int16_t value_type;
164 static size_type const fixed_bytes = 2;
165 static value_type const min_value = -32768;
166 static value_type const max_value = 32767;
169 value_type value() const { return detail::packet::parse_uint16LSB(i()); }
170 void value(value_type v) { detail::packet::write_uint16LSB(i(),v); }
171 Int16LSBParser const & operator= (value_type other) { value(other); return *this; }
173 /** \brief Write parsed value to stream
176 inline std::ostream & operator<<(std::ostream & os, Int16LSBParser const & i)
177 { os << i.value(); return os; }
179 /** \brief Parse 16bit unsigned byte aligned integer
184 : public detail::packet::IntParserOps<UInt16Parser,boost::uint16_t>,
185 public PacketParserBase
187 UInt16Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
189 ///////////////////////////////////////////////////////////////////////////
191 typedef boost::uint16_t value_type;
192 static size_type const fixed_bytes = 2;
193 static value_type const min_value = 0u;
194 static value_type const max_value = 65535u;
196 value_type value() const { return detail::packet::parse_uint16(i()); }
197 void value(value_type v) { detail::packet::write_uint16(i(),v); }
198 UInt16Parser const & operator= (value_type other) { value(other); return *this; }
200 /** \brief Write parsed value to stream
201 \related UInt16Parser
203 inline std::ostream & operator<<(std::ostream & os, UInt16Parser const & i)
204 { os << i.value(); return os; }
206 /** \brief Parse 16bit unsigned byte aligned integer LSB
210 struct UInt16LSBParser
211 : public detail::packet::IntParserOps<UInt16LSBParser,boost::uint16_t>,
212 public PacketParserBase
214 UInt16LSBParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
216 ///////////////////////////////////////////////////////////////////////////
218 typedef boost::uint16_t value_type;
219 static size_type const fixed_bytes = 2;
220 static value_type const min_value = 0u;
221 static value_type const max_value = 65535u;
223 value_type value() const { return detail::packet::parse_uint16LSB(i()); }
224 void value(value_type v) { detail::packet::write_uint16LSB(i(),v); }
225 UInt16LSBParser const & operator= (value_type other) { value(other); return *this; }
227 /** \brief Write parsed value to stream
228 \related UInt16LSBParser
230 inline std::ostream & operator<<(std::ostream & os, UInt16LSBParser const & i)
231 { os << i.value(); return os; }
233 /** \brief Parse 24bit signed byte aligned integer
238 : public detail::packet::IntParserOps<Int24Parser,boost::int32_t>,
239 public PacketParserBase
241 Int24Parser(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 = 3;
247 static value_type const min_value = -8388608;
248 static value_type const max_value = 8388607;
250 value_type value() const {
251 value_type v (detail::packet::parse_uint24(i())); return v&0x800000 ? v|0xff000000 : v; }
252 void value(value_type v) { detail::packet::write_uint24(i(),v); }
253 Int24Parser const & operator= (value_type other) { value(other); return *this; }
255 /** \brief Write parsed value to stream
258 inline std::ostream & operator<<(std::ostream & os, Int24Parser const & i)
259 { os << i.value(); return os; }
261 /** \brief Parse 24bit unsigned byte aligned integer
266 : public detail::packet::IntParserOps<UInt24Parser,boost::uint32_t>,
267 public PacketParserBase
269 UInt24Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
271 ///////////////////////////////////////////////////////////////////////////
273 typedef boost::uint32_t value_type;
274 static size_type const fixed_bytes = 3;
275 static value_type const min_value = 0u;
276 static value_type const max_value = 16777215u;
278 value_type value() const { return detail::packet::parse_uint24(i()); }
279 void value(value_type v) { detail::packet::write_uint24(i(),v); }
280 UInt24Parser const & operator= (value_type other) { value(other); return *this; }
282 /** \brief Write parsed value to stream
283 \related UInt24Parser
285 inline std::ostream & operator<<(std::ostream & os, UInt24Parser const & i)
286 { os << i.value(); return os; }
288 /** \brief Parse 32bit signed byte aligned integer
293 : public detail::packet::IntParserOps<Int32Parser,boost::int32_t>,
294 public PacketParserBase
296 Int32Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
298 ///////////////////////////////////////////////////////////////////////////
300 typedef boost::int32_t value_type;
301 static size_type const fixed_bytes = 4;
302 static value_type const min_value = -2147483647 - 1;
303 static value_type const max_value = 2147483647;
305 value_type value() const { return detail::packet::parse_uint32(i()); }
306 void value(value_type v) { detail::packet::write_uint32(i(),v); }
307 Int32Parser const & operator= (value_type other) { value(other); return *this; }
309 /** \brief Write parsed value to stream
312 inline std::ostream & operator<<(std::ostream & os, Int32Parser const & i)
313 { os << i.value(); return os; }
315 /** \brief Parse 32bit unsigned byte aligned integer
320 : public detail::packet::IntParserOps<UInt32Parser,boost::uint32_t>,
321 public PacketParserBase
323 UInt32Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
325 ///////////////////////////////////////////////////////////////////////////
327 typedef boost::uint32_t value_type;
328 static size_type const fixed_bytes = 4;
329 static value_type const min_value = 0u;
330 static value_type const max_value = 4294967295u;
332 value_type value() const { return detail::packet::parse_uint32(i()); }
333 void value(value_type v) { detail::packet::write_uint32(i(),v); }
334 UInt32Parser const & operator= (value_type other) { value(other); return *this; }
336 /** \brief Write parsed value to stream
337 \related UInt32Parser
339 inline std::ostream & operator<<(std::ostream & os, UInt32Parser const & i)
340 { os << i.value(); return os; }
342 struct UInt32LSBParser
343 : public detail::packet::IntParserOps<UInt32LSBParser,boost::uint32_t>,
344 public PacketParserBase
346 UInt32LSBParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
348 ///////////////////////////////////////////////////////////////////////////
350 typedef boost::uint32_t value_type;
351 static size_type const fixed_bytes = 4;
352 static value_type const min_value = 0u;
353 static value_type const max_value = 4294967295u;
355 value_type value() const { return detail::packet::parse_uint32LSB(i()); }
356 void value(value_type v) { detail::packet::write_uint32LSB(i(),v); }
357 UInt32LSBParser const & operator= (value_type other) { value(other); return *this; }
359 /** \brief Write parsed value to stream
360 \related UInt32LSBParser
362 inline std::ostream & operator<<(std::ostream & os, UInt32LSBParser const & i)
363 { os << i.value(); return os; }
368 /** \brief Parse 64bit signed byte aligned integer
373 : public detail::packet::IntParserOps<Int64Parser,boost::int64_t>,
374 public PacketParserBase
376 Int64Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
378 ///////////////////////////////////////////////////////////////////////////
380 typedef boost::int64_t value_type;
381 static size_type const fixed_bytes = 8;
383 value_type value() const { return detail::packet::parse_uint64(i()); }
384 void value(value_type v) { detail::packet::write_uint64(i(),v); }
385 Int64Parser const & operator= (value_type other) { value(other); return *this; }
387 /** \brief Write parsed value to stream
390 inline std::ostream & operator<<(std::ostream & os, Int64Parser const & i)
391 { os << i.value(); return os; }
394 /** \brief Parse 64bit unsigned byte aligned integer
399 : public detail::packet::IntParserOps<UInt64Parser,boost::uint64_t>,
400 public PacketParserBase
402 UInt64Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
404 ///////////////////////////////////////////////////////////////////////////
406 typedef boost::uint64_t value_type;
407 static size_type const fixed_bytes = 8;
409 value_type value() const { return detail::packet::parse_uint64(i()); }
410 void value(value_type v) { detail::packet::write_uint64(i(),v); }
411 UInt64Parser const & operator= (value_type other) { value(other); return *this; }
413 /** \brief Write parsed value to stream
414 \related UInt64Parser
416 inline std::ostream & operator<<(std::ostream & os, UInt64Parser const & i)
417 { os << i.value(); return os; }
419 /** \brief Parse 64bit unsigned byte aligned integer LSB
423 struct UInt64LSBParser
424 : public detail::packet::IntParserOps<UInt64LSBParser,boost::uint64_t>,
425 public PacketParserBase
427 UInt64LSBParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
429 ///////////////////////////////////////////////////////////////////////////
431 typedef boost::uint64_t value_type;
432 static size_type const fixed_bytes = 8;
434 value_type value() const { return detail::packet::parse_uint64LSB(i()); }
435 void value(value_type v) { detail::packet::write_uint64LSB(i(),v); }
436 UInt64LSBParser const & operator= (value_type other) { value(other); return *this; }
438 /** \brief Write parsed value to stream
439 \related UInt64LSBParser
441 inline std::ostream & operator<<(std::ostream & os, UInt64LSBParser const & i)
442 { os << i.value(); return os; }
444 /** \brief Parse signed bitfield with up to 32bit's
446 This parser will parse a bitfield beginning at the bit \a Start and ending \e before \a
447 End. Bits are numbered <em>most significant bit first</em> as this is the customary
448 numbering used when defining packet data structures. \a Start and \a End can be \e
449 arbitrary as long as the field is between 1 and 32 bits in size. In other words, \c
450 IntFieldParser<53,81> is a valid 30 bit field.
452 When defining a compound parser with several bit fields, you need to take care of the fact,
453 that several integer field parsers will interpret the same data \e bytes (but not the same
454 \e bits). It is customary for several integer field parsers to start at the same byte offset
455 with ever increasing bit offsets.
459 \implementation The integer field parser is highly optimized. Since the bit positions are
460 compile-time constants, the compiler will create optimized bit-masks to directly access
461 the value. The parser is also optimized to access the minimum number of data bytes
466 template <unsigned Start, unsigned End>
467 struct IntFieldParser
468 : public detail::packet::IntParserOps<IntFieldParser<Start,End>,boost::int32_t>,
469 public PacketParserBase
471 IntFieldParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
473 ///////////////////////////////////////////////////////////////////////////
475 typedef boost::int32_t value_type;
476 static size_type const start_bit = Start;
477 static size_type const end_bit = End;
478 static size_type const fixed_bytes = (End-1)/8+1;
479 static value_type const max_value = boost::low_bits_mask_t<End-Start-1>::sig_bits;
480 static value_type const min_value = - max_value - 1;
483 value_type value() const {
484 value_type v (detail::packet::parse_bitfield<Start,End>::parse(i()));
485 return v&boost::high_bit_mask_t<End-Start-1>::high_bit ?
486 v | ~boost::low_bits_mask_t<End-Start>::sig_bits : v;
488 void value(value_type v) { detail::packet::parse_bitfield<Start,End>::write(i(),v); }
489 IntFieldParser const & operator= (value_type other) { value(other); return *this; }
492 BOOST_STATIC_ASSERT( Start<End );
493 BOOST_STATIC_ASSERT( End-Start<=32 );
495 /** \brief Write parsed value to stream
496 \related IntFieldParser
498 template <unsigned Start, unsigned End>
499 inline std::ostream & operator<<(std::ostream & os, IntFieldParser<Start,End> const & i)
500 { os << i.value(); return os; }
502 /** \brief Parse unsigned bitfield with up to 32bit's
504 This parser will parse a bitfield beginning at the bit \a Start and ending \e before \a
505 End. Bits are numbered <em>most significant bit first</em> as this is the customary
506 numbering used when defining packet data structures. \a Start and \a End can be \e
507 arbitrary as long as the field is between 1 and 32 bits in size. In other words, \c
508 IntFieldParser<53,81> is a valid 30 bit field.
510 When defining a compound parser with several bit fields, you need to take care of the fact,
511 that several integer field parsers will interpret the same data \e bytes (but not the same
512 \e bits). It is customary for several integer field parsers to start at the same byte offset
513 with ever increasing bit offsets.
517 \implementation The integer field parser is highly optimized. Since the bit positions are
518 compile-time constants, the compiler will create optimized bit-masks to directly access
519 the value. The parser is also optimized to access the minimum number of data bytes
524 template <unsigned Start, unsigned End>
525 struct UIntFieldParser
526 : public detail::packet::IntParserOps<UIntFieldParser<Start,End>,boost::uint32_t>,
527 public PacketParserBase
529 UIntFieldParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
531 ///////////////////////////////////////////////////////////////////////////
533 typedef boost::uint32_t value_type;
534 static size_type const start_bit = Start;
535 static size_type const end_bit = End;
536 static size_type const fixed_bytes = (End-1)/8+1;
537 static value_type const min_value = 0u;
538 static value_type const max_value = boost::low_bits_mask_t<End-Start>::sig_bits;
540 value_type value() const { return detail::packet::parse_bitfield<Start,End>::parse(i()); }
541 void value(value_type v) { detail::packet::parse_bitfield<Start,End>::write(i(),v); }
542 UIntFieldParser const & operator= (value_type other) { value(other); return *this; }
545 BOOST_STATIC_ASSERT( Start<End );
546 BOOST_STATIC_ASSERT( End-Start<=32 );
548 /** \brief Write parsed value to stream
549 \related UIntFieldParser
551 template <unsigned Start, unsigned End>
552 inline std::ostream & operator<<(std::ostream & os, UIntFieldParser<Start,End> const & i)
553 { os << i.value(); return os; }
555 /** \brief Parse single-bit flag
557 This parser will parse a single bit as True/False value. Bits are numbered <em>most
558 significant bit first</em> as this is the customary numbering used when defining packet data
559 structures. \a Bit can be arbitrary, \c FlagParser<75> is a valid flag parser.
561 When defining a compound parser with several bit fields, you need to take care of the fact,
562 that several integer field parsers will interpret the same data \e bytes (but not the same
563 \e bits). It is customary for several integer field parsers to start at the same byte offset
564 with ever increasing bit offsets.
569 template <unsigned Bit>
571 : public detail::packet::IntParserOps<FlagParser<Bit>,bool>,
572 public PacketParserBase
574 FlagParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
576 ///////////////////////////////////////////////////////////////////////////
578 typedef bool value_type;
579 static size_type const bit = Bit;
580 static size_type const fixed_bytes = Bit/8+1;
581 static value_type const min_value = 0;
582 static value_type const max_value = 1;
584 value_type value() const { return i()[Bit/8] & (1<<(7-(Bit%8))); }
585 void value(value_type v) {
586 if (v) i()[Bit/8] |= 1<<(7-(Bit%8));
587 else i()[Bit/8] &= ~(1<<(7-(Bit%8)));
589 FlagParser const & operator= (value_type other) { value(other); return *this; }
591 /** \brief Write parsed value to stream
594 template <unsigned Bit>
595 inline std::ostream & operator<<(std::ostream & os, FlagParser<Bit> const & i)
596 { os << i.value(); return os; }
600 ///////////////////////////////hh.e////////////////////////////////////////
602 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_IntParser_i_)
603 #define HH_SENF_Packets_IntParser_i_
604 //#include "IntParser.cci"
605 //#include "IntParser.ct"
606 //#include "IntParser.cti"
613 // c-file-style: "senf"
614 // indent-tabs-mode: nil
615 // ispell-local-dictionary: "american"
616 // compile-command: "scons -u test"
617 // comment-column: 40