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 internal header */
31 #ifndef IH_SENF_Packets_IntParser_
32 #define IH_SENF_Packets_IntParser_ 1
35 #include "PacketTypes.hh"
37 //-/////////////////////////////////////////////////////////////////////////////////////////////////
43 //-/////////////////////////////////////////////////////////////////////////////////////////////
46 /** \brief Internal: Integer operation mixin for integer parsers
50 This class contains all the integer operations supported by the integer parsers. It is
51 inherited by each integer parser.
53 template <class Derived, class Value>
57 typedef Value value_type;
59 operator Value () const { return derived().value(); }
62 Value operator op () const { return op derived().value(); }
63 # define mutator(op) \
64 template <class Other> Derived const & operator op ## = (Other other) \
65 { derived().value( derived().value() op other ); return derived(); }
85 Derived const & operator ++ ()
86 { derived().value( derived().value()+1 ); return derived(); }
87 Derived const & operator -- ()
88 { derived().value( derived().value()-1 ); return derived(); }
90 Value operator ++ (int)
91 { Value v (derived().value()); derived().value( v+1 ); return v; }
92 Value operator -- (int)
93 { Value v (derived().value()); derived().value( v-1 ); return v; }
96 Derived & derived() { return *static_cast<Derived *>(this); }
97 Derived const & derived() const { return *static_cast<Derived const *>(this); };
100 //-/////////////////////////////////////////////////////////////////////////////////////////////
101 // Network byte order integer extraction
103 /** \brief Internal: Extract 16bit network byte order value
107 inline boost::uint16_t parse_uint16(iterator i)
109 return i[1] | i[0]<<8;
112 /** \brief Internal: Write 16bit network byte order value
116 inline void write_uint16(iterator i, boost::uint16_t v)
118 i[0] = ( v >> 8 ) & 0xff;
122 /** \brief Internal: Extract 16bit least significant bit order value
126 inline boost::uint16_t parse_uint16LSB(iterator i)
128 return i[0] | i[1]<<8;
131 /** \brief Internal: Write 16bit least significant bit order value
135 inline void write_uint16LSB(iterator i, boost::uint16_t v)
138 i[1] = ( v >> 8 ) & 0xff;
141 /** \brief Internal: Extract 24bit network byte order value
145 inline boost::uint32_t parse_uint24(iterator i)
147 return i[2] | i[1]<<8 | i[0]<<16;
150 /** \brief Internal: Write 24bit network byte order value
154 inline void write_uint24(iterator i, boost::uint32_t v)
156 i[0] = ( v >> 16 ) & 0xff;
157 i[1] = ( v >> 8 ) & 0xff;
161 /** \brief Internal: Extract 32bit network byte order value
165 inline boost::uint32_t parse_uint32(iterator i)
167 return i[3] | i[2]<<8 | i[1]<<16 | i[0]<<24;
170 /** \brief Internal: Write 32bit network byte order value
174 inline void write_uint32(iterator i, boost::uint32_t v)
176 i[0] = ( v >> 24 ) & 0xff;
177 i[1] = ( v >> 16 ) & 0xff;
178 i[2] = ( v >> 8 ) & 0xff;
182 /** \brief Internal: Extract 32bit network byte order value
186 inline boost::uint32_t parse_uint32LSB(iterator i)
188 return i[0] | i[1]<<8 | i[2]<<16 | i[3]<<24;
191 /** \brief Internal: Write 32bit network byte order value
195 inline void write_uint32LSB(iterator i, boost::uint32_t v)
197 i[3] = ( v >> 24 ) & 0xff;
198 i[2] = ( v >> 16 ) & 0xff;
199 i[1] = ( v >> 8 ) & 0xff;
203 /** \brief Internal: Extract 64bit network byte order value
207 inline boost::uint64_t parse_uint64(iterator i)
209 return ((boost::uint64_t)i[7]) | ((boost::uint64_t)i[6])<<8
210 | ((boost::uint64_t)i[5])<<16 | ((boost::uint64_t)i[4])<<24
211 | ((boost::uint64_t)i[3])<<32 | ((boost::uint64_t)i[2])<<40
212 | ((boost::uint64_t)i[1])<<48 | ((boost::uint64_t)i[0])<<56;
215 /** \brief Internal: Write 64bit network byte order value
219 inline void write_uint64(iterator i, boost::uint64_t v)
221 i[0] = ( v >> 56 ) & 0xff;
222 i[1] = ( v >> 48 ) & 0xff;
223 i[2] = ( v >> 40 ) & 0xff;
224 i[3] = ( v >> 32 ) & 0xff;
225 i[4] = ( v >> 24 ) & 0xff;
226 i[5] = ( v >> 16 ) & 0xff;
227 i[6] = ( v >> 8 ) & 0xff;
231 /** \brief Internal: Extract 64bit least significant bit order value
235 inline boost::uint64_t parse_uint64LSB(iterator i)
237 return ((boost::uint64_t)i[0]) | ((boost::uint64_t)i[1])<<8
238 | ((boost::uint64_t)i[2])<<16 | ((boost::uint64_t)i[3])<<24
239 | ((boost::uint64_t)i[4])<<32 | ((boost::uint64_t)i[5])<<40
240 | ((boost::uint64_t)i[6])<<48 | ((boost::uint64_t)i[7])<<56;
243 /** \brief Internal: Write 64bit least significant bit order value
247 inline void write_uint64LSB(iterator i, boost::uint64_t v)
250 i[1] = ( v >> 8 ) & 0xff;
251 i[2] = ( v >> 16 ) & 0xff;
252 i[3] = ( v >> 24 ) & 0xff;
253 i[4] = ( v >> 32 ) & 0xff;
254 i[5] = ( v >> 40 ) & 0xff;
255 i[6] = ( v >> 48 ) & 0xff;
256 i[7] = ( v >> 56 ) & 0xff;
259 //-/////////////////////////////////////////////////////////////////////////////////////////////
260 // bitfield extraction
262 // Doxygen doesn't like this stuff ...
266 template <unsigned offset, unsigned endb, unsigned start, unsigned end>
267 struct parse_bitfield_i
269 static boost::uint32_t parse(iterator i) {
270 return ( ( ( parse_uint32(i+offset+1)>>(40-end) ) // Beware of sign extension !!
271 & boost::low_bits_mask_t<32-(40-end)>::sig_bits )
272 | (i[offset]<<(32-(40-end))) )
273 & boost::low_bits_mask_t<end-start>::sig_bits;
276 static void write(iterator i, boost::uint32_t v) {
277 write_uint32(i+offset+1,
278 (parse_uint32(i+offset+1) & ~(boost::low_bits_mask_t<end-8>::sig_bits<<(40-end)))
279 | ((v & boost::low_bits_mask_t<end-8>::sig_bits) << (40-end)));
280 i[offset] = (i[offset] & ~(boost::low_bits_mask_t<8-start>::sig_bits))
281 | ((v>>(end-8)) & boost::low_bits_mask_t<8-start>::sig_bits);
285 template <unsigned offset, unsigned start, unsigned end>
286 struct parse_bitfield_i<offset, 3, start, end>
288 static boost::uint32_t parse(iterator i) {
289 return ( parse_uint32(i+offset)>>(32-end) )
290 & boost::low_bits_mask_t<end-start>::sig_bits;
293 static void write(iterator i, boost::uint32_t v) {
294 write_uint32(i+offset,
295 (parse_uint32(i+offset) & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(32-end)))
296 | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (32-end)));
300 template <unsigned offset, unsigned start, unsigned end>
301 struct parse_bitfield_i<offset, 2, start, end>
303 static boost::uint32_t parse(iterator i) {
304 return ( parse_uint24(i+offset)>>(24-end) )
305 & boost::low_bits_mask_t<end-start>::sig_bits;
308 static void write(iterator i, boost::uint32_t v) {
309 write_uint24(i+offset,
310 (parse_uint24(i+offset) & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(24-end)))
311 | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (24-end)));
315 template <unsigned offset, unsigned start, unsigned end>
316 struct parse_bitfield_i<offset, 1, start, end>
318 static boost::uint32_t parse(iterator i) {
319 return ( parse_uint16(i+offset)>>(16-end) )
320 & boost::low_bits_mask_t<end-start>::sig_bits;
323 static void write(iterator i, boost::uint32_t v) {
324 write_uint16(i+offset,
325 (parse_uint16(i+offset) & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(16-end)))
326 | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (16-end)));
330 template <unsigned offset, unsigned start, unsigned end>
331 struct parse_bitfield_i<offset, 0, start, end>
333 static boost::uint32_t parse(iterator i) {
334 return ( i[offset]>>(8-end) )
335 & boost::low_bits_mask_t<end-start>::sig_bits;
338 static void write(iterator i, boost::uint32_t v) {
339 i[offset] = (i[offset] & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(8-end)))
340 | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (8-end));
346 /** \brief Internal: Bitfield read/write helper
350 Using template specializations, this class provides optimized bitfield parsers and
351 writers. For each number of bytes the bitfield covers (from 1 to 5 bytes), a template
352 specialization is provided in \c parse_bitfield_i.
354 This helper always processes unsigned values. For signed values sign extension still needs
357 template <unsigned start, unsigned end>
358 struct parse_bitfield
359 : public parse_bitfield_i<start/8,(end-1)/8-start/8,start%8,end-8*(start/8)>
364 //-/////////////////////////////////////////////////////////////////////////////////////////////////
371 // c-file-style: "senf"
372 // indent-tabs-mode: nil
373 // ispell-local-dictionary: "american"
374 // compile-command: "scons -u test"
375 // comment-column: 40