X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FParseInt.hh;h=ee97811b906d3b182bc71ab3be62da3e8ea48f20;hb=81ffa1c459b96dd44472bcef37e1e373934ee138;hp=0d4f4f349bdfd677fa6e2488e6a25d41ae3f537d;hpb=85ab07d100a382467a42e19d741d403a7a96c951;p=senf.git diff --git a/Packets/ParseInt.hh b/Packets/ParseInt.hh index 0d4f4f3..ee97811 100644 --- a/Packets/ParseInt.hh +++ b/Packets/ParseInt.hh @@ -20,15 +20,18 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +/** \file + \brief ParseInt public header */ + #ifndef HH_ParseInt_ #define HH_ParseInt_ 1 // Custom includes #include -#include "ParserBase.hh" #include #include #include +#include "PacketParser.hh" //#include "ParseInt.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -36,312 +39,382 @@ namespace senf { + /** \defgroup parseint Integer parsers - template - struct Parse_Int8 - : public impl::ParseIntOps,boost::int8_t>, - public ParserBase - { - template - struct rebind { typedef Parse_Int8 parser; }; - typedef Iterator byte_iterator; + Most packet fields will ultimately contain some type of integral number. The integer parsers + allow to parse arbitrary integers in network byte order from 1-32 bit, both signed and + unsigned. There are two types of integer parsers: + + \li The normal integer parsers with interpret 1-4 byte integers (9, 16, 24, 32 bits) aligned + at byte boundaries. + \li The bitfield parsers which parse integers with 1-32 bits aligned at any bit. A special + case is the single bit flag parser. + + All fields are parsed in network byte order, the return value of all these parsers is the + value in host byte order. - static unsigned bytes() { return 1; } + The interface of all these parsers is the same (p is an arbitrary integer parser instance, v + is an integer constant): - Parse_Int8() {} - explicit Parse_Int8(Iterator const & i) : ParserBase(i) {} + \li p = v: Assigns the value to the packet field. + \li p.value(v): same as above. + \li p.value(): Returns the fields value as an integer number. + \li Use of p like an integer in most contexts: p += v, p *= v, v = p + + 1 and so on. You will only need to use the explicit \c value() member in rare + circumstances when the automatic conversion is ambiguous or in some template contexts. + + \ingroup packetparser + */ + + /** \brief Parse 8bit signed byte aligned integer + \see parseint + \ingroup parseint + */ + struct Parse_Int8 + : public detail::packet::ParseIntOps, + public PacketParserBase + { + Parse_Int8(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {} /////////////////////////////////////////////////////////////////////////// typedef boost::int8_t value_type; + static size_type const fixed_bytes = 1; - value_type value() const { return this->i()[0]; } - void value(value_type v) { this->i()[0] = v; } + value_type value() const { return i()[0]; } + void value(value_type v) { i()[0] = v; } Parse_Int8 const & operator= (value_type other) { value(other); return *this; } }; - template - std::ostream & operator<<(std::ostream & os, Parse_Int8 const & i) + /** \brief Write parsed value to stream + \related Parse_Int8 + */ + inline std::ostream & operator<<(std::ostream & os, Parse_Int8 const & i) { os << i.value(); return os; } - template + /** \brief Parse 8bit unsigned byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_UInt8 - : public impl::ParseIntOps,boost::uint8_t>, - public ParserBase + : public detail::packet::ParseIntOps, + public PacketParserBase { - template - struct rebind { typedef Parse_UInt8 parser; }; - typedef Iterator byte_iterator; - - static unsigned bytes() { return 1; } - - Parse_UInt8() {} - explicit Parse_UInt8(Iterator const & i) : ParserBase(i) {} + Parse_UInt8(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {} /////////////////////////////////////////////////////////////////////////// typedef boost::uint8_t value_type; + static size_type const fixed_bytes = 1; - value_type value() const { return this->i()[0]; } - void value(value_type v) { this->i()[0] = v; } + value_type value() const { return i()[0]; } + void value(value_type v) { i()[0] = v; } Parse_UInt8 const & operator= (value_type other) { value(other); return *this; } }; - template - std::ostream & operator<<(std::ostream & os, Parse_UInt8 const & i) + /** \brief Write parsed value to stream + \related Parse_UInt8 + */ + inline std::ostream & operator<<(std::ostream & os, Parse_UInt8 const & i) { os << i.value(); return os; } - template + /** \brief Parse 16bit signed byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_Int16 - : public impl::ParseIntOps,boost::int16_t>, - public ParserBase + : public detail::packet::ParseIntOps, + public PacketParserBase { - template - struct rebind { typedef Parse_Int16 parser; }; - typedef Iterator byte_iterator; - - static unsigned bytes() { return 2; } - - Parse_Int16() {} - explicit Parse_Int16(Iterator const & i) : ParserBase(i) {} + Parse_Int16(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {} /////////////////////////////////////////////////////////////////////////// typedef boost::int16_t value_type; + static size_type const fixed_bytes = 2; - value_type value() const { return impl::parse_uint16(this->i()); } - void value(value_type v) { impl::write_uint16(this->i(),v); } + value_type value() const { return detail::packet::parse_uint16(i()); } + void value(value_type v) { detail::packet::write_uint16(i(),v); } Parse_Int16 const & operator= (value_type other) { value(other); return *this; } }; - template - std::ostream & operator<<(std::ostream & os, Parse_Int16 const & i) + /** \brief Write parsed value to stream + \related Parse_Int16 + */ + inline std::ostream & operator<<(std::ostream & os, Parse_Int16 const & i) { os << i.value(); return os; } - template + /** \brief Parse 16bit unsigned byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_UInt16 - : public impl::ParseIntOps,boost::uint16_t>, - public ParserBase + : public detail::packet::ParseIntOps, + public PacketParserBase { - template - struct rebind { typedef Parse_UInt16 parser; }; - typedef Iterator byte_iterator; - - static unsigned bytes() { return 2; } - - Parse_UInt16() {} - explicit Parse_UInt16(Iterator const & i) : ParserBase(i) {} + Parse_UInt16(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {} /////////////////////////////////////////////////////////////////////////// typedef boost::uint16_t value_type; + static size_type const fixed_bytes = 2; - value_type value() const { return impl::parse_uint16(this->i()); } - void value(value_type v) { impl::write_uint16(this->i(),v); } + value_type value() const { return detail::packet::parse_uint16(i()); } + void value(value_type v) { detail::packet::write_uint16(i(),v); } Parse_UInt16 const & operator= (value_type other) { value(other); return *this; } }; - template - std::ostream & operator<<(std::ostream & os, Parse_UInt16 const & i) + /** \brief Write parsed value to stream + \related Parse_UInt16 + */ + inline std::ostream & operator<<(std::ostream & os, Parse_UInt16 const & i) { os << i.value(); return os; } - template + /** \brief Parse 24bit signed byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_Int24 - : public impl::ParseIntOps,boost::int32_t>, - public ParserBase + : public detail::packet::ParseIntOps, + public PacketParserBase { - template - struct rebind { typedef Parse_Int24 parser; }; - typedef Iterator byte_iterator; - - static unsigned bytes() { return 3; } - - Parse_Int24() {} - explicit Parse_Int24(Iterator const & i) : ParserBase(i) {} + Parse_Int24(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {} /////////////////////////////////////////////////////////////////////////// typedef boost::int32_t value_type; + static size_type const fixed_bytes = 3; value_type value() const { - value_type v (impl::parse_uint24(this->i())); return v&0x800000 ? v|0xff000000 : v; } - void value(value_type v) { impl::write_uint24(this->i(),v); } + value_type v (detail::packet::parse_uint24(i())); return v&0x800000 ? v|0xff000000 : v; } + void value(value_type v) { detail::packet::write_uint24(i(),v); } Parse_Int24 const & operator= (value_type other) { value(other); return *this; } }; - template - std::ostream & operator<<(std::ostream & os, Parse_Int24 const & i) + /** \brief Write parsed value to stream + \related Parse_Int24 + */ + inline std::ostream & operator<<(std::ostream & os, Parse_Int24 const & i) { os << i.value(); return os; } - template + /** \brief Parse 24bit unsigned byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_UInt24 - : public impl::ParseIntOps,boost::uint32_t>, - public ParserBase + : public detail::packet::ParseIntOps, + public PacketParserBase { - template - struct rebind { typedef Parse_UInt24 parser; }; - typedef Iterator byte_iterator; - - static unsigned bytes() { return 3; } - - Parse_UInt24() {} - explicit Parse_UInt24(Iterator const & i) : ParserBase(i) {} + Parse_UInt24(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {} /////////////////////////////////////////////////////////////////////////// typedef boost::uint32_t value_type; + static size_type const fixed_bytes = 3; - value_type value() const { return impl::parse_uint24(this->i()); } - void value(value_type v) { impl::write_uint24(this->i(),v); } + value_type value() const { return detail::packet::parse_uint24(i()); } + void value(value_type v) { detail::packet::write_uint24(i(),v); } Parse_UInt24 const & operator= (value_type other) { value(other); return *this; } }; - template - std::ostream & operator<<(std::ostream & os, Parse_UInt24 const & i) + /** \brief Write parsed value to stream + \related Parse_UInt24 + */ + inline std::ostream & operator<<(std::ostream & os, Parse_UInt24 const & i) { os << i.value(); return os; } - template + /** \brief Parse 32bit signed byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_Int32 - : public impl::ParseIntOps,boost::int32_t>, - public ParserBase + : public detail::packet::ParseIntOps, + public PacketParserBase { - template - struct rebind { typedef Parse_Int32 parser; }; - typedef Iterator byte_iterator; - - static unsigned bytes() { return 4; } - - Parse_Int32() {} - explicit Parse_Int32(Iterator const & i) : ParserBase(i) {} + Parse_Int32(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {} /////////////////////////////////////////////////////////////////////////// typedef boost::int32_t value_type; + static size_type const fixed_bytes = 4; - value_type value() const { return impl::parse_uint32(this->i()); } - void value(value_type v) { impl::write_uint32(this->i(),v); } + value_type value() const { return detail::packet::parse_uint32(i()); } + void value(value_type v) { detail::packet::write_uint32(i(),v); } Parse_Int32 const & operator= (value_type other) { value(other); return *this; } }; - template - std::ostream & operator<<(std::ostream & os, Parse_Int32 const & i) + /** \brief Write parsed value to stream + \related Parse_Int32 + */ + inline std::ostream & operator<<(std::ostream & os, Parse_Int32 const & i) { os << i.value(); return os; } - template + /** \brief Parse 32bit unsigned byte aligned integer + \see parseint + \ingroup parseint + */ struct Parse_UInt32 - : public impl::ParseIntOps,boost::uint32_t>, - public ParserBase + : public detail::packet::ParseIntOps, + public PacketParserBase { - template - struct rebind { typedef Parse_UInt32 parser; }; - typedef Iterator byte_iterator; - - static unsigned bytes() { return 4; } - - Parse_UInt32() {} - explicit Parse_UInt32(Iterator const & i) : ParserBase(i) {} + Parse_UInt32(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {} /////////////////////////////////////////////////////////////////////////// typedef boost::uint32_t value_type; + static size_type const fixed_bytes = 4; - value_type value() const { return impl::parse_uint32(this->i()); } - void value(value_type v) { impl::write_uint32(this->i(),v); } + value_type value() const { return detail::packet::parse_uint32(i()); } + void value(value_type v) { detail::packet::write_uint32(i(),v); } Parse_UInt32 const & operator= (value_type other) { value(other); return *this; } }; - template - std::ostream & operator<<(std::ostream & os, Parse_UInt32 const & i) + /** \brief Write parsed value to stream + \related Parse_UInt32 + */ + inline std::ostream & operator<<(std::ostream & os, Parse_UInt32 const & i) { os << i.value(); return os; } - template + /** \brief Parse signed bitfield with up to 32bit's + + This parser will parse a bitfield beginning at the bit \a Start and ending \e before \a + End. Bits are numbered most significant bit first as this is the customary + numbering used when defining packet data structures. \a Start and \a End can be \e + arbitrary as long as the field is between 1 and 32 bits in size. In other words, \c + Parse_IntField<53,81> is a valid 30 bit field. + + When defining a compound parser with several bit fields, you need to take care of the fact, + that several integer field parsers will interpret the same data \e bytes (but not the same + \e bits). It is customary for several integer field parsers to start at the same byte offset + with ever increasing bit offsets. + + \see parseint + + \implementation The integer field parser is highly optimized. Since the bit positions are + compile-time constants, the compiler will create optimized bit-masks to directly access + the value. The parser is also optimized to access the minimum number of data bytes + necessary. + + \ingroup parseint + */ + template struct Parse_IntField - : public impl::ParseIntOps,boost::int32_t>, - public ParserBase + : public detail::packet::ParseIntOps,boost::int32_t>, + public PacketParserBase { - template - struct rebind { typedef Parse_IntField parser; }; - typedef Iterator byte_iterator; - - static unsigned bytes() { return (end-1)/8+1; } - - Parse_IntField() {} - explicit Parse_IntField(Iterator const & i) : ParserBase(i) {} + Parse_IntField(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {} /////////////////////////////////////////////////////////////////////////// typedef boost::int32_t value_type; + static size_type const fixed_bytes = (End-1)/8+1; value_type value() const { - value_type v (impl::parse_bitfield::parse(this->i())); - return v&boost::high_bit_mask_t::high_bit ? - v | ~boost::low_bits_mask_t::sig_bits : v; + value_type v (detail::packet::parse_bitfield::parse(i())); + return v&boost::high_bit_mask_t::high_bit ? + v | ~boost::low_bits_mask_t::sig_bits : v; } - void value(value_type v) { impl::parse_bitfield::write(this->i(),v); } + void value(value_type v) { detail::packet::parse_bitfield::write(i(),v); } Parse_IntField const & operator= (value_type other) { value(other); return *this; } private: - BOOST_STATIC_ASSERT( start - std::ostream & operator<<(std::ostream & os, Parse_IntField const & i) + /** \brief Write parsed value to stream + \related Parse_IntField + */ + template + inline std::ostream & operator<<(std::ostream & os, Parse_IntField const & i) { os << i.value(); return os; } - template + /** \brief Parse unsigned bitfield with up to 32bit's + + This parser will parse a bitfield beginning at the bit \a Start and ending \e before \a + End. Bits are numbered most significant bit first as this is the customary + numbering used when defining packet data structures. \a Start and \a End can be \e + arbitrary as long as the field is between 1 and 32 bits in size. In other words, \c + Parse_IntField<53,81> is a valid 30 bit field. + + When defining a compound parser with several bit fields, you need to take care of the fact, + that several integer field parsers will interpret the same data \e bytes (but not the same + \e bits). It is customary for several integer field parsers to start at the same byte offset + with ever increasing bit offsets. + + \see parseint + + \implementation The integer field parser is highly optimized. Since the bit positions are + compile-time constants, the compiler will create optimized bit-masks to directly access + the value. The parser is also optimized to access the minimum number of data bytes + necessary. + + \ingroup parseint + */ + template struct Parse_UIntField - : public impl::ParseIntOps,boost::uint32_t>, - public ParserBase + : public detail::packet::ParseIntOps,boost::uint32_t>, + public PacketParserBase { - template - struct rebind { typedef Parse_UIntField parser; }; - typedef Iterator byte_iterator; - - static unsigned bytes() { return (end-1)/8+1; } - - Parse_UIntField() {} - explicit Parse_UIntField(Iterator const & i) : ParserBase(i) {} + Parse_UIntField(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {} /////////////////////////////////////////////////////////////////////////// typedef boost::uint32_t value_type; + static size_type const fixed_bytes = (End-1)/8+1; - value_type value() const { return impl::parse_bitfield::parse(this->i()); } - void value(value_type v) { impl::parse_bitfield::write(this->i(),v); } + value_type value() const { return detail::packet::parse_bitfield::parse(i()); } + void value(value_type v) { detail::packet::parse_bitfield::write(i(),v); } Parse_UIntField const & operator= (value_type other) { value(other); return *this; } private: - BOOST_STATIC_ASSERT( start - std::ostream & operator<<(std::ostream & os, Parse_UIntField const & i) + /** \brief Write parsed value to stream + \related Parse_UIntField + */ + template + inline std::ostream & operator<<(std::ostream & os, Parse_UIntField const & i) { os << i.value(); return os; } - template - struct Parse_Flag - : public impl::ParseIntOps,bool>, - public ParserBase - { - template - struct rebind { typedef Parse_Flag parser; }; - typedef Iterator byte_iterator; + /** \brief Parse single-bit flag - static unsigned bytes() { return 1; } + This parser will parse a single bit as True/False value. Bits are numbered most + significant bit first as this is the customary numbering used when defining packet data + structures. \a Bit can be arbitrary, \c Parse_Flag<75> is a valid flag parser. - Parse_Flag() {} - explicit Parse_Flag(Iterator const & i) : ParserBase(i) {} + When defining a compound parser with several bit fields, you need to take care of the fact, + that several integer field parsers will interpret the same data \e bytes (but not the same + \e bits). It is customary for several integer field parsers to start at the same byte offset + with ever increasing bit offsets. + + \see parseint + \ingroup parseint + */ + template + struct Parse_Flag + : public detail::packet::ParseIntOps,bool>, + public PacketParserBase + { + Parse_Flag(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {} /////////////////////////////////////////////////////////////////////////// typedef bool value_type; + static size_type const fixed_bytes = Bit/8+1; - value_type value() const { return this->i()[bit/8] & (1<<(7-(bit%8))); } + value_type value() const { return i()[Bit/8] & (1<<(7-(Bit%8))); } void value(value_type v) { - if (v) this->i()[0] |= 1<<(7-(bit%8)); - else this->i()[0] &= ~(1<<(7-(bit%8))); + if (v) i()[0] |= 1<<(7-(Bit%8)); + else i()[0] &= ~(1<<(7-(Bit%8))); } Parse_Flag const & operator= (value_type other) { value(other); return *this; } }; - template - std::ostream & operator<<(std::ostream & os, Parse_Flag const & i) + /** \brief Write parsed value to stream + \related Parse_Flag + */ + template + inline std::ostream & operator<<(std::ostream & os, Parse_Flag const & i) { os << i.value(); return os; } } ///////////////////////////////hh.e//////////////////////////////////////// +#endif +#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseInt_i_) +#define HH_ParseInt_i_ //#include "ParseInt.cci" //#include "ParseInt.ct" //#include "ParseInt.cti" @@ -354,4 +427,6 @@ namespace senf { // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// comment-column: 40 // End: