removed some useless spaces; not very important, I know :)
[senf.git] / Socket / SocketHandle.ih
index f2e2a32..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>
+// Copyright (C) 2006
+// 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
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
+/** \file
+    \brief SocketHandle internal header
+ */
+
 #ifndef IH_SocketHandle_
 #define IH_SocketHandle_ 1
 
 
 ///////////////////////////////ih.p////////////////////////////////////////
 
-namespace satcom {
-namespace lib {
+namespace senf {
+
 
     class SocketProtocol;
 
     namespace detail {
 
-        class ConvertibleString : public std::string
+        /** \brief String supporting automatic type conversion
+
+            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
+            classes. However, in this concrete case, the derivation is safe since only the
+            additional functionality is added. It is absolutely safe to convert the derived class
+            back to the base type.
+         */
+        class StreamableString : public std::string
         {
         public:
-            ConvertibleString();
-            ConvertibleString(bool v);
-            template <class T>
-            ConvertibleString(T const & other);
+            using std::string::operator=;
+
             template <class T>
-            ConvertibleString & operator+= (ConvertibleString const & other);
+            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'). */
         };
-        
-        struct StateMapOrdering
-            : public std::binary_function<std::string,std::string,bool>
-        {
-            bool operator()(std::string a1, std::string a2) const;
-        };
-        
+
     }
 
-    typedef std::map< std::string, detail::ConvertibleString, detail::StateMapOrdering > SocketStateMap;
+    typedef std::map< std::string, detail::StreamableString > SocketStateMap;
 
     namespace detail {
+        /** \brief Helper to convert SocketStateMap to multiline string representation
+            \internal
+         */
         std::string dumpState(SocketStateMap const & map);
     }
 
+    template <class Policy, class Self> class ConcreteSocketProtocol;
+
+    /** \brief SocketHandle referenced body
+
+        \internal
+
+        senf::SocketBody is the extended (relatively to senf::FileBody) body of
+        senf::SocketHandle. Every SocketHandle must have a SocketBody as it's body (and not a simple
+        FileBody). The casting and conversion operators defined will ensure this if used
+        properly. If this invariant is violated, your Program will probably crash.
+     */
     class SocketBody
         : public FileBody
     {
     public:
         ///////////////////////////////////////////////////////////////////////////
         // Types
-        
+
         typedef boost::intrusive_ptr<SocketBody> ptr;
 
         ///////////////////////////////////////////////////////////////////////////
         ///\name Structors and default members
         ///@{
 
-        explicit SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer);
-        SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer, int fd);
+        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
@@ -85,21 +122,68 @@ namespace lib {
         ///@}
         ///////////////////////////////////////////////////////////////////////////
 
-        SocketProtocol const & protocol() const;
-        bool isServer();
-        
+        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();
-        virtual void v_terminate();
-        virtual bool v_eof() const;
+        virtual void v_close();         ///< Close socket
+                                        /**< This override will automatically \c shutdown() the
+                                           socket whenever it is closed.
+                                           \throws senf::SystemException */
+        virtual void v_terminate();     ///< Forcibly close socket
+                                        /**< This override will automatically \c shutfown() the
+                                           socket whenever it is called. Additionally it will
+                                           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 therefore safe to be
+                                           called from a destructor. */
+        virtual bool v_eof() const;     ///< Check for eof condition
+                                        /**< Since the eof check for sockets is very protocol
+                                           dependent, this member will forward the call to
+                                           senf::SocketPolicy::eof() */
+
+        virtual SocketProtocol const & v_protocol() const = 0;
+        virtual std::string v_protocolName() const = 0;
 
-        boost::scoped_ptr<SocketProtocol> protocol_;
         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////////////////////////////////////////
 #endif
@@ -107,5 +191,10 @@ namespace lib {
 \f
 // Local Variables:
 // mode: c++
-// c-file-style: "satcom"
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
 // End: