48b5c9bc91a70bc0b5775cd863ef7a646c03a59a
[senf.git] / Packets / ParseInt.ih
1 // $Id$
2 //
3 // Copyright (C) 2006 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.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 #ifndef IH_ParseInt_
24 #define IH_ParseInt_ 1
25
26 // Custom includes
27
28 ///////////////////////////////ih.p////////////////////////////////////////
29
30 namespace senf {
31
32 namespace impl {
33     
34     ///////////////////////////////////////////////////////////////////////////
35     // Integer operators
36
37     template <class Derived, class Value>
38     class ParseIntOps
39     {
40     public:
41         typedef Value value_type;
42
43         operator Value () const { return derived().value(); }
44
45 #       define unary(op) \
46             Value operator op () const { return op derived().value(); }
47 #       define mutator(op) \
48             template <class Other> Derived const & operator op ## =  (Other other) \
49                 { derived().value( derived().value() op other ); return derived(); }
50
51         unary(~)
52         unary(!)
53         unary(-)
54
55         mutator(+)
56         mutator(-)
57         mutator(*)
58         mutator(/)
59         mutator(%)
60         mutator(<<)
61         mutator(>>)
62         mutator(&)
63         mutator(|)
64         mutator(^)
65
66 #       undef unary
67 #       undef mutator
68             
69         Derived const & operator ++ ()
70             { derived().value( derived.value()+1 ); return derived(); }
71         Derived const & operator -- ()
72             { derived().value( derived.value()-1 ); return derived(); }
73
74         Derived const & operator ++ (int)
75             { Value v (derived.value()); derived().value( v+1 ); return v; }
76         Derived const & operator -- (int)
77             { Value v (derived.value()); derived().value( v-1 ); return v; }
78
79     private:
80         Derived & derived() { return *static_cast<Derived *>(this); }
81         Derived const & derived() const { return *static_cast<Derived const *>(this); };
82     };
83     
84     ///////////////////////////////////////////////////////////////////////////
85     // Network byte order integer extraction
86     
87     template <class Iterator>
88     boost::uint16_t parse_uint16(Iterator const & i)
89     {
90         return i[1] | i[0]<<8;
91     }
92
93     template <class Iterator>
94     void write_uint16(Iterator const & i, boost::uint16_t v)
95     {
96         i[0] = ( v >>  8 ) & 0xff;
97         i[1] = ( v       ) & 0xff;
98     }
99
100     template <class Iterator>
101     boost::uint32_t parse_uint24(Iterator const & i)
102     {
103         return i[2] | i[1]<<8 | i[0]<<16;
104     }
105
106     template <class Iterator>
107     void write_uint24(Iterator const & i, boost::uint32_t v)
108     {
109         i[0] = ( v >> 16 ) & 0xff;
110         i[1] = ( v >>  8 ) & 0xff;
111         i[2] = ( v       ) & 0xff;
112     }
113
114     template <class Iterator>
115     boost::uint32_t parse_uint32(Iterator const & i)
116     {
117         return i[3] | i[2]<<8 | i[1]<<16 | i[0]<<24;
118     }
119
120     template <class Iterator>
121     void write_uint32(Iterator const & i, boost::uint32_t v)
122     {
123         i[0] = ( v >> 24 ) & 0xff;
124         i[1] = ( v >> 16 ) & 0xff;
125         i[2] = ( v >>  8 ) & 0xff;
126         i[3] = ( v       ) & 0xff;
127     }
128
129     ///////////////////////////////////////////////////////////////////////////
130     // bitfield extraction
131
132     template <class Iterator, unsigned offset, unsigned endb, unsigned start, unsigned end>
133     struct parse_bitfield_i
134     {
135         static boost::uint32_t parse(Iterator const & i) {
136             return ( ( ( parse_uint32(i+offset+1)>>(40-end) ) // Beware of sign extension !!
137                        & boost::low_bits_mask_t<32-(40-end)>::sig_bits ) 
138                      | (i[offset]<<(32-(40-end))) )
139                 & boost::low_bits_mask_t<end-start>::sig_bits;
140         }
141
142         static void write(Iterator const & i, boost::uint32_t v) {
143             write_uint32(i+offset+1, 
144                          (parse_uint32(i+offset+1) & ~(boost::low_bits_mask_t<end-8>::sig_bits<<(40-end)))
145                          | ((v & boost::low_bits_mask_t<end-8>::sig_bits) << (40-end)));
146             i[offset] = (i[offset] & ~(boost::low_bits_mask_t<8-start>::sig_bits))
147                 | ((v>>(end-8)) & boost::low_bits_mask_t<8-start>::sig_bits);
148         }
149     };
150
151     template <class Iterator, unsigned offset, unsigned start, unsigned end>
152     struct parse_bitfield_i<Iterator, offset, 3, start, end>
153     {
154         static boost::uint32_t parse(Iterator const & i) {
155             return ( parse_uint32(i+offset)>>(32-end) )
156                 & boost::low_bits_mask_t<end-start>::sig_bits;
157         }
158
159         static void write(Iterator const & i, boost::uint32_t v) {
160             write_uint32(i+offset, 
161                          (parse_uint32(i+offset) & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(32-end)))
162                          | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (32-end)));
163         }
164     };
165
166     template <class Iterator, unsigned offset, unsigned start, unsigned end>
167     struct parse_bitfield_i<Iterator, offset, 2, start, end>
168     {
169         static boost::uint32_t parse(Iterator const & i) {
170             return ( parse_uint24(i+offset)>>(24-end) )
171                 & boost::low_bits_mask_t<end-start>::sig_bits;
172         }
173
174         static void write(Iterator const & i, boost::uint32_t v) {
175             write_uint24(i+offset, 
176                          (parse_uint24(i+offset) & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(24-end)))
177                          | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (24-end)));
178         }
179     };
180
181     template <class Iterator, unsigned offset, unsigned start, unsigned end>
182     struct parse_bitfield_i<Iterator, offset, 1, start, end>
183     {
184         static boost::uint32_t parse(Iterator const & i) {
185             return ( parse_uint16(i+offset)>>(16-end) )
186                 & boost::low_bits_mask_t<end-start>::sig_bits;
187         }
188
189         static void write(Iterator const & i, boost::uint32_t v) {
190             write_uint16(i+offset, 
191                          (parse_uint16(i+offset) & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(16-end)))
192                          | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (16-end)));
193         }
194     };
195
196     template <class Iterator, unsigned offset, unsigned start, unsigned end>
197     struct parse_bitfield_i<Iterator, offset, 0, start, end>
198     {
199         static boost::uint32_t parse(Iterator const & i) {
200             return ( i[offset]>>(8-end) ) 
201                 & boost::low_bits_mask_t<end-start>::sig_bits;
202         }
203
204         static void write(Iterator const & i, boost::uint32_t v) {
205             i[offset] = (i[offset] & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(8-end)))
206                 | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (8-end));
207         }
208     };
209
210     template <class Iterator, unsigned start, unsigned end>
211     struct parse_bitfield 
212         : public parse_bitfield_i<Iterator,start/8,(end-1)/8-start/8,start%8,end-8*(start/8)>
213     {};
214
215 }}
216
217 ///////////////////////////////ih.e////////////////////////////////////////
218 #endif
219
220 \f
221 // Local Variables:
222 // mode: c++
223 // c-file-style: "senf"
224 // End: