e24f42964867a736aa6cbfc6bfb8bb9ccb8b8c9d
[senf.git] / senf / Packets / IntParser.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief IntParser public header */
25
26 #ifndef HH_SENF_Packets_IntParser_
27 #define HH_SENF_Packets_IntParser_ 1
28
29 // Custom includes
30 #include <iostream>
31 #include <boost/cstdint.hpp>
32 #include <boost/static_assert.hpp>
33 #include <boost/integer/integer_mask.hpp>
34 #include "PacketParser.hh"
35
36 //#include "IntParser.mpp"
37 ///////////////////////////////hh.p////////////////////////////////////////
38 #include "IntParser.ih"
39
40 namespace senf {
41
42     /** \defgroup parseint Integer parsers
43
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:
47
48         \li The normal integer parsers with interpret 1-4 byte integers (9, 16, 24, 32 bits) aligned
49             at byte boundaries.
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.
52
53         All fields are parsed in network byte order, the return value of all these parsers is the
54         value in host byte order.
55
56         The interface of all these parsers is the same (p is an arbitrary integer parser instance, v
57         is an integer constant):
58
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.
65
66         \ingroup packetparser
67      */
68
69     /** \brief Parse 8bit signed byte aligned integer
70         \see parseint
71         \ingroup parseint
72      */
73     struct Int8Parser
74         : public detail::packet::IntParserOps<Int8Parser,boost::int8_t>,
75           public PacketParserBase
76     {
77         Int8Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
78
79         ///////////////////////////////////////////////////////////////////////////
80
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;
85
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; }
89     };
90     /** \brief Write parsed value to stream
91         \related Int8Parser
92      */
93     inline std::ostream & operator<<(std::ostream & os, Int8Parser const & i)
94     { os << i.value(); return os; }
95
96     /** \brief Parse 8bit unsigned byte aligned integer
97         \see parseint
98         \ingroup parseint
99      */
100     struct UInt8Parser
101         : public detail::packet::IntParserOps<UInt8Parser,boost::uint8_t>,
102           public PacketParserBase
103     {
104         UInt8Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
105
106         ///////////////////////////////////////////////////////////////////////////
107
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;
112
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; }
116     };
117     /** \brief Write parsed value to stream
118         \related UInt8Parser
119      */
120     inline std::ostream & operator<<(std::ostream & os, UInt8Parser const & i)
121     { os << i.value(); return os; }
122
123     /** \brief Parse 16bit signed byte aligned integer
124         \see parseint
125         \ingroup parseint
126      */
127     struct Int16Parser
128         : public detail::packet::IntParserOps<Int16Parser,boost::int16_t>,
129           public PacketParserBase
130     {
131         Int16Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
132
133         ///////////////////////////////////////////////////////////////////////////
134
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;
139
140
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; }
144     };
145     /** \brief Write parsed value to stream
146         \related Int16Parser
147      */
148     inline std::ostream & operator<<(std::ostream & os, Int16Parser const & i)
149     { os << i.value(); return os; }
150
151     /** \brief Parse 16bit signed byte aligned integer LSB
152         \see parseint
153         \ingroup parseint
154      */
155     struct Int16LSBParser
156         : public detail::packet::IntParserOps<Int16LSBParser,boost::int16_t>,
157           public PacketParserBase
158     {
159         Int16LSBParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
160
161         ///////////////////////////////////////////////////////////////////////////
162
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;
167
168
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; }
172     };
173     /** \brief Write parsed value to stream
174         \related Int16LSBParser
175      */
176     inline std::ostream & operator<<(std::ostream & os, Int16LSBParser const & i)
177     { os << i.value(); return os; }
178
179     /** \brief Parse 16bit unsigned byte aligned integer
180         \see parseint
181         \ingroup parseint
182      */
183     struct UInt16Parser
184         : public detail::packet::IntParserOps<UInt16Parser,boost::uint16_t>,
185           public PacketParserBase
186     {
187         UInt16Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
188
189         ///////////////////////////////////////////////////////////////////////////
190
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;
195
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; }
199     };
200     /** \brief Write parsed value to stream
201         \related UInt16Parser
202      */
203     inline std::ostream & operator<<(std::ostream & os, UInt16Parser const & i)
204     { os << i.value(); return os; }
205
206     /** \brief Parse 16bit unsigned byte aligned integer LSB
207         \see parseint
208         \ingroup parseint
209      */
210     struct UInt16LSBParser
211         : public detail::packet::IntParserOps<UInt16LSBParser,boost::uint16_t>,
212           public PacketParserBase
213     {
214         UInt16LSBParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
215
216         ///////////////////////////////////////////////////////////////////////////
217
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;
222
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; }
226     };
227     /** \brief Write parsed value to stream
228         \related UInt16LSBParser
229      */
230     inline std::ostream & operator<<(std::ostream & os, UInt16LSBParser const & i)
231     { os << i.value(); return os; }
232
233     /** \brief Parse 24bit signed byte aligned integer
234         \see parseint
235         \ingroup parseint
236      */
237     struct Int24Parser
238         : public detail::packet::IntParserOps<Int24Parser,boost::int32_t>,
239           public PacketParserBase
240     {
241         Int24Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
242
243         ///////////////////////////////////////////////////////////////////////////
244
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;
249
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; }
254     };
255     /** \brief Write parsed value to stream
256         \related Int24Parser
257      */
258     inline std::ostream & operator<<(std::ostream & os, Int24Parser const & i)
259     { os << i.value(); return os; }
260
261     /** \brief Parse 24bit unsigned byte aligned integer
262         \see parseint
263         \ingroup parseint
264      */
265     struct UInt24Parser
266         : public detail::packet::IntParserOps<UInt24Parser,boost::uint32_t>,
267           public PacketParserBase
268     {
269         UInt24Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
270
271         ///////////////////////////////////////////////////////////////////////////
272
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;
277
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; }
281     };
282     /** \brief Write parsed value to stream
283         \related UInt24Parser
284      */
285     inline std::ostream & operator<<(std::ostream & os, UInt24Parser const & i)
286     { os << i.value(); return os; }
287
288     /** \brief Parse 32bit signed byte aligned integer
289         \see parseint
290         \ingroup parseint
291      */
292     struct Int32Parser
293         : public detail::packet::IntParserOps<Int32Parser,boost::int32_t>,
294           public PacketParserBase
295     {
296         Int32Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
297
298         ///////////////////////////////////////////////////////////////////////////
299
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;
304
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; }
308     };
309     /** \brief Write parsed value to stream
310         \related Int32Parser
311      */
312     inline std::ostream & operator<<(std::ostream & os, Int32Parser const & i)
313     { os << i.value(); return os; }
314
315     /** \brief Parse 32bit unsigned byte aligned integer
316         \see parseint
317         \ingroup parseint
318      */
319     struct UInt32Parser
320         : public detail::packet::IntParserOps<UInt32Parser,boost::uint32_t>,
321           public PacketParserBase
322     {
323         UInt32Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
324
325         ///////////////////////////////////////////////////////////////////////////
326
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;
331
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; }
335     };
336     /** \brief Write parsed value to stream
337         \related UInt32Parser
338      */
339     inline std::ostream & operator<<(std::ostream & os, UInt32Parser const & i)
340     { os << i.value(); return os; }
341
342     struct UInt32LSBParser
343         : public detail::packet::IntParserOps<UInt32LSBParser,boost::uint32_t>,
344           public PacketParserBase
345     {
346         UInt32LSBParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
347
348         ///////////////////////////////////////////////////////////////////////////
349
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;
354
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; }
358     };
359     /** \brief Write parsed value to stream
360         \related UInt32LSBParser
361      */
362     inline std::ostream & operator<<(std::ostream & os, UInt32LSBParser const & i)
363     { os << i.value(); return os; }
364
365
366
367
368     /** \brief Parse 64bit signed byte aligned integer
369         \see parseint
370         \ingroup parseint
371      */
372     struct Int64Parser
373         : public detail::packet::IntParserOps<Int64Parser,boost::int64_t>,
374           public PacketParserBase
375     {
376         Int64Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
377
378         ///////////////////////////////////////////////////////////////////////////
379
380         typedef boost::int64_t value_type;
381         static size_type const fixed_bytes = 8;
382
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; }
386     };
387     /** \brief Write parsed value to stream
388         \related Int64Parser
389     */
390     inline std::ostream & operator<<(std::ostream & os, Int64Parser const & i)
391     { os << i.value(); return os; }
392
393
394     /** \brief Parse 64bit unsigned byte aligned integer
395         \see parseint
396         \ingroup parseint
397      */
398     struct UInt64Parser
399         : public detail::packet::IntParserOps<UInt64Parser,boost::uint64_t>,
400           public PacketParserBase
401     {
402         UInt64Parser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
403
404         ///////////////////////////////////////////////////////////////////////////
405
406         typedef boost::uint64_t value_type;
407         static size_type const fixed_bytes = 8;
408
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; }
412     };
413     /** \brief Write parsed value to stream
414         \related UInt64Parser
415      */
416     inline std::ostream & operator<<(std::ostream & os, UInt64Parser const & i)
417     { os << i.value(); return os; }
418
419     /** \brief Parse 64bit unsigned byte aligned integer LSB
420         \see parseint
421         \ingroup parseint
422      */
423     struct UInt64LSBParser
424         : public detail::packet::IntParserOps<UInt64LSBParser,boost::uint64_t>,
425           public PacketParserBase
426     {
427         UInt64LSBParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
428
429         ///////////////////////////////////////////////////////////////////////////
430
431         typedef boost::uint64_t value_type;
432         static size_type const fixed_bytes = 8;
433
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; }
437     };
438     /** \brief Write parsed value to stream
439         \related UInt64LSBParser
440      */
441     inline std::ostream & operator<<(std::ostream & os, UInt64LSBParser const & i)
442     { os << i.value(); return os; }
443
444     /** \brief Parse signed bitfield with up to 32bit's
445
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.
451
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.
456
457         \see parseint
458
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
462             necessary.
463
464         \ingroup parseint
465      */
466     template <unsigned Start, unsigned End>
467     struct IntFieldParser
468         : public detail::packet::IntParserOps<IntFieldParser<Start,End>,boost::int32_t>,
469           public PacketParserBase
470     {
471         IntFieldParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
472
473         ///////////////////////////////////////////////////////////////////////////
474
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;
481
482
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;
487         }
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; }
490
491     private:
492         BOOST_STATIC_ASSERT( Start<End );
493         BOOST_STATIC_ASSERT( End-Start<=32 );
494     };
495     /** \brief Write parsed value to stream
496         \related IntFieldParser
497      */
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; }
501
502     /** \brief Parse unsigned bitfield with up to 32bit's
503
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.
509
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.
514
515         \see parseint
516
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
520             necessary.
521
522         \ingroup parseint
523      */
524     template <unsigned Start, unsigned End>
525     struct UIntFieldParser
526         : public detail::packet::IntParserOps<UIntFieldParser<Start,End>,boost::uint32_t>,
527           public PacketParserBase
528     {
529         UIntFieldParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
530
531         ///////////////////////////////////////////////////////////////////////////
532
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;
539
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; }
543
544     private:
545         BOOST_STATIC_ASSERT( Start<End );
546         BOOST_STATIC_ASSERT( End-Start<=32 );
547     };
548     /** \brief Write parsed value to stream
549         \related UIntFieldParser
550      */
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; }
554
555     /** \brief Parse single-bit flag
556
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.
560
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.
565
566         \see parseint
567         \ingroup parseint
568      */
569     template <unsigned Bit>
570     struct FlagParser
571         : public detail::packet::IntParserOps<FlagParser<Bit>,bool>,
572           public PacketParserBase
573     {
574         FlagParser(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
575
576         ///////////////////////////////////////////////////////////////////////////
577
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;
583
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)));
588         }
589         FlagParser const & operator= (value_type other) { value(other); return *this; }
590     };
591     /** \brief Write parsed value to stream
592         \related FlagParser
593      */
594     template <unsigned Bit>
595     inline std::ostream & operator<<(std::ostream & os, FlagParser<Bit> const & i)
596     { os << i.value(); return os; }
597
598 }
599
600 ///////////////////////////////hh.e////////////////////////////////////////
601 #endif
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"
607 #endif
608
609 \f
610 // Local Variables:
611 // mode: c++
612 // fill-column: 100
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
618 // End: