PPI: Checkin of first compiling (yet not working) version
[senf.git] / Packets / ParseInt.hh
index 865fd56..ee97811 100644 (file)
@@ -20,6 +20,9 @@
 // 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
 
 
 namespace senf {
 
+    /** \defgroup parseint Integer parsers
+
+        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.
+
+        The interface of all these parsers is the same (p is an arbitrary integer parser instance, v
+        is an integer constant):
+
+        \li <tt>p = v</tt>: Assigns the value to the packet field.
+        \li <tt>p.value(v)</tt>: same as above.
+        \li <tt>p.value()</tt>: Returns the fields value as an integer number.
+        \li Use of p like an integer in most contexts: <tt>p += v</tt>, <tt>p *= v</tt>, <tt>v = p +
+            1</tt> 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<Parse_Int8,boost::int8_t>,
           public PacketParserBase
@@ -51,9 +85,16 @@ namespace senf {
         void value(value_type v) { i()[0] = v; }
         Parse_Int8 const & operator= (value_type other) { value(other); return *this; }
     };
+    /** \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; }
 
+    /** \brief Parse 8bit unsigned byte aligned integer
+        \see parseint
+        \ingroup parseint
+     */
     struct Parse_UInt8
         : public detail::packet::ParseIntOps<Parse_UInt8,boost::uint8_t>,
           public PacketParserBase
@@ -69,9 +110,16 @@ namespace senf {
         void value(value_type v) { i()[0] = v; }
         Parse_UInt8 const & operator= (value_type other) { value(other); return *this; }
     };
+    /** \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; }
 
+    /** \brief Parse 16bit signed byte aligned integer
+        \see parseint
+        \ingroup parseint
+     */
     struct Parse_Int16
         : public detail::packet::ParseIntOps<Parse_Int16,boost::int16_t>,
           public PacketParserBase
@@ -87,9 +135,16 @@ namespace senf {
         void value(value_type v) { detail::packet::write_uint16(i(),v); }
         Parse_Int16 const & operator= (value_type other) { value(other); return *this; }
     };
+    /** \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; }
 
+    /** \brief Parse 16bit unsigned byte aligned integer
+        \see parseint
+        \ingroup parseint
+     */
     struct Parse_UInt16
         : public detail::packet::ParseIntOps<Parse_UInt16,boost::uint16_t>,
           public PacketParserBase
@@ -105,9 +160,16 @@ namespace senf {
         void value(value_type v) { detail::packet::write_uint16(i(),v); }
         Parse_UInt16 const & operator= (value_type other) { value(other); return *this; }
     };
+    /** \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; }
 
+    /** \brief Parse 24bit signed byte aligned integer
+        \see parseint
+        \ingroup parseint
+     */
     struct Parse_Int24
         : public detail::packet::ParseIntOps<Parse_Int24,boost::int32_t>,
           public PacketParserBase
@@ -124,9 +186,16 @@ namespace senf {
         void value(value_type v) { detail::packet::write_uint24(i(),v); }
         Parse_Int24 const & operator= (value_type other) { value(other); return *this; }
     };
+    /** \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; }
 
+    /** \brief Parse 24bit unsigned byte aligned integer
+        \see parseint
+        \ingroup parseint
+     */
     struct Parse_UInt24
         : public detail::packet::ParseIntOps<Parse_UInt24,boost::uint32_t>,
           public PacketParserBase
@@ -142,9 +211,16 @@ namespace senf {
         void value(value_type v) { detail::packet::write_uint24(i(),v); }
         Parse_UInt24 const & operator= (value_type other) { value(other); return *this; }
     };
+    /** \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; }
 
+    /** \brief Parse 32bit signed byte aligned integer
+        \see parseint
+        \ingroup parseint
+     */
     struct Parse_Int32
         : public detail::packet::ParseIntOps<Parse_Int32,boost::int32_t>,
           public PacketParserBase
@@ -160,9 +236,16 @@ namespace senf {
         void value(value_type v) { detail::packet::write_uint32(i(),v); }
         Parse_Int32 const & operator= (value_type other) { value(other); return *this; }
     };
+    /** \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; }
 
+    /** \brief Parse 32bit unsigned byte aligned integer
+        \see parseint
+        \ingroup parseint
+     */
     struct Parse_UInt32
         : public detail::packet::ParseIntOps<Parse_UInt32,boost::uint32_t>,
           public PacketParserBase
@@ -178,9 +261,34 @@ namespace senf {
         void value(value_type v) { detail::packet::write_uint32(i(),v); }
         Parse_UInt32 const & operator= (value_type other) { value(other); return *this; }
     };
+    /** \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; }
 
+    /** \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 <em>most significant bit first</em> 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 <unsigned Start, unsigned End>
     struct Parse_IntField
         : public detail::packet::ParseIntOps<Parse_IntField<Start,End>,boost::int32_t>,
@@ -205,10 +313,35 @@ namespace senf {
         BOOST_STATIC_ASSERT( Start<End );
         BOOST_STATIC_ASSERT( End-Start<=32 );
     };
+    /** \brief Write parsed value to stream
+        \related Parse_IntField
+     */
     template <unsigned Start, unsigned End>
     inline std::ostream & operator<<(std::ostream & os, Parse_IntField<Start,End> const & i)
     { os << i.value(); return os; }
 
+    /** \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 <em>most significant bit first</em> 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 <unsigned Start, unsigned End>
     struct Parse_UIntField
         : public detail::packet::ParseIntOps<Parse_UIntField<Start,End>,boost::uint32_t>,
@@ -229,13 +362,30 @@ namespace senf {
         BOOST_STATIC_ASSERT( Start<End );
         BOOST_STATIC_ASSERT( End-Start<=32 );
     };
+    /** \brief Write parsed value to stream
+        \related Parse_UIntField
+     */
     template <unsigned Start, unsigned End>
     inline std::ostream & operator<<(std::ostream & os, Parse_UIntField<Start,End> const & i)
     { os << i.value(); return os; }
 
-    template <unsigned bit>
+    /** \brief Parse single-bit flag
+
+        This parser will parse a single bit as True/False value. Bits are numbered <em>most
+        significant bit first</em> 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.
+
+        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 <unsigned Bit>
     struct Parse_Flag
-        : public detail::packet::ParseIntOps<Parse_Flag<bit>,bool>,
+        : public detail::packet::ParseIntOps<Parse_Flag<Bit>,bool>,
           public PacketParserBase
     {
         Parse_Flag(data_iterator i, state_type s) : PacketParserBase(i,s,fixed_bytes) {}
@@ -243,17 +393,20 @@ namespace senf {
         ///////////////////////////////////////////////////////////////////////////
 
         typedef bool value_type;
-        static size_type const fixed_bytes = bit/8+1;
+        static size_type const fixed_bytes = Bit/8+1;
 
-        value_type value() const { return 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) i()[0] |= 1<<(7-(bit%8));
-            else   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 <unsigned bit>
-    inline std::ostream & operator<<(std::ostream & os, Parse_Flag<bit> const & i)
+    /** \brief Write parsed value to stream
+        \related Parse_Flag
+     */
+    template <unsigned Bit>
+    inline std::ostream & operator<<(std::ostream & os, Parse_Flag<Bit> const & i)
     { os << i.value(); return os; }
 
 }