Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

IntParser.ih

Go to the documentation of this file.
00001 // $Id: IntParser.ih 1742 2010-11-04 14:51:56Z g0dil $
00002 //
00003 // Copyright (C) 2006
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00026 #ifndef IH_SENF_Packets_IntParser_
00027 #define IH_SENF_Packets_IntParser_ 1
00028 
00029 // Custom includes
00030 #include "PacketTypes.hh"
00031 
00032 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00033 
00034 namespace senf {
00035 namespace detail {
00036 namespace packet {
00037 
00038     //-/////////////////////////////////////////////////////////////////////////////////////////////
00039     // Integer operators
00040 
00048     template <class Derived, class Value>
00049     class IntParserOps
00050     {
00051     public:
00052         typedef Value value_type;
00053 
00054         operator Value () const { return derived().value(); }
00055 
00056 #       define unary(op) \
00057             Value operator op () const { return op derived().value(); }
00058 #       define mutator(op) \
00059             template <class Other> Derived const & operator op ## =  (Other other) \
00060                 { derived().value( derived().value() op other ); return derived(); }
00061 
00062         unary(~)
00063         unary(!)
00064         unary(-)
00065 
00066         mutator(+)
00067         mutator(-)
00068         mutator(*)
00069         mutator(/)
00070         mutator(%)
00071         mutator(<<)
00072         mutator(>>)
00073         mutator(&)
00074         mutator(|)
00075         mutator(^)
00076 
00077 #       undef unary
00078 #       undef mutator
00079 
00080         Derived const & operator ++ ()
00081             { derived().value( derived().value()+1 ); return derived(); }
00082         Derived const & operator -- ()
00083             { derived().value( derived().value()-1 ); return derived(); }
00084 
00085         Value operator ++ (int)
00086             { Value v (derived().value()); derived().value( v+1 ); return v; }
00087         Value operator -- (int)
00088             { Value v (derived().value()); derived().value( v-1 ); return v; }
00089 
00090     private:
00091         Derived & derived() { return *static_cast<Derived *>(this); }
00092         Derived const & derived() const { return *static_cast<Derived const *>(this); };
00093     };
00094 
00095     //-/////////////////////////////////////////////////////////////////////////////////////////////
00096     // Network byte order integer extraction
00097 
00102     inline boost::uint16_t parse_uint16(iterator i)
00103     {
00104         return i[1] | i[0]<<8;
00105     }
00106 
00111     inline void write_uint16(iterator i, boost::uint16_t v)
00112     {
00113         i[0] = ( v >>  8 ) & 0xff;
00114         i[1] = ( v       ) & 0xff;
00115     }
00116 
00121     inline boost::uint16_t parse_uint16LSB(iterator i)
00122     {
00123         return i[0] | i[1]<<8;
00124     }
00125 
00130     inline void write_uint16LSB(iterator i, boost::uint16_t v)
00131     {
00132         i[0] = ( v       ) & 0xff;
00133         i[1] = ( v >>  8 ) & 0xff;
00134     }
00135 
00140     inline boost::uint32_t parse_uint24(iterator i)
00141     {
00142         return i[2] | i[1]<<8 | i[0]<<16;
00143     }
00144 
00149     inline void write_uint24(iterator i, boost::uint32_t v)
00150     {
00151         i[0] = ( v >> 16 ) & 0xff;
00152         i[1] = ( v >>  8 ) & 0xff;
00153         i[2] = ( v       ) & 0xff;
00154     }
00155 
00160     inline boost::uint32_t parse_uint32(iterator i)
00161     {
00162         return i[3] | i[2]<<8 | i[1]<<16 | i[0]<<24;
00163     }
00164 
00169     inline void write_uint32(iterator i, boost::uint32_t v)
00170     {
00171         i[0] = ( v >> 24 ) & 0xff;
00172         i[1] = ( v >> 16 ) & 0xff;
00173         i[2] = ( v >>  8 ) & 0xff;
00174         i[3] = ( v       ) & 0xff;
00175     }
00176 
00181     inline boost::uint32_t parse_uint32LSB(iterator i)
00182     {
00183         return i[0] | i[1]<<8 | i[2]<<16 | i[3]<<24;
00184     }
00185 
00190     inline void write_uint32LSB(iterator i, boost::uint32_t v)
00191     {
00192         i[3] = ( v >> 24 ) & 0xff;
00193         i[2] = ( v >> 16 ) & 0xff;
00194         i[1] = ( v >>  8 ) & 0xff;
00195         i[0] = ( v       ) & 0xff;
00196     }
00197 
00202     inline boost::uint64_t parse_uint64(iterator i)
00203     {
00204         return ((boost::uint64_t)i[7]) | ((boost::uint64_t)i[6])<<8
00205                 | ((boost::uint64_t)i[5])<<16 | ((boost::uint64_t)i[4])<<24
00206                 | ((boost::uint64_t)i[3])<<32 | ((boost::uint64_t)i[2])<<40
00207                 | ((boost::uint64_t)i[1])<<48 | ((boost::uint64_t)i[0])<<56;
00208     }
00209 
00214     inline void write_uint64(iterator i, boost::uint64_t v)
00215     {
00216         i[0] = ( v >> 56 ) & 0xff;
00217         i[1] = ( v >> 48 ) & 0xff;
00218         i[2] = ( v >> 40 ) & 0xff;
00219         i[3] = ( v >> 32 ) & 0xff;
00220         i[4] = ( v >> 24 ) & 0xff;
00221         i[5] = ( v >> 16 ) & 0xff;
00222         i[6] = ( v >> 8  ) & 0xff;
00223         i[7] = ( v       ) & 0xff;
00224     }
00225 
00230     inline boost::uint64_t parse_uint64LSB(iterator i)
00231     {
00232         return ((boost::uint64_t)i[0]) | ((boost::uint64_t)i[1])<<8
00233                 | ((boost::uint64_t)i[2])<<16 | ((boost::uint64_t)i[3])<<24
00234                 | ((boost::uint64_t)i[4])<<32 | ((boost::uint64_t)i[5])<<40
00235                 | ((boost::uint64_t)i[6])<<48 | ((boost::uint64_t)i[7])<<56;
00236     }
00237 
00242     inline void write_uint64LSB(iterator i, boost::uint64_t v)
00243     {
00244         i[0] = ( v       ) & 0xff;
00245         i[1] = ( v >> 8  ) & 0xff;
00246         i[2] = ( v >> 16 ) & 0xff;
00247         i[3] = ( v >> 24 ) & 0xff;
00248         i[4] = ( v >> 32 ) & 0xff;
00249         i[5] = ( v >> 40 ) & 0xff;
00250         i[6] = ( v >> 48 ) & 0xff;
00251         i[7] = ( v >> 56 ) & 0xff;
00252     }
00253 
00254     //-/////////////////////////////////////////////////////////////////////////////////////////////
00255     // bitfield extraction
00256 
00257     // Doxygen doesn't like this stuff ...
00258 
00259 #   ifndef DOXYGEN
00260 
00261     template <unsigned offset, unsigned endb, unsigned start, unsigned end>
00262     struct parse_bitfield_i
00263     {
00264         static boost::uint32_t parse(iterator i) {
00265             return ( ( ( parse_uint32(i+offset+1)>>(40-end) ) // Beware of sign extension !!
00266                        & boost::low_bits_mask_t<32-(40-end)>::sig_bits )
00267                      | (i[offset]<<(32-(40-end))) )
00268                 & boost::low_bits_mask_t<end-start>::sig_bits;
00269         }
00270 
00271         static void write(iterator i, boost::uint32_t v) {
00272             write_uint32(i+offset+1,
00273                          (parse_uint32(i+offset+1) & ~(boost::low_bits_mask_t<end-8>::sig_bits<<(40-end)))
00274                          | ((v & boost::low_bits_mask_t<end-8>::sig_bits) << (40-end)));
00275             i[offset] = (i[offset] & ~(boost::low_bits_mask_t<8-start>::sig_bits))
00276                 | ((v>>(end-8)) & boost::low_bits_mask_t<8-start>::sig_bits);
00277         }
00278     };
00279 
00280     template <unsigned offset, unsigned start, unsigned end>
00281     struct parse_bitfield_i<offset, 3, start, end>
00282     {
00283         static boost::uint32_t parse(iterator i) {
00284             return ( parse_uint32(i+offset)>>(32-end) )
00285                 & boost::low_bits_mask_t<end-start>::sig_bits;
00286         }
00287 
00288         static void write(iterator i, boost::uint32_t v) {
00289             write_uint32(i+offset,
00290                          (parse_uint32(i+offset) & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(32-end)))
00291                          | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (32-end)));
00292         }
00293     };
00294 
00295     template <unsigned offset, unsigned start, unsigned end>
00296     struct parse_bitfield_i<offset, 2, start, end>
00297     {
00298         static boost::uint32_t parse(iterator i) {
00299             return ( parse_uint24(i+offset)>>(24-end) )
00300                 & boost::low_bits_mask_t<end-start>::sig_bits;
00301         }
00302 
00303         static void write(iterator i, boost::uint32_t v) {
00304             write_uint24(i+offset,
00305                          (parse_uint24(i+offset) & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(24-end)))
00306                          | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (24-end)));
00307         }
00308     };
00309 
00310     template <unsigned offset, unsigned start, unsigned end>
00311     struct parse_bitfield_i<offset, 1, start, end>
00312     {
00313         static boost::uint32_t parse(iterator i) {
00314             return ( parse_uint16(i+offset)>>(16-end) )
00315                 & boost::low_bits_mask_t<end-start>::sig_bits;
00316         }
00317 
00318         static void write(iterator i, boost::uint32_t v) {
00319             write_uint16(i+offset,
00320                          (parse_uint16(i+offset) & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(16-end)))
00321                          | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (16-end)));
00322         }
00323     };
00324 
00325     template <unsigned offset, unsigned start, unsigned end>
00326     struct parse_bitfield_i<offset, 0, start, end>
00327     {
00328         static boost::uint32_t parse(iterator i) {
00329             return ( i[offset]>>(8-end) )
00330                 & boost::low_bits_mask_t<end-start>::sig_bits;
00331         }
00332 
00333         static void write(iterator i, boost::uint32_t v) {
00334             i[offset] = (i[offset] & ~(boost::low_bits_mask_t<end-start>::sig_bits<<(8-end)))
00335                 | ((v & boost::low_bits_mask_t<end-start>::sig_bits) << (8-end));
00336         }
00337     };
00338 
00339 #   endif
00340 
00352     template <unsigned start, unsigned end>
00353     struct parse_bitfield
00354         : public parse_bitfield_i<start/8,(end-1)/8-start/8,start%8,end-8*(start/8)>
00355     {};
00356 
00357 }}}
00358 
00359 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00360 #endif
00361 
00362 
00363 // Local Variables:
00364 // mode: c++
00365 // fill-column: 100
00366 // c-file-style: "senf"
00367 // indent-tabs-mode: nil
00368 // ispell-local-dictionary: "american"
00369 // compile-command: "scons -u test"
00370 // comment-column: 40
00371 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research