Utils/Daemon: Add warning when the scheduler has registered events at a fork()
[senf.git] / Packets / PacketInterpreter.hh
index d49510f..790c600 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
 #define HH_PacketInterpreter_ 1
 
 // Custom includes
-#include <boost/intrusive/ilist.hpp>
+#include "../boost/intrusive/ilist.hpp"
 #include <boost/optional.hpp>
 #include <boost/range.hpp>
 #include <boost/type_traits/aligned_storage.hpp>
 #include <boost/type_traits/alignment_of.hpp>
-#include "Utils/intrusive_refcount.hh"
-#include "Utils/pool_alloc_mixin.hh"
+#include "../Utils/intrusive_refcount.hh"
+#include "../Utils/pool_alloc_mixin.hh"
+#include "../Utils/Tags.hh"
 #include "PacketData.hh"
-#include "typeidvalue.hh"
+#include "../Utils/TypeIdValue.hh"
 
 //#include "PacketInterpreter.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -42,7 +45,12 @@ namespace senf {
 
     template <class PacketType> class PacketInterpreter;
 
-    /** \brief
+    /** \brief Internal: Base packet interpreter class
+        
+        \internal
+
+        This is the base class for the persistent interpreter. This class encapsulates all the
+        functionality accessible via the packet handle, most handle operations are just forwarded.
       */
     class PacketInterpreterBase
         : protected PacketData, 
@@ -68,27 +76,34 @@ namespace senf {
 
         enum Append_t { Append };
         enum Prepend_t { Prepend };
-        enum NoInit_t { noinit };
 
+        /** \brief Internal: Abstract packet factory
+
+            \internal
+
+            This abstract class provides an abstract packet factory interface. It allows to call
+            almost any one of the create / createAfter / createBefore static PacketInterpreter
+            without static information on the type of packet to create.
+         */
         struct Factory { 
             virtual ~Factory();
 
             // Create completely new packet
 
             virtual ptr create() const = 0;
-            virtual ptr create(NoInit_t) const = 0;
+            virtual ptr create(senf::NoInit_t) const = 0;
             virtual ptr create(size_type size) const = 0;
-            virtual ptr create(size_type size, NoInit_t) const = 0;
+            virtual ptr create(size_type size, senf::NoInit_t) const = 0;
             template <class ForwardReadableRange>
             ptr create(ForwardReadableRange const & range) const;
             
             // Create packet as new packet after a given packet
 
             virtual ptr createAfter(PacketInterpreterBase::ptr packet) const = 0;
-            virtual ptr createAfter(PacketInterpreterBase::ptr packet, NoInit_t) const = 0;
+            virtual ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t) const = 0;
             virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size) const = 0;
             virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, 
-                                    NoInit_t) const = 0;
+                                    senf::NoInit_t) const = 0;
             template <class ForwardReadableRange>
             ptr createAfter(PacketInterpreterBase::ptr packet, 
                             ForwardReadableRange const & range) const;
@@ -96,7 +111,7 @@ namespace senf {
             // Create packet as new packet (header) const before a given packet
 
             virtual ptr createBefore(PacketInterpreterBase::ptr packet) const = 0;
-            virtual ptr createBefore(PacketInterpreterBase::ptr packet, NoInit_t) const = 0;
+            virtual ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t) const = 0;
 
             // Parse next packet in chain
 
@@ -147,11 +162,20 @@ namespace senf {
         
         ///@}
 
+        ///\name Annotations
+        ///@{
+
+        template <class Annotation>
+        Annotation & annotation();
+
+        ///@}
+
         ///\name Access to the abstract interface
         ///@{
 
         optional_range nextPacketRange();
-        void finalize();
+        void finalizeThis();
+        void finalizeTo(ptr other);
         void dump(std::ostream & os);
         TypeIdValue typeId();
         factory_t factory();
@@ -168,6 +192,11 @@ namespace senf {
         ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
         ptr appendClone(detail::PacketImpl * impl, range r);
 
+    public:
+        // Need this for g++ < 4.0. Since PacketInterpreter is not publicly visible, it should not
+        // be a real problem to make impl() public here
+        using PacketData::impl;
+
     private:
         // abstract packet type interface
 
@@ -191,12 +220,19 @@ namespace senf {
         void releaseImpl();
 
         friend class detail::PacketImpl;
-        friend class intrusive_refcount_t<PacketInterpreterBase>;
+        friend class intrusive_refcount_base;
         template <class PacketType> friend class PacketInterpreter;
         friend class detail::packet::test::TestDriver;
+        friend class PacketParserBase;
     };
 
-    /** \brief Concrete packet interpreter
+    /** \brief Internal: Concrete packet interpreter
+
+        \internal
+
+        Instantiations of this class build the interpreter chain. This class is accessed by the
+        packet handles. It provides the packet-type specific functionality in addition to the
+        interface defined in the PacketInterpreterBase class.
 
         \see PacketTypeBase for the \a PacketType interface
       */
@@ -229,18 +265,18 @@ namespace senf {
         // Create completely new packet
 
         static ptr create();
-        static ptr create(NoInit_t);
+        static ptr create(senf::NoInit_t);
         static ptr create(size_type size);
-        static ptr create(size_type size, NoInit_t);
+        static ptr create(size_type size, senf::NoInit_t);
         template <class ForwardReadableRange>
         static ptr create(ForwardReadableRange const & range);
 
         // Create packet as new packet after a given packet
 
         static ptr createAfter(PacketInterpreterBase::ptr packet);
-        static ptr createAfter(PacketInterpreterBase::ptr packet, NoInit_t);
+        static ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t);
         static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
-        static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, NoInit_t);
+        static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, senf::NoInit_t);
         template <class ForwardReadableRange>
         static ptr createAfter(PacketInterpreterBase::ptr packet, 
                                ForwardReadableRange const & range);
@@ -248,7 +284,7 @@ namespace senf {
         // Create packet as new packet (header) before a given packet
 
         static ptr createBefore(PacketInterpreterBase::ptr packet);
-        static ptr createBefore(PacketInterpreterBase::ptr packet, NoInit_t);
+        static ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
 
         // Create a clone of the current packet
 
@@ -296,31 +332,37 @@ namespace senf {
 
         // factory
 
+        /** \brief Internal: Implementation of abstract factory interface
+            
+            \internal
+
+            Implements the abstract factory interface for \a PacketType
+         */
         struct FactoryImpl : public Factory {
             // Create completely new packet
 
             virtual PacketInterpreterBase::ptr create() const;
-            virtual PacketInterpreterBase::ptr create(NoInit_t) const;
+            virtual PacketInterpreterBase::ptr create(senf::NoInit_t) const;
             virtual PacketInterpreterBase::ptr create(size_type size) const;
-            virtual PacketInterpreterBase::ptr create(size_type size,NoInit_t) const;
+            virtual PacketInterpreterBase::ptr create(size_type size,senf::NoInit_t) const;
             
             // Create packet as new packet after a given packet
 
             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet) 
                 const;
             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
-                                                           NoInit_t) const;
+                                                           senf::NoInit_t) const;
             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
                                                            size_type size) const;
             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
-                                                           size_type size, NoInit_t) const;
+                                                           size_type size, senf::NoInit_t) const;
             
             // Create packet as new packet (header) before a given packet
 
             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet) 
                 const;
             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
-                                                            NoInit_t) 
+                                                            senf::NoInit_t) 
                 const;
 
             // Parse next packet in chain
@@ -341,12 +383,20 @@ namespace senf {
         friend class FactoryImpl;
     };
 
-    struct InvalidPacketChainException : public std::exception
-    { virtual char const * what() const throw() { return "invalid packet chain"; } };
+    /** \brief Invalid packet chain operation
+
+        This exception signals an invalid operation on the chain like trying to find a non-existent
+        chain member and other similar error conditions. 
+     */
+    struct InvalidPacketChainException : public senf::Exception
+    { InvalidPacketChainException() : senf::Exception("invalid packet chain"){} };
     
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(HH_Packets__decls_) && !defined(HH_PacketInterpreter_i_)
+#define HH_PacketInterpreter_i_
 #include "PacketInterpreter.cci"
 #include "PacketInterpreter.ct"
 #include "PacketInterpreter.cti"