Packets: Fix VariantParser invalid parser access bug
[senf.git] / Socket / SocketProtocol.hh
index fa8d0ff..7590312 100644 (file)
@@ -1,8 +1,8 @@
 // $Id$
 //
 // Copyright (C) 2006
-// Fraunhofer Institute for Open Communication Systems (FOKUS) 
-// Competence Center NETwork research (NET), St. Augustin, GERMANY 
+// 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
 
 /** \file
     \brief SocketProtocol and ConcreteSocketProtocol public header
-
-    \idea We should optimize the protocol handling. Allocating a protocol instance for every socket
-        body seems quite wasteful. We could derive SocketPolicy from SocketBody (probably privately,
-        since private inheritance models more of 'has a' than 'is a'). This would allow to reduce
-        the number of heap-allocations per socket to one which is good.
  */
 
 // The private inheritance idea should indeed work very well: We just need to change the
 
 /** \defgroup protocol_group The Protocol Classes
 
-    \htmlonly
-    <map name="protocols">
-    <area shape="rect" alt="SocketPolicy" href="structsenf_1_1SocketPolicy.html" title="SocketPolicy" coords="416,50,536,68" />
-    <area shape="rect" alt="ConcreteSocketProtocol" href="classsenf_1_1ConcreteSocketProtocol.html" title="ConcreteSocketProtocol" coords="268,65,456,88" />
-    <area shape="rect" alt="SocketProtocol" href="classsenf_1_1SocketProtocol.html" title="SocketProtocol" coords="1,2,120,26" />
-    <area shape="rect" alt="BSDSocketProtocol" href="classsenf_1_1BSDSocketProtocol.html" title="BSDSocketProtocol" coords="124,118,276,143" />
-    <area shape="rect" alt="AddressableBSDSocketProtocol" href="classsenf_1_1AddressableBSDSocketProtocol.html" title="AddressableBSDSocketProtocol" coords="82,200,314,224" />
-    <area shape="rect" alt="IPv4Protocol" href="classsenf_1_1IPv4Protocol.html" title="IPv4Protocol" coords="149,272,252,296" />
-    <area shape="rect" alt="IPv6Protocol" href="classsenf_1_1IPv6Protocol.html" title="IPv6Protocol" coords="149,335,251,359" />
-    <area shape="rect" alt="TCPProtocol" href="classsenf_1_1TCPProtocol.html" title="TCPProtocol" coords="151,398,248,420" />
-    <area shape="rect" alt="TCPv4SocketProtocol" href="classsenf_1_1TCPv4SocketProtocol.html" title="TCPv4SocketProtocol" coords="288,471,405,494" />
-    <area shape="rect" alt="TCPv6SocketProtocol" href="classsenf_1_1TCPv6SocketProtocol.html" title="TCPv6SocketProtocol" coords="424,470,540,494" />
-    <area shape="rect" alt="PacketProtocol" href="classsenf_1_1PacketProtocol.html" title="PacketProtocol" coords="560,469,680,495" />
-    </map>
-    <img src="Protocols.png" border="0" alt="Protocols" usemap="#protocols">
-    \endhtmlonly
+     <div class="diamap" name="Protocols">
+     <span coords="0,0,118,25">\ref SocketProtocol</span>
+     <span coords="139,381,279,407">\ref UNSocketProtocol</span>
+     <span coords="527,412,693,438">\ref PacketSocketProtocol</span>
+     <span coords="214,49,471,86">\ref ConcreteSocketProtocol</span>
+     <span coords="135,112,283,137">\ref BSDSocketProtocol</span>
+     <span coords="114,258,304,284">\ref DatagramSocketProtocol</span>
+     <span coords="136,320,281,346">\ref TCPSocketProtocol</span>
+     <span coords="395,446,604,472">\ref UNDatagramSocketProtocol</span>
+     <span coords="89,189,329,215">\ref AddressableBSDSocketProtocol</span>
+     <span coords="282,481,444,507">\ref TCPv4SocketProtocol</span>
+     </div>
+     \htmlonly <img src="Protocols.png" border="0" alt="Protocols" usemap="#Protocols"> \endhtmlonly
 
     The socket handle classes and templates only implement the most important socket API methods
     using the policy framework. To access the complete API, the protocol interface is
@@ -72,9 +64,6 @@
     \see
         \ref handle_group \n
         \ref policy_group
-
-    \todo Complete the protocol interface implementations. Better distribution of members to
-        protocol facets and more precise distribution of functionality among the facets.
  */
 
 /** \defgroup concrete_protocol_group Protocol Implementations (Concrete Protocol Classes)
     accessibility of the socket body from all facets.
  */
 
-#ifndef HH_SocketProtocol_
-#define HH_SocketProtocol_ 1
+#ifndef HH_SENF_Socket_SocketProtocol_
+#define HH_SENF_Socket_SocketProtocol_ 1
 
 // Custom includes
 #include <boost/utility.hpp>
@@ -153,17 +142,9 @@ namespace senf {
         ///////////////////////////////////////////////////////////////////////////
         // Virtual interface
 
-        virtual std::auto_ptr<SocketProtocol> clone() const = 0;
-                                        ///< Polymorphically return a copy of this protocol class
-                                        /**< This member will create a new copy of the protocol
-                                             class on the heap.
-                                             \attention This member must be implemented in every \e
-                                                 leaf protocol class to return a new instance of the
-                                                 appropriate type. */
-
         virtual unsigned available() const = 0;
-                                        ///< Return number of bytes available for reading without
-                                        ///< blocking
+                                        ///< Return (maximum) number of bytes available for reading
+                                        ///< without < blocking
                                         /**< This member will check in a (very, sigh) protocol
                                              dependent way, how many bytes may be read from a socket
                                              in a single (non-blocking) read operation. If the
@@ -176,9 +157,9 @@ namespace senf {
                                              returns ethernet frames, returning 1500 from
                                              available() is ok). However, this should only be done
                                              as a last resort. Also beware, that this number should
-                                             not be to large since the socket layer will always need
-                                             to allocate that number of bytes for the data to be
-                                             read. */
+                                             not be too large since the socket layer will always
+                                             need to allocate that number of bytes for the data to
+                                             be read. */
 
         virtual bool eof() const = 0;   ///< Check for end-of-file condition
                                         /**< This is another check which (like available()) is
@@ -190,7 +171,8 @@ namespace senf {
         virtual void close() const;     ///< Close socket
                                         /**< This override will automatically \c shutdown() the
                                              socket whenever it is closed.
-                                             \throws senf::SystemException */
+                                             \throws senf::SystemException 
+                                             \fixme Move into (at least) BSDSOcketProtocol */
         
         virtual void terminate() const; ///< Forcibly close socket
                                         /**< This override will automatically \c shutdown() the
@@ -198,7 +180,8 @@ namespace senf {
                                              disable SO_LINGER to ensure, that v_terminate will not
                                              block. Like the overriden method, this member will ignore
                                              failures and will never throw. It is therefore safe to be
-                                             called from a destructor. */
+                                             called from a destructor. 
+                                             \fixme Move into (at least) BSDSocketProtocol */
 
         virtual void state(SocketStateMap & map, unsigned lod) const;
                                         ///< Return socket state information
@@ -260,27 +243,27 @@ namespace senf {
                                              ::dup2()). */
 
     private:
-        // backpointer to owning SocketBody instance
-        
-        SocketBody & body() const;
+        virtual std::auto_ptr<SocketBody> clone(bool isServer) const = 0;
+        virtual std::auto_ptr<SocketBody> clone(int fd, bool isServer) const = 0;
+        virtual SocketBody & body() const = 0;
 
-        SocketBody * body_;
         friend class SocketBody;
     };
     
-    template <class Policy> class ClientSocketHandle;
-    template <class Policy> class ServerSocketHandle;
+    template <class SPolicy> class ClientSocketHandle;
+    template <class SPolicy> class ServerSocketHandle;
 
     /** \brief Concrete Socket Protocol implementation base class
 
         ConcreteSocketProtocol is the base class of a concrete socket protocol implementation. The
         final protocol class must inherit from ConcreteSocketProtocol. The template argument \a
-        SocketPolicy must be set to the complete socket policy of the protocol.
+        SocketPolicy must be set to the complete socket policy of the protocol. \a Self is the name
+        of the final protocol class which inherits this class.
 
         A protocol implementation may define the protocol interface directly. It can also
         (additionally) make use of multiple inheritance to combine a set of protocol facets into a
         specific protocol implementation (i.e. TCPv4SocketProtocol inherits from
-        ConcreteSocketProtocol and from the protocol facets IPv4Protocol, TCPProtocol,
+        ConcreteSocketProtocol and from the protocol facets IPv4SocketProtocol, TCPSocketProtocol,
         BSDSocketProtocol and AddressableBSDSocketProtocol). The protocol facets are not concrete
         protocols themselves, they are combined to build concrete protocols. This structure will
         remove a lot of code duplication. It is important to ensure, that the protocol facets do not
@@ -288,7 +271,7 @@ namespace senf {
         
         \doc init_client init_server
      */
-    template <class SocketPolicy>
+    template <class SocketPolicy, class Self>
     class ConcreteSocketProtocol
         : public virtual SocketProtocol
     {
@@ -312,7 +295,7 @@ namespace senf {
         ///////////////////////////////////////////////////////////////////////////
 
         Policy const & policy() const;
-
+        
     protected:
         ClientSocketHandle<Policy> clientHandle() const; 
                                         ///< Get client handle for associated socket
@@ -324,8 +307,11 @@ namespace senf {
                                              this protocol instance */
 
     private:
-        Policy policy_;
+        virtual std::auto_ptr<SocketBody> clone(bool isServer) const;
+        virtual std::auto_ptr<SocketBody> clone(int fd, bool isServer) const;
+        virtual SocketBody & body() const;
 
+        Policy policy_;
     };
 
     /// @}