removed some useless spaces; not very important, I know :)
[senf.git] / Packets / Packet.hh
index d04c6ae..566c219 100644 (file)
@@ -1,6 +1,8 @@
-// Copyright (C) 2007 
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
 //     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
@@ -27,8 +29,9 @@
 // Custom includes
 #include <boost/operators.hpp>
 
-#include "Utils/Exception.hh"
-#include "Utils/SafeBool.hh"
+#include "../Utils/Exception.hh"
+#include "../Utils/Tags.hh"
+#include "../Utils/safe_bool.hh"
 #include "PacketInterpreter.hh"
 
 //#include "Packet.mpp"
@@ -135,7 +138,7 @@ namespace senf {
             \ref packetparser for a specification of the parser interface
       */
     class Packet
-        : public SafeBool<Packet>,
+        : public safe_bool<Packet>,
           public boost::equality_comparable<Packet>
     {
     public:
@@ -143,13 +146,10 @@ namespace senf {
         // Types
         
         typedef void type;              ///< Type of the packet.
-        typedef senf::detail::packet::size_type size_type; ///< Unsigned type to represent packet size
+        typedef senf::detail::packet::size_type size_type;
+                                        ///< Unsigned type to represent packet size
         typedef PacketInterpreterBase::factory_t factory_t; ///< Packet factory type (see below)
 
-                                        /// Special argument flag
-                                        /** Used in some ConcretePacket constructors */
-        enum NoInit_t { noinit };       
-
         ///////////////////////////////////////////////////////////////////////////
         ///\name Structors and default members
         ///@{
@@ -159,14 +159,14 @@ namespace senf {
         // default destructor
         
         Packet();                       ///< Create uninitialized packet handle
-                                        /**< An uninitialized handle is not valid(). It does not
+                                        /**< An uninitialized handle is in - valid(). It does not
                                              allow any operation except assignment and checking for
                                              validity. */
         Packet clone() const;           ///< Create copy packet
-                                        /**< clone() will create a complete copy the packet. The
-                                             returned packet will have the same data and packet
-                                             chain. It does however not share any data with the
-                                             original packet. */
+                                        /**< clone() will create a complete copy of \c this
+                                             packet. The returned packet will have the same data and
+                                             packet chain. It does however not share any data with
+                                             the original packet. */
 
         // conversion constructors
 
@@ -184,83 +184,84 @@ namespace senf {
 
                                      Packet      next() const; 
                                         ///< Get next packet in chain
+                                        /**< \throws InvalidPacketChainException if no next packet 
+                                             exists */
+                                     Packet      next(NoThrow_t) const; 
+                                        ///< Get next packet in chain
+                                        /**< \returns in - valid() packet if no next packet 
+                                             exists */
         template <class OtherPacket> OtherPacket next() const; 
-                                        ///< Get next packet of given type in chain
-                                        /**< \throws InvalidPacketChainException if no such packet
-                                             is found */
+                                        ///< Get next packet in chain and cast to \a OtherPacket
+                                        /**< \throws std::bad_cast if the next() packet is not of
+                                             type \a OtherPacket
+                                             \throws InvalidPacketChainException if no next packet
+                                                 exists */
         template <class OtherPacket> OtherPacket next(NoThrow_t) const; 
-                                        ///< Get next packet of given type in chain
-                                        /**< \param[in] nothrow This argument always has the value
-                                             \c senf::nothrow
-                                             \returns in-valid() packet, if no such packet is found */
-        template <class OtherPacket> OtherPacket findNext() const;
-                                        ///< Find next packet of given type in chain
-                                        /**< findNext() is like next(), it will however return \c
-                                             *this if it is of the given type. 
-                                             \throws InvalidPacketChainException if no such packet
-                                                 is found */
-        template <class OtherPacket> OtherPacket findNext(NoThrow_t) const;
-                                        ///< Find next packet of given type in chain
-                                        /**< findNext() is like next(), it will however return \c
-                                             *this if it is of the given type.
-                                             \param[in] nothrow This argument always has the value
-                                             \c senf::nothrow
-                                             \returns in-valid() packet, if no such packet is found */
+                                        ///< Get next packet in chain and cast to \a OtherPacket
+                                        /**< \throws std::bad_cast if the next() packet is not of
+                                             type \a OtherPacket
+                                             \returns in - valid() packet if no next packet
+                                                 exists */
+        template <class OtherPacket> OtherPacket find() const;
+                                        ///< Search chain forward for packet of type \a OtherPacket
+                                        /**< The search will start with the current packet.
+                                             \throws InvalidPacketChainException if no packet of
+                                                 type \a OtherPacket can be found. */
+        template <class OtherPacket> OtherPacket find(NoThrow_t) const;
+                                        ///< Search chain forward for packet of type \a OtherPacket
+                                        /**< The search will start with the current packet.
+                                             \returns in - valid() packet if no packet of type \a
+                                                 OtherPacket can be found. */
         
-
                                      Packet      prev() const; 
                                         ///< Get previous packet in chain
+                                        /**< \throws InvalidPacketChainException if no previous
+                                             packet exists */
+                                     Packet      prev(NoThrow_t) const; 
+                                        ///< Get previous packet in chain
+                                        /**< \returns in - valid() packet if no previous packet
+                                             exists */
         template <class OtherPacket> OtherPacket prev() const; 
-                                        ///< Get previous packet of given type in chain
-                                        /**< \throws InvalidPacketChainException if no such packet
-                                             is found */
-        template <class OtherPacket> OtherPacket prev(NoThrow_t) const;
-                                        ///< Get previous packet of given type in chain
-                                        /**< \param[in] nothrow This argument always has the value
-                                             \c senf::nothrow
-                                             \returns in-valid() packet, if no such packet is found */
-        template <class OtherPacket> OtherPacket findPrev() const;
-                                        ///< Find previous packet of given type in chain
-                                        /**< findPrev() is like prev(), it will however return \c
-                                             *this if it is of the type 
-                                             \throws InvalidPacketChainException if no such packet
-                                                 is found */
-        template <class OtherPacket> OtherPacket findPrev(NoThrow_t) const;
-                                        ///< Find previous packet of given type in chain
-                                        /**< findPrev() is like prev(), it will however return \c
-                                             *this if it is of the type 
-                                             \param[in] nothrow This argument always has the value
-                                             \c senf::nothrow
-                                             \returns in-valid() packet, if no such packet is found */
+                                        ///< Get previous packet in chain and cast to \a OtherPacket
+                                        /**< \throws std::bad_cast, if the previous packet is not of
+                                             type \a OtherPacket
+                                             \throws InvalidPacketChainException if no previous
+                                                 packet exists */
+        template <class OtherPacket> OtherPacket prev(NoThrow_t) const; 
+                                        ///< Get previous packet in chain and cast to \a OtherPacket
+                                        /**< \throws std::bad_cast, if the previous packet is not of
+                                             type \a OtherPacket
+                                             \returns in - valid() packet if no previous packet 
+                                                 exists */
+        template <class OtherPacket> OtherPacket rfind() const;
+                                        ///< Search chain backwards for packet of type \a OtherPacket
+                                        /**< The search will start with the current packet.
+                                             \throws InvalidPacketChainException if no packet of
+                                                 type \a OtherPacket can be found. */
+        template <class OtherPacket> OtherPacket rfind(NoThrow_t) const;
+                                        ///< Search chain backwards for packet of type \a OtherPacket
+                                        /**< The search will start with the current packet.
+                                             \returns in - valid() packet if no packet of type \a
+                                                 OtherPacket can be found. */
 
 
                                      Packet      first() const;
                                         ///< Return first packet in chain
         template <class OtherPacket> OtherPacket first() const;
-                                        ///< Return first packet of given type in chain
-                                        /**< \throws InvalidPacketChainException if no such packet
-                                             is found */
-        template <class OtherPacket> OtherPacket first(NoThrow_t) const;
-                                        ///< Return first packet of given type in chain
-                                        /**< \param[in] nothrow This argument always has the value
-                                             \c senf::nothrow
-                                             \returns in-valid() packet, if no such packet is found */
+                                        ///< Return first packet in chain and cast
+                                        /**< \throws std::bad_cast if the first() packet is not of
+                                             type \a OtherPacket */
 
                                      Packet      last() const;
                                         ///< Return last packet in chain
         template <class OtherPacket> OtherPacket last() const;
-                                        ///< Return last packet of given type in chain
-                                        /**< \throws InvalidPacketChainException if no such packet
-                                             is found */
-        template <class OtherPacket> OtherPacket last(NoThrow_t) const;
-                                        ///< Return last packet of given type in chain
-                                        /**< \param[in] nothrow This argument always has the value
-                                             \c senf::nothrow
-                                             \returns in-valid() packet, if no such packet is found */
+                                        ///< Return last packet in chain and cast
+                                        /**< \throws std::bad_cast if the last() packet is not of
+                                             type \a OtherPacket  */
 
 
         template <class OtherPacket> OtherPacket parseNextAs() const;
-                                        ///< Parse payload as given by \a OtherPacket and add packet
+                                        ///< Interpret payload of \c this as \a OtherPacket
                                         /**< parseNextAs() will throw away the packet chain after
                                              the current packet if necessary. It will then parse the
                                              payload section of \c this packet as given by \a
@@ -269,32 +270,32 @@ namespace senf {
                                              \returns new packet instance sharing the same data and
                                                  placed after \c this packet in the chain. */
                                      Packet      parseNextAs(factory_t factory) const;
-                                        ///< Parse payload as given by \a factory and add packet
+                                        ///< Interpret payload of \c this as \a factory type packet
                                         /**< parseNextAs() will throw away the packet chain after
                                              the current packet if necessary. It will then parse the
                                              payload section of \c this packet as given by \a
-                                             OtherPacket. The new packet is added to the chain after
+                                             factory. The new packet is added to the chain after
                                              \c this.
                                              \returns new packet instance sharing the same data and
                                                  placed after \c this packet in the chain. */
+
         template <class OtherPacket> bool        is() const;
                                         ///< Check, whether \c this packet is of the given type
         template <class OtherPacket> OtherPacket as() const;
                                         ///< Cast current packet to the given type
                                         /**< This operations returns a handle to the same packet
                                              header/interpreter however cast to the given
-                                             ConcretePacket type. <b>This conversion is
-                                             unchecked</b>. If the packet really is of a different
-                                             type, this will wreak havoc with the packet
-                                             data-structures. You can validate whether the
-                                             conversion is valid using is(). */
+                                             ConcretePacket type.
+                                             \throws std::bad_cast if the current packet is not of
+                                                 type \a OtherPacket */
 
         Packet append(Packet packet) const; ///< Append the given packet to \c this packet
                                         /**< This operation will replace the payload section of \c
                                              this packet with \a packet. This operation will replace
                                              the packet chain after \c this packet with a clone of
                                              \a packet and will replace the raw data of the payload
-                                             of \c this with the raw data if \a packet.
+                                             of \c this with the raw data of \a packet. \c this
+                                             packet will not share any date with \a packet.
                                              \returns Packet handle to the cloned \a packet, placed
                                                  after \c this in the packet/header/interpreter
                                                  chain. */
@@ -321,10 +322,12 @@ namespace senf {
         bool boolean_test() const;      ///< Check, whether the packet is valid()
                                         /**< \see valid() */
         bool valid() const;             ///< Check, whether the packet is valid()
-                                        /**< An in-valid() packet does not allow any operation
-                                             except checking for validity and assignment. in-valid()
-                                             packets serve the same role as 0-pointers. */
-        
+                                        /**< An in - valid() packet does not allow any operation
+                                             except checking for validity and assignment. in -
+                                             valid() packets serve the same role as 0-pointers. 
+                                             
+                                             This is an alias for boolean_test() which is called
+                                             when using a packet in a boolean context. */
 
         void finalize() const;          ///< Update calculated fields
                                         /**< This call will update all calculated fields of the
@@ -372,6 +375,7 @@ namespace senf {
         
         template <class PacketType>
         friend class ConcretePacket;
+        friend class PacketParserBase;
     };
 
     /** \brief Protocol specific packet handle
@@ -415,6 +419,7 @@ namespace senf {
         // Types
         
         typedef PacketType type;
+        typedef typename PacketType::parser Parser;
 
         ///////////////////////////////////////////////////////////////////////////
         ///\name Structors and default members
@@ -439,10 +444,10 @@ namespace senf {
         static ConcretePacket create(); ///< Create default initialized packet
                                         /**< The packet will be initialized to it's default empty
                                              state. */
-        static ConcretePacket create(NoInit_t); ///< Create uninitialized empty packet
+        static ConcretePacket create(senf::NoInit_t); ///< Create uninitialized empty packet
                                         /**< This will create a completely empty and uninitialized
                                              packet with <tt>size() == 0</tt>.
-                                             \param[in] noinit This parameter must always have the
+                                             \param[in] senf::noinit This parameter must always have the
                                                  value \c senf::noinit. */
         static ConcretePacket create(size_type size); ///< Create default initialized packet
                                         /**< This member will create a default initialized packet
@@ -453,11 +458,12 @@ namespace senf {
                                              \throws TruncatedPacketException if \a size is smaller
                                                  than the smallest permissible size for this type of
                                                  packet. */
-        static ConcretePacket create(size_type size, NoInit_t); ///< Create uninitialized packet
+        static ConcretePacket create(size_type size, senf::NoInit_t); 
+                                        ///< Create uninitialized packet
                                         /**< Creates an uninitialized (all-zero) packet of the exact
                                              given size. 
                                              \param[in] size Size of the packet to create in bytes
-                                             \param[in] noinit This parameter must always have the
+                                             \param[in] senf::noinit This parameter must always have the
                                                  value \c senf::noinit. */
         template <class ForwardReadableRange>
         static ConcretePacket create(ForwardReadableRange const & range); 
@@ -478,14 +484,14 @@ namespace senf {
                                              state. It will be appended as next header/interpreter
                                              after \a packet in that packets interpreter chain.
                                              \param[in] packet Packet to append new packet to. */
-        static ConcretePacket createAfter(Packet packet, NoInit_t);
+        static ConcretePacket createAfter(Packet packet, senf::NoInit_t);
                                         ///< Create uninitialized empty packet after\a packet
                                         /**< This will create a completely empty and uninitialized
                                              packet with <tt>size() == 0</tt>. It will be appended
                                              as next header/interpreter after \a packet in that
                                              packets interpreter chain.
                                              \param[in] packet Packet to append new packet to.
-                                             \param[in] noinit This parameter must always have the
+                                             \param[in] senf::noinit This parameter must always have the
                                                  value \c senf::noinit. */
         static ConcretePacket createAfter(Packet packet, size_type size);
                                         ///< Create default initialized packet after \a packet
@@ -500,7 +506,7 @@ namespace senf {
                                              \throws TruncatedPacketException if \a size is smaller
                                                  than the smallest permissible size for this type of
                                                  packet. */
-        static ConcretePacket createAfter(Packet packet, size_type size, NoInit_t);
+        static ConcretePacket createAfter(Packet packet, size_type size, senf::NoInit_t);
                                         ///< Create uninitialized packet after \a packet
                                         /**< Creates an uninitialized (all-zero) packet of the exact
                                              given size.  It will be appended as next
@@ -508,7 +514,7 @@ namespace senf {
                                              interpreter chain.
                                              \param[in] packet Packet to append new packet to.
                                              \param[in] size Size of the packet to create in bytes
-                                             \param[in] noinit This parameter must always have the
+                                             \param[in] senf::noinit This parameter must always have the
                                                  value \c senf::noinit. */
         template <class ForwardReadableRange>
         static ConcretePacket createAfter(Packet packet, 
@@ -534,7 +540,7 @@ namespace senf {
                                              header/interpreter before \a packet in that packets
                                              interpreter chain.
                                              \param[in] packet Packet to prepend new packet to. */
-        static ConcretePacket createBefore(Packet packet, NoInit_t);
+        static ConcretePacket createBefore(Packet packet, senf::NoInit_t);
                                         ///< Create uninitialized empty packet before \a packet
                                         /**< Creates a completely empty and uninitialized packet. It
                                              will be prepended as previous header/interpreter before
@@ -550,7 +556,7 @@ namespace senf {
 
         // Field access
 
-        typename type::parser * operator->() const; ///< Access packet fields
+        Parser * operator->() const;    ///< Access packet fields
                                         /**< This operator allows to access the parsed fields of the
                                              packet using the notation <tt>packet->field()</tt>. The
                                              fields of the packet are specified by the PacketType's
@@ -562,6 +568,13 @@ namespace senf {
                                              / recreation ...)
                                              \see \ref packetparser for the parser interface. */
 
+        Parser parser() const;          ///< Access packet field parser directly
+                                        /**< Access the parser of the packet. This is the same
+                                             object returned by the operator->() operator. The
+                                             operator however does not allow to access this object
+                                             itself, only it's members.
+                                             \see \ref packetparser for the parser interface */
+
     protected:
 
     private:
@@ -581,7 +594,7 @@ namespace senf {
 
 ///////////////////////////////hh.e////////////////////////////////////////
 #endif
-#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_Packet_i_)
+#if !defined(HH_Packets__decls_) && !defined(HH_Packet_i_)
 #define HH_Packet_i_
 #include "Packet.cci"
 #include "Packet.ct"