Utils: Revamp documentation overview and add some missing docs
[senf.git] / Packets / Packet.hh
index 2511c8a..44dcf2f 100644 (file)
@@ -1,9 +1,7 @@
-// $Id$
-//
-// Copyright (C) 2006 
+// Copyright (C) 2007 
 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
-//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// TODO: Implement assign() method akin to reinterpret(). However,
-// instead of using the data already present, assign() will replace
-// the date of the current packet with the given Packet.
-
-// TODO: Implement wrapping-constructor. Somehow we want to have a
-// constructor, which allows creating a chain of packet interpreters
-// with as little overhead as possible.
-
-// TODO: Document the additional concrete Packet facade requirements
-// explicitly and not only within the Parser requirements (check(),
-// bytes() and min_bytes() members ...)
-
-// TODO: Implement special container replacing vector which manages
-// some headroom to allow efficient insertion of elements at the
-// beginning. This really is just another type of deque
-// implementation.
-
 /** \file
-    \brief Main packet interface
- */
+    \brief Packet public header */
 
 #ifndef HH_Packet_
 #define HH_Packet_ 1
 
 // Custom includes
-#include <boost/utility.hpp> // for boost::noncopyable
-#include <boost/cstdint.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/intrusive_ptr.hpp>
-#include <list>
-#include <vector>
-#include <iostream>
+#include <boost/operators.hpp>
 
-#include "Packet.mpp"
-// ////////////////////////////hh.p////////////////////////////////////////
+#include "../Utils/Exception.hh"
+#include "../Utils/safe_bool.hh"
+#include "PacketInterpreter.hh"
+
+//#include "Packet.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
 
 namespace senf {
+
+    /** \defgroup packet_module Packet Handling
+
+        The basic groundwork of the Packet library is the packet handling:
+
+        \li The packet classes provide access to a chain of packet headers (more generically called
+            interpreters).
+        \li They automatically manage the required memory resources and the shared packet data.
+
+        \section packet_module_chain The Interpreter Chain
+
+        The central data structure for a packet is the interpreter chain
+
+        \image html structure.png The Interpreter Chain
+
+        This image depicts a packet with several headers. Each interpreter is responsible for a
+        specific sub-range of the complete packet. This range always \e includes the packets payload
+        (This is, why we call the data structure interpreter and not header: The interpreter is
+        responsible for interpreting a range of the packet according to a specific protocol), the
+        packet interpreters are nested inside each other.
+    
+        For each interpreter, this structure automatically divides the packet into three areas (each
+        of which are optional): The header, the payload and the trailer. Every packet will have
+        either a header or a payload section while most don't have a trailer.
+
+        As user of the library you always interact with the chain through one (or more) of the
+        interpreters. The interpreter provides methods to traverse to the following or preceding
+        header (interpreter) and provides two levels of access to the packet data: Generic low-level
+        access in the form of an STL compatible sequence and access to the parsed fields which are
+        provided by the parser associated with the concrete packet type.
+
+        \section packet_module_management Resource Management
+
+        The interface to the packet library is provided using a handle class (\ref Packet for
+        generic, protocol agnostic access and \ref ConcretePacket derived from \ref Packet to access
+        a specific protocol). This handle automatically manages the resources associated with the
+        packet (the interpreter chain and the data storage holding the packet data). The resources
+        are automatically released when the last packet handle referencing a specific packet is
+        destroyed.
+
+        \implementation The packet chain is provided on two levels: The internal representation \ref
+            PacketInterpreterBase and \ref PacketInterpreter which are referenced by the Handle
+            classes \ref Packet and \ref ConcretePacket. \n
+            The internal representation classes are pertinent in the sense, that they exist
+            regardless of the existence of a handle referencing them (as long as the packet
+            exists). Still the interpreter chain is lazy and packet interpreters beside the first
+            are only created dynamically when accessed (this is implemented in the handle not in the
+            internal representation). \n
+            The packet interpreters make use of a pool allocator. This provides extremely efficient
+            creation and destruction of packet interpreter's and removes the dynamic memory
+            management overhead from the packet interpreter management. The packet implementation
+            class (\ref PacketImpl which holds the packet data itself) however is still dynamically
+            managed (however there is only a single instance for each packet).
+     */
+
+    template <class PackeType> class ConcretePacket;
+
+    ///\addtogroup packet_module
+    ///@{
     
-    namespace impl { template <class OtherPacket> class PkReg_EntryImpl; }
-    namespace impl { class PacketImpl; }
+    /** \brief Main Packet class
 
-    /** \brief Basic interface to all packet facades
+        Packet is the main externally visible class of the packet library. Packet is a handle into
+        the internal packet representation. From Packet you may access the data of that specific
+        sub-packet/header/interpreter and navigate to the neighboring
+        sub-packets/headers/interpreters.
 
-        \section packet_overview Overview
-        
-        This class is the base class of all Packets. It implements the
-        generic Packet interface and provides the packet management
-        framework. senf::Packet manages the necessary memory
-        resources and controlls the chain of packet interpreters.
-
-        The Packet user always interfaces with the pkf via a Packet
-        derived class. This is the only external entity ever held by a
-        library user. The interface is implemented using a reference
-        counted smart pointer, so resource management is quasi
-        automatic.
-
-        \image html "../../structure.png" Overview
-        
-        Internally, every Packet references a PacketImpl instance which
-        manages the raw packet data and the interpreter list. This raw
-        data is interpreted by the concrete Packet derived class
-        according to the definition of that derived class's packet
-        type (i.e. EthernetPacket or UDPPacket).
+        Packet is protocol agnostic. This class only provides non-protocol dependent members. To
+        access the protocol specific features of a packet (like header fields) the ConcretePacket
+        class extending Packet is provided.
 
-        Packet provides several interfaces:
+        \section packet_semantics Semantics
         
-        - Creation of Packet instances: create()
-
-        - Access to the chain of interpreters: next(), prev(), head(),
-          last(), find_next(), find_prev(), get_next(), get_prev(),
-          is(), as() and reinterpret()
-
-        - Access to the raw packet data: begin(), end(), size(),
-          insert() and erase()
-
-        - An interface to the derived class: v_nextInterpreter(),
-          v_finalize(), registerInterpreter()
-
-
-        \section packet_der Implementing new Packet facades
-
-        To implement a new Packet facade, publically derive from
-        Packet. You need to implement the following minimal interface:
-
-        - You need to provide a new #ptr typedef
-
-        - You have to implement v_nextInterpreter() and v_finalize()
-
-        - The constructor should be private
-
-        - You must make Packet a \c friend of the new Packet facade
-
-        - You must implement a static check() method which validates
-          a byte region as your new Packet
-
-        \code        
-            class ExamplePacket 
-                : public senf::Packet
-            {
-            public:
-                typedef ptr_t<ExamplePacket>::ptr ptr;
-
-                static bool check(Packet::iterator begin, Packet::iterator end)
-                {
-                    // Validate, that the region [begin,end) can be
-                    // interpreted as an ExamplePacket without risking
-                    // memory access violations.
-                }
-
-            private:
-                template <class Arg>
-                ExamplePacket(Arg arg [, other args ... ])
-                    : senf::Packet(arg)
-                {}
-
-                virtual void v_nextInterpreter() const
-                {
-                    // NextPacketType and header_length of course
-                    // depend on the packet type
-                    registerInterpreter<NextPacketType>(begin()+header_length, end());
-                }
-
-                virtual void v_finalize()
-                {
-                    // calculate checksum etc
-                }
-
-                friend class senf::Packet;
-            };
-        \endcode
-
-        Please do not implement the methods inline to not clutter up
-        the header file. This is done here in the example to simplify
-        it. If a class is to be registered in some
-        senf:PacketRegistry, it must not take any additional
-        constructor parameters.
-
-        After having implemented the bare framework, the most comman
-        way to implement access to the packets specific data is to use
-        the parser framework by additionally inheriting a
-        corresponding parser. This also automatically implements the
-        check() method, which is provided by the Parser.
-
-        In the following example we only show the differences from the
-        previous example:
-
-        \code
-            class ExamplePacket
-                : public senf::Packet,
-                  public Parse_Example<senf::Packet::iterator,
-                                       ExamplePacket>
-            {
-
-                // check does not need to be implemented here, it is
-                // inherited from the parser 
-
-            private:
-                template <class InputIterator>
-                ExamplePacket(InputIterator begin, InputIterator end)
-                    : senf::Packet(begin,end)
-                {}
-            };
-        \endcode
-
-        See the senf::ParserBase Documentation for how to
-        implement Parse_Example.
-
-        The implementation of v_nextInterpreter most of the time
-        relies on some packet registry. This is simplified using the
-        senf::PacketRegistryMixin class as follows. Again, we
-        only show the differences from the preceding Example:
-
-        \code
-            struct ExampleRegistry {
-                type boost::uint16_t key_t;
-            };
-
-            class ExamplePacket
-                : public senf::Packet,
-                  public Parse_Example<senf::Packet::iterator,
-                                       ExamplePacket>,
-                  public senf::PacketRegistryMixin<ExampleRegistry,
-                                                          ExamplePacket>
-            {
-                using senf::Packet::registerInterpreter;
-                using senf::PacketRegsitryMixin<ExampleRegistry,ExamplePacket>::registerInterpreter;
-            private:
-                virtual void v_nextInterpreter() const
-                {
-                    // nextType() is defined in Parse_Example and
-                    // returns the key in the ExampleRegistry of the
-                    // next Packet.
-                    registerInterpreter(nextType(),begin()+header_length, end());
-                }
-            };
-        \endcode
-
-        For further details on the packet registry, see
-        senf::PacketRegistry.
-
-        \section packet_impl Implementation details
-
-        The Packet interface is implemented to minimize overhead as
-        far as possible without getting to complex. One area for
-        improvement ist the container class used to hold the raw
-        data. This currently is an \a std::vector. This could be
-        imporved by either allocating some headroom/tailroom in the
-        vector and using this when inserting data at the beginning or
-        end. Alternatively, a new container class (like the
-        senf::deque_list) could be used to support zero-copy
-        semantics.
-
-        At the moment, we leave the implementation at
-        std::vector. This container is very simple and especially it
-        can directly be sent out using the operating system since a \a
-        vector stores data at contiguous memory locations. An \a
-        std::deque could be used with \a writev(), however since we
-        have no access to the implementation details of the \a deque,
-        we cannot construct the \a writev() data structures.
-
-        The interpreter list managed by Packet is lazy, meaning packet
-        interpreter facades are added only when requestd by next(),
-        last() or find_next(). v_nextInterpreter() is called if
-        necessary by these methods to complete the interpreter chain.
-
-        To implement the automatic memory management, every Packet
-        facade is reference counted. Additionally, the number of
-        (indirect) references to PacketImpl is counted. This allows to
-        manage the PacketImpl instance automatically. To make this
-        work, it is necessary to ensure throughout the Packet code,
-        that the reference count of a Packet is not accidentally
-        decremented to zero. Also, the internal pointers from the
-        interpreter list to the Packet facades must not be
-        counted. They are therefore implemented differently (
-        boost::shared_ptr vs. boost::intrusive_ptr). The choice of
-        boost::intrusive_ptr for the externaly visible smart pointer
-        for all Packet facades is taken to reduce the overhead (an
-        intrusive_ptr is only the size of an ordinary pointer, a
-        smart_ptr has the size of two pointers).
-
-        \nosubgrouping
+        All operations accessing the data of \c this packet in some way will ignore any preceding
+        packets/headers/interpreters in the chain. It does not matter, whether a given packet is
+        taken from the middle or the beginning of the chain, all operations (except those explicitly
+        accessing the chain of course) should work the same.
+        
+        This especially includes members like clone() or append(): clone() will clone \e only from
+        \c this packet until the end of the chain, append() will append the given packet \e ignoring
+        any possibly preceding packets/headers/interpreters.
+
+        In the same way, the data() member provides an STL-sequence compatible view of the packet
+        data. This only includes the data which is part of \c this packet including header, trailer
+        \e and payload but \e not the headers or trailers of packets \e before \c this packet in the
+        packet/header/interpreter chain (nonetheless, this data overlaps with the data of other
+        packets).
+
+        Several members are member templates taking an \a OtherPacket template parameter. This
+        parameter must be the ConcretePacket instantiation associated with some concrete packet type
+        (protocol). For each implemented protocol, typedefs should be provided for these
+        instantiations (Example: \ref EthernetPacket is a typedef for
+        \ref ConcretePacket < \ref EthernetPacketType >).
+
+        \see 
+            \ref ConcretePacket for the type specific interface\n
+            \ref PacketData for the sequence interface\n
+            \ref packetparser for a specification of the parser interface
       */
-    class Packet : boost::noncopyable
+    class Packet
+        : public safe_bool<Packet>,
+          public boost::equality_comparable<Packet>
     {
     public:
-        ///\name Types
-        ///@{
-        typedef boost::uint8_t byte; //!< single byte datatype
-        ///@}
-
-    private:
-        ///\name Implementation
-        ///@{
-        // These types are implementation details. They are however
-        // needed to provide the correct typedefs for the user
-        // interface. Hiding these classes would incur a huge
-        // additional indirection overhead.
-
-        typedef std::vector<byte> raw_container;
-        typedef boost::shared_ptr<Packet> interpreter_list_ptr;
-        typedef std::list<senf::Packet::interpreter_list_ptr> interpreter_list;
-        typedef unsigned refcount_t;
-
-        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+        
+        typedef void type;              ///< Type of the packet.
+        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)
 
-    public:
+                                        /// Special argument flag
+                                        /** Used in some ConcretePacket constructors */
+        enum NoInit_t { noinit };       
 
         ///////////////////////////////////////////////////////////////////////////
-        ///\name Types
+        ///\name Structors and default members
         ///@{
+
+        // default copy constructor
+        // default copy assignment
+        // default destructor
         
-        /** \brief smart pointer template for all Packet classes
-            
-            This struct is just a template typedef. It defines the
-            smart pointer used for all Packet classes.
-         */
-        template <class T> struct ptr_t { typedef boost::intrusive_ptr<T> ptr; };
-
-        /** \brief smart pointer to the Packet facades
-
-            Every derived class \e must redeclare this member for it's
-            derived type:
-            \code 
-                typedef ptr_t<DerivedClass>::ptr ptr
-            \endcode
-         */
-        typedef ptr_t<Packet>::ptr ptr; 
-        typedef raw_container::iterator iterator; //!< raw data iterator
-        typedef raw_container::size_type size_type;
-        typedef raw_container::difference_type difference_type;
+        Packet();                       ///< Create uninitialized packet handle
+                                        /**< An uninitialized handle is not 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. */
+
+        // conversion constructors
+
+        template <class PacketType>     
+        Packet(ConcretePacket<PacketType> packet); ///< Copy-construct Packet from ConcretePacket
+                                        /**< This constructor allows to convert an arbitrary
+                                             ConcretePacket into a general Packet, loosing the
+                                             protocol specific interface. */
 
         ///@}
+        ///////////////////////////////////////////////////////////////////////////
 
-        // ////////////////////////////////////////////////////////////////////////
-
-        ///\name Creating packets
+        ///\name Interpreter chain access
         ///@{
 
-        /** \brief create new Packet
-            
-            This method is used to create a new Packet. All Packet
-            instances are created via this method, they are \e never
-            created directly from the Packet derived class.
-
-            \param OtherPacket Type of Packet to create, a Packet
-                    derived class
-            \param b begin iterator of byte range to create the Packet
-                    from
-            \param e corresponding end iterator
-            \return smart pointer to new packet
-            \throws TruncatedPacketException The data cannot be parsed
-                    securely (the data might be trunctated or just
-                    plain invalid)
-         */
-        template <class OtherPacket, class InputIterator>
-        static typename ptr_t<OtherPacket>::ptr create(InputIterator b, InputIterator e);
-
-        template <class OtherPacket>
-        static typename ptr_t<OtherPacket>::ptr create();
-
-        template <class OuterPacket>
-        static typename ptr_t<OuterPacket>::ptr create(Packet::ptr payload);
+                                     Packet      next() 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 */
+        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 */
+        
+
+                                     Packet      prev() 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 */
+
+
+                                     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 */
+
+                                     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 */
+
+
+        template <class OtherPacket> OtherPacket parseNextAs() const;
+                                        ///< Parse payload as given by \a OtherPacket and add 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
+                                             \c this.
+                                             \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
+                                        /**< 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
+                                             \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(). */
+
+        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.
+                                             \returns Packet handle to the cloned \a packet, placed
+                                                 after \c this in the packet/header/interpreter
+                                                 chain. */
 
         ///@}
 
-        ///\name Interpreter chain
+        ///\name Data access
         ///@{
-        
-        /** \brief get next packet from the interpreter chain
-            \return smart pointer to next packet or 0 if last packet */
-        ptr next() const;
-        /** \brief get previous packet from the interpreter chain
-            \return smart pointer to previous packet or 0 if last packet */
-        ptr prev() const;
-        /** \brief first packet of the interpreter chain
-            \return smart pointer to first packet */
-        ptr head() const;
-        /** \brief get last packet of the interpreter chain
-            \return smart pointer to last packet */
-        ptr last() const;
-        
-        /** \brief first packet of given type after the current packet
-            \return smart pointer to first following packet of type \a
-                OtherPacket or 0, if no such packet exists */
-        template <class OtherPacket> typename ptr_t<OtherPacket>::ptr find_next() const;
-        /** \brief first packet of given type before the current packet
-            \return smart pointer to first preceding packet of type \a
-                OtherPacket or 0, if no such packet exists */
-        template <class OtherPacket> typename ptr_t<OtherPacket>::ptr find_prev() const;
-
-        /** \brief first packet of given type after the current packet
-            \return smart pointer to first following packet of type \a
-            OtherPacket. \e Assert's, that a packet of this type exists */
-        template <class OtherPacket> typename ptr_t<OtherPacket>::ptr get_next() const;
-        /** \brief first packet of given type before the current packet
-            \return smart pointer to first preceding packet of type \a
-            OtherPacket. \e Assert's, that a packet of this type exists */
-        template <class OtherPacket> typename ptr_t<OtherPacket>::ptr get_prev() const;
-
-        /** \brief check, wether the packet is of the given type
-            \return true, if packt is of type \a OtherPacket, false
-                otherwise */
-        template <class OtherPacket> bool is() const; 
-        /** \brief cast packet pointer to the given type
-            \return a properly cast smart pointer if packet is of type
-                \a OtherPacket. Otherwise return 0 */
-        template <class OtherPacket> typename ptr_t<OtherPacket>::ptr as(); 
-
-        /** \brief replace current packet interpreter
-
-            This method will \e replace the current packet facade in
-            the interpreter list with a new interpreter given by \a
-            OtherPacket. 
-
-            \attention This invalidates the packet instance \e
-            this</b>. You must ensure, not to use the Packet instance
-            any further after this call
-
-            \return smart pointer to a \e new packet facade
-            \throws TruncatedPacketException there is not enough data
-                to savely interpret the packet as the given type. The
-                original packet is \e not invalidated
-         */
-        template <class OtherPacket>
-        typename ptr_t<OtherPacket>::ptr reinterpret();
 
+        PacketData & data() const;      ///< Access the packets raw data container
+        size_type size() const;         ///< Return size of packet in bytes
+                                        /**< This size does \e not include the size of any preceding
+                                             headers/packets/interpreters. It does however include
+                                             \c this packets payload. */
+        
         ///@}
 
-        ///\name Raw packet data
+        ///\name Other methods
         ///@{
 
-        /** \brief begin interator of raw packet data
-            
-            This iterator allows access to the raw data interpreted by
-            the packet facade. This \e includes any header possibly
-            interpreted by the derived packet instance. To access the
-            payload of the packet, use next()->begin().
-
-            \return random access iterator to the begin of the raw
-                data */
-        iterator begin() const;
-        /** \brief past-the-end iterator of raw packet data
-            
-            This iterator allows access to the raw data interpreted by
-            the packet facade. This \e includes any header possibly
-            interpreted by the derived packet instance. To access the
-            payload of the packet, use next()->end().
-
-            \return random access past-the-end iterator of the raw
-                data */
-        iterator end() const;
-        /** \brief raw data size of packet
-            \return size of the raw data interpreted by this
-                packet in bytes. This is \e not necessarily the size of
-                the complete packet, use head()->size() for this. */
-        size_t size() const;
-
-        // Modifying the raw packet data
-
-        // FIXME: Make all data mutators protected
-
-        typedef enum { AUTO, BEFORE, INSIDE, OUTSIDE, AFTER } Whence;
-
-        /** \brief insert single byte \a v before pos
-
-            \attention The change will \e not be validated by the
-            derived packet instance. This method is mostly to be used
-            by the derived class implementation and their helper
-            classes. */
-        void insert(iterator pos, byte v, Whence whence = AUTO);
-        /** \brief insert \a n copies of byte \a v before pos
-
-            \attention The change will \e not be validated by the
-            derived packet instance. This method is mostly to be used
-            by the derived class implementation and their helper
-            classes. */
-        void insert(iterator pos, size_type n, byte v, Whence whence = AUTO);
-        /** \brief insert a copy of the given range before pos
-
-            \attention The change will \e not be validated by the
-            derived packet instance. This method is mostly to be used
-            by the derived class implementation and their helper
-            classes. */
-        template <class InputIterator> 
-        void insert(iterator pos, InputIterator f, InputIterator l, Whence whence = AUTO);
-
-        /** \brief erase single byte
-
-            \attention The change will \e not be validated by the
-            derived packet instance. This method is mostly to be used
-            by the derived class implementation and their helper
-            classes. */
-        void erase(iterator pos);
-        /** \brief erase range
-
-            \attention The change will \e not be validated by the
-            derived packet instance. This method is mostly to be used
-            by the derived class implementation and their helper
-            classes. */
-        void erase(iterator first, iterator last);
-
+        bool operator==(Packet other) const; ///< Check for packet identity
+                                        /**< Two packet handles compare equal if they really are the
+                                             same packet header in the same packet chain. */
+        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. 
+                                             
+                                             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
+                                             packet after it has been created or changed. This
+                                             includes checksums, payload size fields or other
+                                             fields, which can be set from other information in the
+                                             packet. Each concrete packet type should document,
+                                             which fields are set by finalize().
+
+                                             finalize() will automatically process all
+                                             packets/headers/interpreters from the end of the chain
+                                             backwards up to \c this. */
+
+        void dump(std::ostream & os) const; ///< Write out a printable packet representation
+                                        /**< This method is provided mostly to help debugging packet
+                                             problems. Each concrete packet should implement a dump
+                                             method writing out all fields of the packet in a
+                                             readable representation. dump() will call this member
+                                             for each packet/header/interpreter in the chain from \c
+                                             this packet up to the end of the chain. */
+
+        TypeIdValue typeId() const;     ///< Get id of \c this packet
+                                        /**< This value is used e.g. in the packet registry to
+                                             associate packet types with other information.
+                                             \returns A type holding the same information as a
+                                                 type_info object, albeit assignable */
+        factory_t factory() const;      ///< Return factory instance of \c this packet
+                                        /**< The returned factory instance can be used to create new
+                                             packets of the given type without knowing the concrete
+                                             type of the packet. The value may be stored away for
+                                             later use if needed. */
+        
         ///@}
 
-        void dump(std::ostream & os) const;
-
     protected:
-        ///\name Derived class interface
-        ///@{
+        explicit Packet(PacketInterpreterBase::ptr packet);
 
-        /** \brief create new interpreter facade for an existing packet
-            
-            This constructor is called, when a new interpreter is to
-            be added to the interpreter chain. The constructor is
-            called indirectly from registerInterpreter() or
-            reinterpret() via the derived classes template
-            constructor.
-         */
-        template <class Operation>
-        Packet(Operation const & arg);
-        virtual ~Packet();
-        
-    private:
-        /** \brief create next packet interpreter
+        PacketInterpreterBase::ptr ptr() const;
 
-            This method is called by next(), last() or find_next() to
-            create any missing interpreters in the interpreter
-            chain. This method must be overridden in the derived class
-            to register the next packet interpreter in the interpreter
-            chain with the packet framework.
+    private:
+        Packet checkNext() const;
+        Packet checkLast() const;
+        
+        PacketInterpreterBase::ptr packet_;
+        
+        template <class PacketType>
+        friend class ConcretePacket;
+        friend class PacketParserBase;
+    };
 
-            To register the new interpreter, use
-            registerInterpreter() to create the new Packet
-            instance. The new instance is automatically added to the
-            interpreter chain after the current interpreter.
+    /** \brief Protocol specific packet handle
 
-            See also senf::PacketRegistryMixin on how to
-            use a Registry to find the next interpreters implementing
-            class.
-         */
-        virtual void v_nextInterpreter() const = 0;
+        The ConcretePacket template class extends Packet to provide protocol/packet type specific
+        aspects. These are packet constructors and access to the parsed packet fields.
 
-        /** \brief finalize packet for sending
+        The \c PacketType template argument to ConcretePacket is a protocol specific and internal
+        policy class which defines the protocol specific behavior. To access a specific type of
+        packet, the library provides corresponding typedefs of ConcretePacket < \a SomePacketType >
+        (e.g. \ref EthernetPacket as typedef for \ref ConcretePacket < \ref EthernetPacketType >).
 
-            This method is called by the packet framework to let the
-            interpreter facade do some final calculations/packet
-            cleanup before the packet is sent out or digested in some
-            other way. This is the place to calcaulate checksums and
-            such.
+        The new members provided by ConcretePacket over packet are mostly comprised of the packet
+        constructors. These come in three major flavors:
+        
+        \li The create() family of constructors will create completely new packets.
+        \li The createAfter() family of constructors will create new packets (with new data for the
+            packet) \e after a given existing packet.
+        \li The createBefore()  family of constructors will create new packets (again with new data)
+            \e before a given existing packet.
+        
+        Whereas create() will create a completely new packet with it's own chain and data storage,
+        createAfter() and createBefore() extend a packet with additional
+        headers/interpreters. createAfter() will set the payload of the given packet to the new
+        packet whereas createBefore() will create a new packet with the existing packet as it's
+        payload. 
+
+        createAfter() differs from Packet::parseNextAs() in that the former creates a new packet \e
+        replacing any possibly existing data whereas the latter will interpret the already \e
+        existing data as given by the type argument.
+        
+        \see \ref PacketTypeBase for a specification of the interface to be provided by the \a
+            PacketType policy class.
+      */
+    template <class PacketType>
+    class ConcretePacket 
+        : public Packet
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+        
+        typedef PacketType type;
 
-            This method is autmatically called for all interpreters on
-            the interpreter chain.
-         */
-        virtual void v_finalize() = 0;
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
 
-        virtual void v_dump(std::ostream & os) const = 0;
+        // default copy constructor
+        // default copy assignment
+        // default destructor
+        // no conversion constructors
+
+        ConcretePacket();               ///< Create uninitialized packet handle
+                                        /**< An uninitialized handle is not valid(). It does not
+                                             allow any operation except assignment and checking for
+                                             validity. */
+
+        static factory_t factory();     ///< Return factory for packets of specific type
+                                        /**< This \e static member is like Packet::factory() for a
+                                             specific packet of type \a PacketType */
+
+        // Create completely new packet
+
+        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
+                                        /**< This will create a completely empty and uninitialized
+                                             packet with <tt>size() == 0</tt>.
+                                             \param[in] 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
+                                             with the given size. If the size parameter is smaller
+                                             than the minimum allowed packet size an exception will
+                                             be thrown.
+                                             \param[in] size Size of the packet to create in bytes.
+                                             \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
+                                        /**< 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
+                                                 value \c senf::noinit. */
+        template <class ForwardReadableRange>
+        static ConcretePacket create(ForwardReadableRange const & range); 
+                                        ///< Create packet from given data
+                                        /**< The packet will be created from a copy of the given
+                                             data. The data from the range will be copied directly
+                                             into the packet representation. The data will \e not be
+                                             validated in any way.
+                                             \param[in] range <a
+                                                 href="http://www.boost.org/libs/range/index.html">Boost.Range</a> 
+                                                 of data to construct packet from. */
+
+        // Create packet as new packet after a given packet
+
+        static ConcretePacket createAfter(Packet packet); 
+                                        ///< Create default initialized packet after \a packet
+                                        /**< The packet will be initialized to it's default empty
+                                             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);
+                                        ///< 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
+                                                 value \c senf::noinit. */
+        static ConcretePacket createAfter(Packet packet, size_type size);
+                                        ///< Create default initialized packet after \a packet
+                                        /**< This member will create a default initialized packet
+                                             with the given size. If the size parameter is smaller
+                                             than the minimum allowed packet size an exception will
+                                             be thrown. 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] size Size of the packet to create in bytes.
+                                             \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);
+                                        ///< Create uninitialized packet after \a packet
+                                        /**< Creates an uninitialized (all-zero) packet of the exact
+                                             given size.  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] size Size of the packet to create in bytes
+                                             \param[in] noinit This parameter must always have the
+                                                 value \c senf::noinit. */
+        template <class ForwardReadableRange>
+        static ConcretePacket createAfter(Packet packet, 
+                                          ForwardReadableRange const & range);
+                                        ///< Create packet from given data after \a packet
+                                        /**< The packet will be created from a copy of the given
+                                             data. The data from the range will be copied directly
+                                             into the packet representation. The data will \e not be
+                                             validated in any way.  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] range <a
+                                                 href="http://www.boost.org/libs/range/index.html">Boost.Range</a> 
+                                                 of data to construct packet from. */
+
+        // Create packet as new packet (header) before a given packet
+
+        static ConcretePacket createBefore(Packet packet); 
+                                        ///< Create default initialized packet before \a packet
+                                        /**< The packet will be initialized to it's default empty
+                                             state. It will be prepended as previous
+                                             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);
+                                        ///< Create uninitialized empty packet before \a packet
+                                        /**< Creates a completely empty and uninitialized packet. It
+                                             will be prepended as previous header/interpreter before
+                                             \a packet in that packets interpreter chain.
+                                             \param[in] packet Packet to prepend new packet to. */
+        
+        // Create a clone of the current packet
 
-    protected:
-        /** \brief add interpreter to interpreter chain
-
-            This method is used by v_nextInterpreter() in the derived
-            classes to add a new interpreter to the interpreter
-            chain. This method will call \c OtherPacket's constructor
-            with the correct arguments and insert the new interpreter
-            into the interpreter list. This method is used, if no
-            further arguments are to be passed to the \c OtherPacket
-            constructor. If additional arguments are necessary, just
-            add them after \c end. The compiler will then choose the
-            correct overload to use.
-         */
-        template <class OtherPacket>
-        typename ptr_t<OtherPacket>::ptr registerInterpreter(
-            raw_container::iterator begin, raw_container::iterator end) const;
-        template <class OtherPacket, class A0>
-        typename ptr_t<OtherPacket>::ptr registerInterpreter(
-            raw_container::iterator begin, raw_container::iterator end,
-            A0 const & a0) const;
-
-#       define BOOST_PP_ITERATION_PARAMS_1 (4, (2, 9, "Packets/Packet.mpp", 3))
-#       include BOOST_PP_ITERATE()
+        ConcretePacket clone() const;
 
         ///@}
+        ///////////////////////////////////////////////////////////////////////////
 
-    private:
-
-        ///\name Implementation
-        ///@{
-
-        void add_ref() const;
-        bool release();
-        bool unlink();
+        // Field access
 
-       struct PacketOp_register;
-       friend class PacketOp_register;
-        void i_registerInterpreter(Packet * p) const;
+        typename type::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
+                                             \c parser member. 
 
-       struct PacketOp_replace;
-       friend class PacketOp_replace;
-        void i_replaceInterpreter(Packet * p);
+                                             The members are not strictly restricted to simple field
+                                             access. The parser class may have any member which is
+                                             needed for full packet access (e.g. checksum validation
+                                             / recreation ...)
+                                             \see \ref packetparser for the parser interface. */
 
-       struct PacketOp_set;
-       friend class PacketOp_set;
-        void i_setInterpreter(impl::PacketImpl * i);
+    protected:
 
     private:
-        friend class impl::PacketImpl;
-        template <class OtherPacket> friend class impl::PkReg_EntryImpl;
+        typedef PacketInterpreter<PacketType> interpreter;
 
-        impl::PacketImpl* impl_;
-        size_type begin_;
-        size_type end_;
-        interpreter_list::iterator self_;
-        mutable bool parsed_;
-        mutable refcount_t refcount_;
+        ConcretePacket(typename interpreter::ptr packet_);
+        
+        typename interpreter::ptr ptr() const;
 
-        ///@}
+        friend class Packet;
+        friend class PacketInterpreter<PacketType>;
     };
 
-    /** \brief dump packet to stream
-        \related Packet */
-    // std::ostream & operator<<(std::ostream & os, Packet const & packet);
-
-    /** \brief smart pointer handling
-        \relates Packet */
-    void intrusive_ptr_add_ref(Packet const *);
-    /** \brief smart pointer handling
-        \relates Packet */
-    void intrusive_ptr_release(Packet *);
-
-    struct TruncatedPacketException : public std::exception
-    { virtual char const * what() const throw() { return "truncated packet"; } };
+    ///@}
 
 }
 
-// ////////////////////////////hh.e////////////////////////////////////////
+///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(HH_Packets__decls_) && !defined(HH_Packet_i_)
+#define HH_Packet_i_
 #include "Packet.cci"
 #include "Packet.ct"
 #include "Packet.cti"
-
-#include "Packet.mpp"
 #endif
 
 \f
 // Local Variables:
 // mode: c++
+// fill-column: 100
 // c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
 // End:
+