4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief IntParser public header */
31 #ifndef HH_SENF_Packets_IntParser_
32 #define HH_SENF_Packets_IntParser_ 1
36 #include <boost/cstdint.hpp>
37 #include <boost/static_assert.hpp>
38 #include <boost/integer/integer_mask.hpp>
39 #include "PacketParser.hh"
41 //#include "IntParser.mpp"
42 //-/////////////////////////////////////////////////////////////////////////////////////////////////
43 #include "IntParser.ih"
47 /** \defgroup parseint Integer parsers
49 Most packet fields will ultimately contain some type of integral number. The integer parsers
50 allow to parse arbitrary integers in network byte order from 1-32 bit, both signed and
51 unsigned. There are two types of integer parsers:
53 \li The normal integer parsers with interpret 1-4 byte integers (9, 16, 24, 32 bits) aligned
55 \li The bitfield parsers which parse integers with 1-32 bits aligned at any bit. A special
56 case is the single bit flag parser.
58 All fields are parsed in network byte order, the return value of all these parsers is the
59 value in host byte order.
61 The interface of all these parsers is the same (p is an arbitrary integer parser instance, v
62 is an integer constant):
64 \li <tt>p = v</tt>: Assigns the value to the packet field.
65 \li <tt>p.value(v)</tt>: same as above.
66 \li <tt>p.value()</tt>: Returns the fields value as an integer number.
67 \li Use of p like an integer in most contexts: <tt>p += v</tt>, <tt>p *= v</tt>, <tt>v = p
68 1</tt> and so on. You will only need to use the explicit \c value() member in rare
69 circumstances when the automatic conversion is ambiguous or in some template contexts.
74 /** \brief Parse 8bit signed byte aligned integer
79 : public detail::packet::IntParserOps<Int8Parser,boost::int8_t>,
80 public PacketParserBase
82 Int8Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
84 //-////////////////////////////////////////////////////////////////////////
86 typedef boost::int8_t value_type;
87 static size_type const fixed_bytes = 1;
88 static value_type const min_value = -128;
89 static value_type const max_value = 127;
91 value_type value() const { return i()[0]; }
92 void value(value_type v) { i()[0] = v; }
93 Int8Parser const & operator= (value_type other) { value(other); return *this; }
95 /** \brief Write parsed value to stream
98 inline std::ostream & operator<<(std::ostream & os, Int8Parser const & i)
99 { os << i.value(); return os; }
101 /** \brief Parse 8bit unsigned byte aligned integer
106 : public detail::packet::IntParserOps<UInt8Parser,boost::uint8_t>,
107 public PacketParserBase
109 UInt8Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
111 //-////////////////////////////////////////////////////////////////////////
113 typedef boost::uint8_t value_type;
114 static size_type const fixed_bytes = 1;
115 static value_type const min_value = 0u;
116 static value_type const max_value = 255u;
118 value_type value() const { return i()[0]; }
119 void value(value_type v) { i()[0] = v; }
120 UInt8Parser const & operator= (value_type other) { value(other); return *this; }
122 /** \brief Write parsed value to stream
125 inline std::ostream & operator<<(std::ostream & os, UInt8Parser const & i)
126 { os << i.value(); return os; }
128 /** \brief Parse 16bit signed byte aligned integer
133 : public detail::packet::IntParserOps<Int16Parser,boost::int16_t>,
134 public PacketParserBase
136 Int16Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
138 //-////////////////////////////////////////////////////////////////////////
140 typedef boost::int16_t value_type;
141 static size_type const fixed_bytes = 2;
142 static value_type const min_value = -32768;
143 static value_type const max_value = 32767;
146 value_type value() const { return detail::packet::parse_uint16(i()); }
147 void value(value_type v) { detail::packet::write_uint16(i(),v); }
148 Int16Parser const & operator= (value_type other) { value(other); return *this; }
150 /** \brief Write parsed value to stream
153 inline std::ostream & operator<<(std::ostream & os, Int16Parser const & i)
154 { os << i.value(); return os; }
156 /** \brief Parse 16bit signed byte aligned integer LSB
160 struct Int16LSBParser
161 : public detail::packet::IntParserOps<Int16LSBParser,boost::int16_t>,
162 public PacketParserBase
164 Int16LSBParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
166 //-////////////////////////////////////////////////////////////////////////
168 typedef boost::int16_t value_type;
169 static size_type const fixed_bytes = 2;
170 static value_type const min_value = -32768;
171 static value_type const max_value = 32767;
174 value_type value() const { return detail::packet::parse_uint16LSB(i()); }
175 void value(value_type v) { detail::packet::write_uint16LSB(i(),v); }
176 Int16LSBParser const & operator= (value_type other) { value(other); return *this; }
178 /** \brief Write parsed value to stream
179 \related Int16LSBParser
181 inline std::ostream & operator<<(std::ostream & os, Int16LSBParser const & i)
182 { os << i.value(); return os; }
184 /** \brief Parse 16bit unsigned byte aligned integer
189 : public detail::packet::IntParserOps<UInt16Parser,boost::uint16_t>,
190 public PacketParserBase
192 UInt16Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
194 //-////////////////////////////////////////////////////////////////////////
196 typedef boost::uint16_t value_type;
197 static size_type const fixed_bytes = 2;
198 static value_type const min_value = 0u;
199 static value_type const max_value = 65535u;
201 value_type value() const { return detail::packet::parse_uint16(i()); }
202 void value(value_type v) { detail::packet::write_uint16(i(),v); }
203 UInt16Parser const & operator= (value_type other) { value(other); return *this; }
205 /** \brief Write parsed value to stream
206 \related UInt16Parser
208 inline std::ostream & operator<<(std::ostream & os, UInt16Parser const & i)
209 { os << i.value(); return os; }
211 /** \brief Parse 16bit unsigned byte aligned integer LSB
215 struct UInt16LSBParser
216 : public detail::packet::IntParserOps<UInt16LSBParser,boost::uint16_t>,
217 public PacketParserBase
219 UInt16LSBParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
221 //-////////////////////////////////////////////////////////////////////////
223 typedef boost::uint16_t value_type;
224 static size_type const fixed_bytes = 2;
225 static value_type const min_value = 0u;
226 static value_type const max_value = 65535u;
228 value_type value() const { return detail::packet::parse_uint16LSB(i()); }
229 void value(value_type v) { detail::packet::write_uint16LSB(i(),v); }
230 UInt16LSBParser const & operator= (value_type other) { value(other); return *this; }
232 /** \brief Write parsed value to stream
233 \related UInt16LSBParser
235 inline std::ostream & operator<<(std::ostream & os, UInt16LSBParser const & i)
236 { os << i.value(); return os; }
238 /** \brief Parse 24bit signed byte aligned integer
243 : public detail::packet::IntParserOps<Int24Parser,boost::int32_t>,
244 public PacketParserBase
246 Int24Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
248 //-////////////////////////////////////////////////////////////////////////
250 typedef boost::int32_t value_type;
251 static size_type const fixed_bytes = 3;
252 static value_type const min_value = -8388608;
253 static value_type const max_value = 8388607;
255 value_type value() const {
256 value_type v (detail::packet::parse_uint24(i())); return v&0x800000 ? v|0xff000000 : v; }
257 void value(value_type v) { detail::packet::write_uint24(i(),v); }
258 Int24Parser const & operator= (value_type other) { value(other); return *this; }
260 /** \brief Write parsed value to stream
263 inline std::ostream & operator<<(std::ostream & os, Int24Parser const & i)
264 { os << i.value(); return os; }
266 /** \brief Parse 24bit unsigned byte aligned integer
271 : public detail::packet::IntParserOps<UInt24Parser,boost::uint32_t>,
272 public PacketParserBase
274 UInt24Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
276 //-////////////////////////////////////////////////////////////////////////
278 typedef boost::uint32_t value_type;
279 static size_type const fixed_bytes = 3;
280 static value_type const min_value = 0u;
281 static value_type const max_value = 16777215u;
283 value_type value() const { return detail::packet::parse_uint24(i()); }
284 void value(value_type v) { detail::packet::write_uint24(i(),v); }
285 UInt24Parser const & operator= (value_type other) { value(other); return *this; }
287 /** \brief Write parsed value to stream
288 \related UInt24Parser
290 inline std::ostream & operator<<(std::ostream & os, UInt24Parser const & i)
291 { os << i.value(); return os; }
293 /** \brief Parse 32bit signed byte aligned integer
298 : public detail::packet::IntParserOps<Int32Parser,boost::int32_t>,
299 public PacketParserBase
301 Int32Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
303 //-////////////////////////////////////////////////////////////////////////
305 typedef boost::int32_t value_type;
306 static size_type const fixed_bytes = 4;
307 static value_type const min_value = -2147483647 - 1;
308 static value_type const max_value = 2147483647;
310 value_type value() const { return detail::packet::parse_uint32(i()); }
311 void value(value_type v) { detail::packet::write_uint32(i(),v); }
312 Int32Parser const & operator= (value_type other) { value(other); return *this; }
314 /** \brief Write parsed value to stream
317 inline std::ostream & operator<<(std::ostream & os, Int32Parser const & i)
318 { os << i.value(); return os; }
320 /** \brief Parse 32bit unsigned byte aligned integer
325 : public detail::packet::IntParserOps<UInt32Parser,boost::uint32_t>,
326 public PacketParserBase
328 UInt32Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
330 //-////////////////////////////////////////////////////////////////////////
332 typedef boost::uint32_t value_type;
333 static size_type const fixed_bytes = 4;
334 static value_type const min_value = 0u;
335 static value_type const max_value = 4294967295u;
337 value_type value() const { return detail::packet::parse_uint32(i()); }
338 void value(value_type v) { detail::packet::write_uint32(i(),v); }
339 UInt32Parser const & operator= (value_type other) { value(other); return *this; }
341 /** \brief Write parsed value to stream
342 \related UInt32Parser
344 inline std::ostream & operator<<(std::ostream & os, UInt32Parser const & i)
345 { os << i.value(); return os; }
347 struct UInt32LSBParser
348 : public detail::packet::IntParserOps<UInt32LSBParser,boost::uint32_t>,
349 public PacketParserBase
351 UInt32LSBParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
353 //-////////////////////////////////////////////////////////////////////////
355 typedef boost::uint32_t value_type;
356 static size_type const fixed_bytes = 4;
357 static value_type const min_value = 0u;
358 static value_type const max_value = 4294967295u;
360 value_type value() const { return detail::packet::parse_uint32LSB(i()); }
361 void value(value_type v) { detail::packet::write_uint32LSB(i(),v); }
362 UInt32LSBParser const & operator= (value_type other) { value(other); return *this; }
364 /** \brief Write parsed value to stream
365 \related UInt32LSBParser
367 inline std::ostream & operator<<(std::ostream & os, UInt32LSBParser const & i)
368 { os << i.value(); return os; }
373 /** \brief Parse 64bit signed byte aligned integer
378 : public detail::packet::IntParserOps<Int64Parser,boost::int64_t>,
379 public PacketParserBase
381 Int64Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
383 //-////////////////////////////////////////////////////////////////////////
385 typedef boost::int64_t value_type;
386 static size_type const fixed_bytes = 8;
388 value_type value() const { return detail::packet::parse_uint64(i()); }
389 void value(value_type v) { detail::packet::write_uint64(i(),v); }
390 Int64Parser const & operator= (value_type other) { value(other); return *this; }
392 /** \brief Write parsed value to stream
395 inline std::ostream & operator<<(std::ostream & os, Int64Parser const & i)
396 { os << i.value(); return os; }
399 /** \brief Parse 64bit unsigned byte aligned integer
404 : public detail::packet::IntParserOps<UInt64Parser,boost::uint64_t>,
405 public PacketParserBase
407 UInt64Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
409 //-////////////////////////////////////////////////////////////////////////
411 typedef boost::uint64_t value_type;
412 static size_type const fixed_bytes = 8;
414 value_type value() const { return detail::packet::parse_uint64(i()); }
415 void value(value_type v) { detail::packet::write_uint64(i(),v); }
416 UInt64Parser const & operator= (value_type other) { value(other); return *this; }
418 /** \brief Write parsed value to stream
419 \related UInt64Parser
421 inline std::ostream & operator<<(std::ostream & os, UInt64Parser const & i)
422 { os << i.value(); return os; }
424 /** \brief Parse 64bit unsigned byte aligned integer LSB
428 struct UInt64LSBParser
429 : public detail::packet::IntParserOps<UInt64LSBParser,boost::uint64_t>,
430 public PacketParserBase
432 UInt64LSBParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
434 //-////////////////////////////////////////////////////////////////////////
436 typedef boost::uint64_t value_type;
437 static size_type const fixed_bytes = 8;
439 value_type value() const { return detail::packet::parse_uint64LSB(i()); }
440 void value(value_type v) { detail::packet::write_uint64LSB(i(),v); }
441 UInt64LSBParser const & operator= (value_type other) { value(other); return *this; }
443 /** \brief Write parsed value to stream
444 \related UInt64LSBParser
446 inline std::ostream & operator<<(std::ostream & os, UInt64LSBParser const & i)
447 { os << i.value(); return os; }
449 /** \brief Parse signed bitfield with up to 32bit's
451 This parser will parse a bitfield beginning at the bit \a Start and ending \e before \a
452 End. Bits are numbered <em>most significant bit first</em> as this is the customary
453 numbering used when defining packet data structures. \a Start and \a End can be \e
454 arbitrary as long as the field is between 1 and 32 bits in size. In other words, \c
455 IntFieldParser<53,81> is a valid 30 bit field.
457 When defining a compound parser with several bit fields, you need to take care of the fact,
458 that several integer field parsers will interpret the same data \e bytes (but not the same
459 \e bits). It is customary for several integer field parsers to start at the same byte offset
460 with ever increasing bit offsets.
464 \implementation The integer field parser is highly optimized. Since the bit positions are
465 compile-time constants, the compiler will create optimized bit-masks to directly access
466 the value. The parser is also optimized to access the minimum number of data bytes
471 template <unsigned Start, unsigned End>
472 struct IntFieldParser
473 : public detail::packet::IntParserOps<IntFieldParser<Start,End>,boost::int32_t>,
474 public PacketParserBase
476 IntFieldParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
478 //-////////////////////////////////////////////////////////////////////////
480 typedef boost::int32_t value_type;
481 static size_type const start_bit = Start;
482 static size_type const end_bit = End;
483 static size_type const fixed_bytes = (End-1)/8+1;
484 static value_type const max_value = boost::low_bits_mask_t<End-Start-1>::sig_bits;
485 static value_type const min_value = - max_value - 1;
488 value_type value() const {
489 value_type v (detail::packet::parse_bitfield<Start,End>::parse(i()));
490 return v&boost::high_bit_mask_t<End-Start-1>::high_bit ?
491 v | ~boost::low_bits_mask_t<End-Start>::sig_bits : v;
493 void value(value_type v) { detail::packet::parse_bitfield<Start,End>::write(i(),v); }
494 IntFieldParser const & operator= (value_type other) { value(other); return *this; }
497 BOOST_STATIC_ASSERT( Start<End );
498 BOOST_STATIC_ASSERT( End-Start<=32 );
500 /** \brief Write parsed value to stream
501 \related IntFieldParser
503 template <unsigned Start, unsigned End>
504 inline std::ostream & operator<<(std::ostream & os, IntFieldParser<Start,End> const & i)
505 { os << i.value(); return os; }
507 /** \brief Parse unsigned bitfield with up to 32bit's
509 This parser will parse a bitfield beginning at the bit \a Start and ending \e before \a
510 End. Bits are numbered <em>most significant bit first</em> as this is the customary
511 numbering used when defining packet data structures. \a Start and \a End can be \e
512 arbitrary as long as the field is between 1 and 32 bits in size. In other words, \c
513 IntFieldParser<53,81> is a valid 30 bit field.
515 When defining a compound parser with several bit fields, you need to take care of the fact,
516 that several integer field parsers will interpret the same data \e bytes (but not the same
517 \e bits). It is customary for several integer field parsers to start at the same byte offset
518 with ever increasing bit offsets.
522 \implementation The integer field parser is highly optimized. Since the bit positions are
523 compile-time constants, the compiler will create optimized bit-masks to directly access
524 the value. The parser is also optimized to access the minimum number of data bytes
529 template <unsigned Start, unsigned End>
530 struct UIntFieldParser
531 : public detail::packet::IntParserOps<UIntFieldParser<Start,End>,boost::uint32_t>,
532 public PacketParserBase
534 UIntFieldParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
536 //-////////////////////////////////////////////////////////////////////////
538 typedef boost::uint32_t value_type;
539 static size_type const start_bit = Start;
540 static size_type const end_bit = End;
541 static size_type const fixed_bytes = (End-1)/8+1;
542 static value_type const min_value = 0u;
543 static value_type const max_value = boost::low_bits_mask_t<End-Start>::sig_bits;
545 value_type value() const { return detail::packet::parse_bitfield<Start,End>::parse(i()); }
546 void value(value_type v) { detail::packet::parse_bitfield<Start,End>::write(i(),v); }
547 UIntFieldParser const & operator= (value_type other) { value(other); return *this; }
550 BOOST_STATIC_ASSERT( Start<End );
551 BOOST_STATIC_ASSERT( End-Start<=32 );
553 /** \brief Write parsed value to stream
554 \related UIntFieldParser
556 template <unsigned Start, unsigned End>
557 inline std::ostream & operator<<(std::ostream & os, UIntFieldParser<Start,End> const & i)
558 { os << i.value(); return os; }
560 /** \brief Parse single-bit flag
562 This parser will parse a single bit as True/False value. Bits are numbered <em>most
563 significant bit first</em> as this is the customary numbering used when defining packet data
564 structures. \a Bit can be arbitrary, \c FlagParser<75> is a valid flag parser.
566 When defining a compound parser with several bit fields, you need to take care of the fact,
567 that several integer field parsers will interpret the same data \e bytes (but not the same
568 \e bits). It is customary for several integer field parsers to start at the same byte offset
569 with ever increasing bit offsets.
574 template <unsigned Bit>
576 : public detail::packet::IntParserOps<FlagParser<Bit>,bool>,
577 public PacketParserBase
579 FlagParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
581 //-////////////////////////////////////////////////////////////////////////
583 typedef bool value_type;
584 static size_type const bit = Bit;
585 static size_type const fixed_bytes = Bit/8+1;
586 static value_type const min_value = 0;
587 static value_type const max_value = 1;
589 value_type value() const { return i()[Bit/8] & (1<<(7-(Bit%8))); }
590 void value(value_type v) {
591 if (v) i()[Bit/8] |= 1<<(7-(Bit%8));
592 else i()[Bit/8] &= ~(1<<(7-(Bit%8)));
594 FlagParser const & operator= (value_type other) { value(other); return *this; }
596 /** \brief Write parsed value to stream
599 template <unsigned Bit>
600 inline std::ostream & operator<<(std::ostream & os, FlagParser<Bit> const & i)
601 { os << i.value(); return os; }
605 //-/////////////////////////////////////////////////////////////////////////////////////////////////
607 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_IntParser_i_)
608 #define HH_SENF_Packets_IntParser_i_
609 //#include "IntParser.cci"
610 //#include "IntParser.ct"
611 //#include "IntParser.cti"
618 // c-file-style: "senf"
619 // indent-tabs-mode: nil
620 // ispell-local-dictionary: "american"
621 // compile-command: "scons -u test"
622 // comment-column: 40