senfscons: Fix 'Object' build helper to work with empty source list in SCons 0.96.1
[senf.git] / Packets / PacketParser.hh
index 2b73860..76b8252 100644 (file)
 
     Parsers can be grouped into several categories. These categories are not all defined rigorously
     but are nevertheless helpful when working with the parsers:
-    \li <em>Value parsers</em> provide the lowest level parsers (e.g. senf::Parse_UInt16 which
+    \li <em>\ref parserimpl_value</em> provide the lowest level parsers (e.g. senf::Parse_UInt16 which
         returns an integer value).
-    \li <em>Collection parsers</em> are parsers which model a collection of sub-elements like
+    \li <em>\ref parserimpl_collection</em> are parsers which model a collection of sub-elements like
         senf::Parse_List or senf::Parse_Vector.
-    \li <em>Composite parsers</em> collect several fields of arbitrary type into a new
+    \li <em>\ref parserimpl_composite</em> collect several fields of arbitrary type into a new
         parser. Parsers defined using the \ref packetparsermacros fall under this category.
-    \li <em>Packet parsers</em> are used to define a packet type.
+    \li <em>\ref parserimpl_packet</em> are used to define a packet type.
 
     \warning Parsers are like iterators: They are invalidated <em>whenever the size of the packet's
     data is changed</em>. You should not store a parser anywhere. If you want to keep a parser
 
     You will probably only very seldom need to implement a completely new collection
     parser. Instead, you can rely on senf::Parse_Vector or senf::Parse_List and implement new
-    polcies.
+    policies.
 
     \subsection parserimpl_composite Composite parsers
     
     interface. These members may access the packet data in any way. You just need to ensure, that
     the integration into the packet-type is correct (the senf::PacketTypeMixin will by default use
     senf::bytes() to find the end of the header).
-    
+
+    <hr>
  */
 
 #ifndef HH_PacketParser_
 #include <boost/utility/enable_if.hpp>
 #include <boost/type_traits.hpp>
 #include <boost/optional.hpp>
-#include "Utils/SafeBool.hh"
+#include "../Utils/SafeBool.hh"
 #include "PacketTypes.hh"
 #include "PacketData.hh"
 
 ///////////////////////////////hh.p////////////////////////////////////////
 
 namespace senf {
+
+    class Packet;
     
     /** \brief Parser Base class
 
@@ -291,10 +294,10 @@ namespace senf {
                                                  container does not hold at least \a size bytes
                                                  beginning at \a i. */
 
-        bool check(size_type size);     ///< Check size of data container
+        bool check(size_type size) const; ///< Check size of data container
                                         /**< \returns \c true, if the data container holds at least
                                              \a size beginning at i(), \c false otherwise. */
-        void validate(size_type size);  ///< Validate size of data container
+        void validate(size_type size) const; ///< Validate size of data container
                                         /**< \throws TruncatedPacketException if the raw data
                                              container does not hold at least \a size bytes
                                              beginning at i(). */
@@ -313,8 +316,13 @@ namespace senf {
                                              implementation. Re-implement this member in your own
                                              parsers if needed. */
 
+        Packet packet() const;          ///< Get packet this parser is parsing from
+                                        /**< \important This member should only be used from packet
+                                             parsers when access to previous or following packets is
+                                             needed e.g. for calculating checksums etc. */
+
     private:
-        data_iterator end();
+        data_iterator end() const;
 
         data_iterator i_;
         PacketData * data_;
@@ -369,6 +377,7 @@ namespace senf {
 #   else
     /** \brief Generic parser copying
 
+
         This operator allows to copy the values of identical parsers. This operation does \e not
         depend on the parsers detailed implementation, it will just replace the data bytes of the
         target parser with those from the source parser. This allows to easily copy around complex
@@ -403,6 +412,28 @@ namespace senf {
     Parser operator<<(Parser target, Value const & value);
 #   endif
 
+#   ifndef DOXYGEN
+    template <class Parser, class Value>
+    typename boost::enable_if_c < 
+        boost::is_base_of<PacketParserBase, Parser>::value 
+            && ! boost::is_base_of<PacketParserBase, Value>::value,
+        Parser >::type
+    operator<<(Parser target, boost::optional<Value> const & value);
+#   else 
+    /** \brief Generic parser value assignment
+
+        This operator allows to assign a value to parsers which implement a <tt>value(</tt>\a
+        value<tt>)</tt> member. This special version allows to assign optional values: IF the
+        optional value is not set, the assignment will be skipped. 
+
+        This operator allows to use a common syntax for assigning values or parsers to a parser.
+
+        \ingroup packetparser
+     */
+    template <class Parser, class Value>
+    Parser operator<<(Parser target, boost::optional<Value> const & value);
+#   endif
+
     /** \defgroup packetparsermacros Helper macros for defining new packet parsers
         
         To simplify the definition of simple packet parsers, several macros are provided. Before