// $Id$ // // Copyright (C) 2006 // Fraunhofer Institute for Open Communication Systems (FOKUS) // // The contents of this file are subject to the Fraunhofer FOKUS Public License // Version 1.0 (the "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // http://senf.berlios.de/license.html // // The Fraunhofer FOKUS Public License Version 1.0 is based on, // but modifies the Mozilla Public License Version 1.1. // See the full license text for the amendments. // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License // for the specific language governing rights and limitations under the License. // // The Original Code is Fraunhofer FOKUS code. // // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. // (registered association), Hansastraße 27 c, 80686 Munich, Germany. // All Rights Reserved. // // Contributor(s): // Stefan Bund /** \file \brief IntParser internal header */ #ifndef IH_SENF_Packets_IntParser_ #define IH_SENF_Packets_IntParser_ 1 // Custom includes #include "PacketTypes.hh" //-///////////////////////////////////////////////////////////////////////////////////////////////// namespace senf { namespace detail { namespace packet { //-///////////////////////////////////////////////////////////////////////////////////////////// // Integer operators /** \brief Internal: Integer operation mixin for integer parsers \internal This class contains all the integer operations supported by the integer parsers. It is inherited by each integer parser. */ template class IntParserOps { public: typedef Value value_type; operator Value () const { return derived().value(); } # define unary(op) \ Value operator op () const { return op derived().value(); } # define mutator(op) \ template Derived const & operator op ## = (Other other) \ { derived().value( derived().value() op other ); return derived(); } unary(~) unary(!) unary(-) mutator(+) mutator(-) mutator(*) mutator(/) mutator(%) mutator(<<) mutator(>>) mutator(&) mutator(|) mutator(^) # undef unary # undef mutator Derived const & operator ++ () { derived().value( derived().value()+1 ); return derived(); } Derived const & operator -- () { derived().value( derived().value()-1 ); return derived(); } Value operator ++ (int) { Value v (derived().value()); derived().value( v+1 ); return v; } Value operator -- (int) { Value v (derived().value()); derived().value( v-1 ); return v; } private: Derived & derived() { return *static_cast(this); } Derived const & derived() const { return *static_cast(this); }; }; //-///////////////////////////////////////////////////////////////////////////////////////////// // Network byte order integer extraction /** \brief Internal: Extract 16bit network byte order value \internal */ inline boost::uint16_t parse_uint16(iterator i) { return i[1] | i[0]<<8; } /** \brief Internal: Write 16bit network byte order value \internal */ inline void write_uint16(iterator i, boost::uint16_t v) { i[0] = ( v >> 8 ) & 0xff; i[1] = ( v ) & 0xff; } /** \brief Internal: Extract 16bit least significant bit order value \internal */ inline boost::uint16_t parse_uint16LSB(iterator i) { return i[0] | i[1]<<8; } /** \brief Internal: Write 16bit least significant bit order value \internal */ inline void write_uint16LSB(iterator i, boost::uint16_t v) { i[0] = ( v ) & 0xff; i[1] = ( v >> 8 ) & 0xff; } /** \brief Internal: Extract 24bit network byte order value \internal */ inline boost::uint32_t parse_uint24(iterator i) { return i[2] | i[1]<<8 | i[0]<<16; } /** \brief Internal: Write 24bit network byte order value \internal */ inline void write_uint24(iterator i, boost::uint32_t v) { i[0] = ( v >> 16 ) & 0xff; i[1] = ( v >> 8 ) & 0xff; i[2] = ( v ) & 0xff; } /** \brief Internal: Extract 32bit network byte order value \internal */ inline boost::uint32_t parse_uint32(iterator i) { return i[3] | i[2]<<8 | i[1]<<16 | i[0]<<24; } /** \brief Internal: Write 32bit network byte order value \internal */ inline void write_uint32(iterator i, boost::uint32_t v) { i[0] = ( v >> 24 ) & 0xff; i[1] = ( v >> 16 ) & 0xff; i[2] = ( v >> 8 ) & 0xff; i[3] = ( v ) & 0xff; } /** \brief Internal: Extract 32bit network byte order value \internal */ inline boost::uint32_t parse_uint32LSB(iterator i) { return i[0] | i[1]<<8 | i[2]<<16 | i[3]<<24; } /** \brief Internal: Write 32bit network byte order value \internal */ inline void write_uint32LSB(iterator i, boost::uint32_t v) { i[3] = ( v >> 24 ) & 0xff; i[2] = ( v >> 16 ) & 0xff; i[1] = ( v >> 8 ) & 0xff; i[0] = ( v ) & 0xff; } /** \brief Internal: Extract 64bit network byte order value \internal */ inline boost::uint64_t parse_uint64(iterator i) { return ((boost::uint64_t)i[7]) | ((boost::uint64_t)i[6])<<8 | ((boost::uint64_t)i[5])<<16 | ((boost::uint64_t)i[4])<<24 | ((boost::uint64_t)i[3])<<32 | ((boost::uint64_t)i[2])<<40 | ((boost::uint64_t)i[1])<<48 | ((boost::uint64_t)i[0])<<56; } /** \brief Internal: Write 64bit network byte order value \internal */ inline void write_uint64(iterator i, boost::uint64_t v) { i[0] = ( v >> 56 ) & 0xff; i[1] = ( v >> 48 ) & 0xff; i[2] = ( v >> 40 ) & 0xff; i[3] = ( v >> 32 ) & 0xff; i[4] = ( v >> 24 ) & 0xff; i[5] = ( v >> 16 ) & 0xff; i[6] = ( v >> 8 ) & 0xff; i[7] = ( v ) & 0xff; } /** \brief Internal: Extract 64bit least significant bit order value \internal */ inline boost::uint64_t parse_uint64LSB(iterator i) { return ((boost::uint64_t)i[0]) | ((boost::uint64_t)i[1])<<8 | ((boost::uint64_t)i[2])<<16 | ((boost::uint64_t)i[3])<<24 | ((boost::uint64_t)i[4])<<32 | ((boost::uint64_t)i[5])<<40 | ((boost::uint64_t)i[6])<<48 | ((boost::uint64_t)i[7])<<56; } /** \brief Internal: Write 64bit least significant bit order value \internal */ inline void write_uint64LSB(iterator i, boost::uint64_t v) { i[0] = ( v ) & 0xff; i[1] = ( v >> 8 ) & 0xff; i[2] = ( v >> 16 ) & 0xff; i[3] = ( v >> 24 ) & 0xff; i[4] = ( v >> 32 ) & 0xff; i[5] = ( v >> 40 ) & 0xff; i[6] = ( v >> 48 ) & 0xff; i[7] = ( v >> 56 ) & 0xff; } //-///////////////////////////////////////////////////////////////////////////////////////////// // bitfield extraction // Doxygen doesn't like this stuff ... # ifndef DOXYGEN template struct parse_bitfield_i { static boost::uint32_t parse(iterator i) { return ( ( ( parse_uint32(i+offset+1)>>(40-end) ) // Beware of sign extension !! & boost::low_bits_mask_t<32-(40-end)>::sig_bits ) | (i[offset]<<(32-(40-end))) ) & boost::low_bits_mask_t::sig_bits; } static void write(iterator i, boost::uint32_t v) { write_uint32(i+offset+1, (parse_uint32(i+offset+1) & ~(boost::low_bits_mask_t::sig_bits<<(40-end))) | ((v & boost::low_bits_mask_t::sig_bits) << (40-end))); i[offset] = (i[offset] & ~(boost::low_bits_mask_t<8-start>::sig_bits)) | ((v>>(end-8)) & boost::low_bits_mask_t<8-start>::sig_bits); } }; template struct parse_bitfield_i { static boost::uint32_t parse(iterator i) { return ( parse_uint32(i+offset)>>(32-end) ) & boost::low_bits_mask_t::sig_bits; } static void write(iterator i, boost::uint32_t v) { write_uint32(i+offset, (parse_uint32(i+offset) & ~(boost::low_bits_mask_t::sig_bits<<(32-end))) | ((v & boost::low_bits_mask_t::sig_bits) << (32-end))); } }; template struct parse_bitfield_i { static boost::uint32_t parse(iterator i) { return ( parse_uint24(i+offset)>>(24-end) ) & boost::low_bits_mask_t::sig_bits; } static void write(iterator i, boost::uint32_t v) { write_uint24(i+offset, (parse_uint24(i+offset) & ~(boost::low_bits_mask_t::sig_bits<<(24-end))) | ((v & boost::low_bits_mask_t::sig_bits) << (24-end))); } }; template struct parse_bitfield_i { static boost::uint32_t parse(iterator i) { return ( parse_uint16(i+offset)>>(16-end) ) & boost::low_bits_mask_t::sig_bits; } static void write(iterator i, boost::uint32_t v) { write_uint16(i+offset, (parse_uint16(i+offset) & ~(boost::low_bits_mask_t::sig_bits<<(16-end))) | ((v & boost::low_bits_mask_t::sig_bits) << (16-end))); } }; template struct parse_bitfield_i { static boost::uint32_t parse(iterator i) { return ( i[offset]>>(8-end) ) & boost::low_bits_mask_t::sig_bits; } static void write(iterator i, boost::uint32_t v) { i[offset] = (i[offset] & ~(boost::low_bits_mask_t::sig_bits<<(8-end))) | ((v & boost::low_bits_mask_t::sig_bits) << (8-end)); } }; # endif /** \brief Internal: Bitfield read/write helper \internal Using template specializations, this class provides optimized bitfield parsers and writers. For each number of bytes the bitfield covers (from 1 to 5 bytes), a template specialization is provided in \c parse_bitfield_i. This helper always processes unsigned values. For signed values sign extension still needs to be performed. */ template struct parse_bitfield : public parse_bitfield_i {}; }}} //-///////////////////////////////////////////////////////////////////////////////////////////////// #endif // Local Variables: // mode: c++ // fill-column: 100 // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" // compile-command: "scons -u test" // comment-column: 40 // End: