removed some useless spaces; not very important, I know :)
[senf.git] / Socket / SocketHandle.ih
index 5e9fae4..b113145 100644 (file)
@@ -1,9 +1,9 @@
 // $Id$
 //
 // Copyright (C) 2006
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
-//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+// 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
 // it under the terms of the GNU General Public License as published by
@@ -44,8 +44,8 @@ namespace senf {
 
         /** \brief String supporting automatic type conversion
 
-            The ConvertibleString class is used to simplify creating a text representation of
-            arbitrary values. ConvertibleString is an ordinary string with an additional constructor
+            The StreamableString class is used to simplify creating a text representation of
+            arbitrary values. StreamableString is an ordinary string with an additional constructor
             which allows constructing the string from any arbitrary, streamable type.
 
             \note It is generally not advisable to derive from the standard library container
@@ -53,36 +53,30 @@ namespace senf {
             additional functionality is added. It is absolutely safe to convert the derived class
             back to the base type.
          */
-        class ConvertibleString : public std::string
+        class StreamableString : public std::string
         {
         public:
-            ConvertibleString();
-            ConvertibleString(bool v);  ///< Bool conversion constructor
-                                        /**< The bool conversion is defined explicitly to use a
-                                           specialized representation (the strings 'true' and
-                                           'false') */
-            template <class T>
-            ConvertibleString(T const & other);
-                                        ///< Conversion constructor
-                                        /**< This constructor will assign the string from any
-                                           arbitrary type. It will use boost::lexical_cast to
-                                           convert the argument to its string representation. */
+            using std::string::operator=;
 
             template <class T>
-            ConvertibleString & operator+= (ConvertibleString const & other);
-                                        ///< Add additional values with separator
-                                        /**< This operator facilitates the representation of
-                                           multiple values in a single string. Each value is first
-                                           converted to a string (using the type conversion
-                                           machinery of C++ and the ConvertibleString conversion
-                                           constructors). It is then appended to the current string
-                                           with ', ' as a separator (if the current string is
-                                           non-empty). */
+            StreamableString & operator<<(T const & other);
+                                        ///< Value assigment
+                                        /**< This operator will assign the string from any
+                                             arbitrary type. It will use boost::lexical_cast to
+                                             convert the argument to its string representation. 
+
+                                             If the string is non-empty, an additional separating
+                                             comma is added to the string. */
+
+            StreamableString & operator<<(bool v);  ///< Bool assignment
+                                        /**< The bool assignment is defined explicitly to use a
+                                             specialized representation (the strings 'true' and
+                                             'false'). */
         };
 
     }
 
-    typedef std::map< std::string, detail::ConvertibleString > SocketStateMap;
+    typedef std::map< std::string, detail::StreamableString > SocketStateMap;
 
     namespace detail {
         /** \brief Helper to convert SocketStateMap to multiline string representation
@@ -91,6 +85,8 @@ namespace senf {
         std::string dumpState(SocketStateMap const & map);
     }
 
+    template <class Policy, class Self> class ConcreteSocketProtocol;
+
     /** \brief SocketHandle referenced body
 
         \internal
@@ -101,13 +97,9 @@ namespace senf {
         properly. If this invariant is violated, your Program will probably crash.
      */
     class SocketBody
-        : public FileBody, 
-          public senf::pool_alloc_mixin<SocketBody>
+        : public FileBody
     {
     public:
-        using senf::pool_alloc_mixin<SocketBody>::operator new;
-        using senf::pool_alloc_mixin<SocketBody>::operator delete;
-
         ///////////////////////////////////////////////////////////////////////////
         // Types
 
@@ -117,19 +109,12 @@ namespace senf {
         ///\name Structors and default members
         ///@{
 
-        SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer);
-                                        /**<
-                                           \param protocol Protocol class implementing the desired
-                                           protocol
-                                           \param isServer \c true, if this socket is a server
-                                           socket, false otherwise */
-        SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer, int fd);
-                                        /**<
-                                           \param protocol Protocol class implementing the desired
-                                           protocol
-                                           \param isServer \c true, if this socket is a server
-                                           socket, false otherwise
-                                           \param fd socket file descriptor */
+        SocketBody(bool isServer);      /**< \param isServer \c true, if this socket is a server
+                                             socket, false otherwise */
+        SocketBody(bool isServer, int fd);
+                                        /**< \param isServer \c true, if this socket is a server
+                                             socket, false otherwise
+                                             \param fd socket file descriptor */
 
         // no copy
         // no conversion constructors
@@ -137,14 +122,18 @@ namespace senf {
         ///@}
         ///////////////////////////////////////////////////////////////////////////
 
-        SocketProtocol const & protocol() const;
-                                        ///< Access the protocol instance
+        SocketProtocol & protocol(); ///< Access the protocol instance
+        SocketProtocol const & protocol() const; ///< Access the protocol instance (const)
+
         bool isServer();                ///< Check socket type
                                         /**< \return \c true, if this is a server socket, \c false
                                            otherwise */
 
         void state(SocketStateMap & map, unsigned lod);
 
+        std::auto_ptr<SocketBody> clone(bool isServer) const;
+        std::auto_ptr<SocketBody> clone(int fd, bool isServer) const;
+
     private:
         virtual void v_close();         ///< Close socket
                                         /**< This override will automatically \c shutdown() the
@@ -162,10 +151,38 @@ namespace senf {
                                            dependent, this member will forward the call to
                                            senf::SocketPolicy::eof() */
 
-        boost::scoped_ptr<SocketProtocol> protocol_;
+        virtual SocketProtocol const & v_protocol() const = 0;
+        virtual std::string v_protocolName() const = 0;
+
         bool isServer_;
     };
 
+    template <class SProtocol>
+    class ProtocolSocketBody 
+        : public SocketBody, 
+          private SProtocol,
+          public senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >
+    {
+    public:
+        typedef SProtocol Protocol;
+
+        using senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >::operator new;
+        using senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >::operator delete;
+
+        ProtocolSocketBody(bool isServer); /**< \param isServer \c true, if this socket is a server
+                                             socket, false otherwise */
+        ProtocolSocketBody(bool isServer, int fd);
+                                        /**< \param isServer \c true, if this socket is a server
+                                             socket, false otherwise
+                                             \param fd socket file descriptor */
+        
+    private:
+        virtual SocketProtocol const & v_protocol() const;
+        virtual std::string v_protocolName() const;
+
+        friend class ConcreteSocketProtocol<typename SProtocol::Policy, SProtocol>;
+    };
+
 }
 
 ///////////////////////////////ih.e////////////////////////////////////////