switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Socket / SocketHandle.ih
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief SocketHandle internal header
30  */
31
32 #ifndef IH_SENF_Socket_SocketHandle_
33 #define IH_SENF_Socket_SocketHandle_ 1
34
35 // Custom includes
36 #include <map>
37 #include <string>
38 #include <boost/scoped_ptr.hpp>
39 #include "FileHandle.hh"
40
41 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42
43 namespace senf {
44
45
46     class SocketProtocol;
47
48     namespace detail {
49
50         /** \brief String supporting automatic type conversion
51
52             The StreamableString class is used to simplify creating a text representation of
53             arbitrary values. StreamableString is an ordinary string with an additional constructor
54             which allows constructing the string from any arbitrary, streamable type.
55
56             \note It is generally not advisable to derive from the standard library container
57             classes. However, in this concrete case, the derivation is safe since only the
58             additional functionality is added. It is absolutely safe to convert the derived class
59             back to the base type.
60          */
61         class StreamableString : public std::string
62         {
63         public:
64             using std::string::operator=;
65
66             template <class T>
67             StreamableString & operator<<(T const & other);
68                                         ///< Value assignment
69                                         /**< This operator will assign the string from any
70                                              arbitrary type. It will use boost::lexical_cast to
71                                              convert the argument to its string representation.
72
73                                              If the string is non-empty, an additional separating
74                                              comma is added to the string. */
75
76             StreamableString & operator<<(bool v);  ///< Bool assignment
77                                         /**< The bool assignment is defined explicitly to use a
78                                              specialized representation (the strings 'true' and
79                                              'false'). */
80         };
81
82     }
83
84     typedef std::map< std::string, detail::StreamableString > SocketStateMap;
85
86     namespace detail {
87         /** \brief Helper to convert SocketStateMap to multiline string representation
88             \internal
89          */
90         std::string dumpState(SocketStateMap const & map);
91     }
92
93     template <class Policy, class Self> class ConcreteSocketProtocol;
94
95     /** \brief SocketHandle referenced body
96
97         \internal
98
99         senf::SocketBody is the extended (relatively to senf::FileBody) body of
100         senf::SocketHandle. Every SocketHandle must have a SocketBody as it's body (and not a simple
101         FileBody). The casting and conversion operators defined will ensure this if used
102         properly. If this invariant is violated, your Program will probably crash.
103      */
104     class SocketBody
105         : public FileBody
106     {
107     public:
108         //-/////////////////////////////////////////////////////////////////////////////////////////
109         // Types
110
111         typedef boost::intrusive_ptr<SocketBody> ptr;
112
113         //-/////////////////////////////////////////////////////////////////////////////////////////
114         ///\name Structors and default members
115         //\{
116
117         SocketBody(bool isServer);      /**< \param isServer \c true, if this socket is a server
118                                              socket, false otherwise */
119         SocketBody(bool isServer, int fd);
120                                         /**< \param isServer \c true, if this socket is a server
121                                              socket, false otherwise
122                                              \param fd socket file descriptor */
123
124         // no copy
125         // no conversion constructors
126
127         //\}
128         //-/////////////////////////////////////////////////////////////////////////////////////////
129
130         SocketProtocol & protocol() const; ///< Access the protocol instance
131
132         bool isServer();                ///< Check socket type
133                                         /**< \return \c true, if this is a server socket, \c false
134                                            otherwise */
135
136         void state(SocketStateMap & map, unsigned lod);
137
138         std::auto_ptr<SocketBody> clone(bool isServer) const;
139         std::auto_ptr<SocketBody> clone(int fd, bool isServer) const;
140
141     private:
142         virtual void v_close();         ///< Close socket
143                                         /**< This override will automatically \c shutdown() the
144                                            socket whenever it is closed.
145                                            \throws senf::SystemException */
146         virtual void v_terminate();     ///< Forcibly close socket
147                                         /**< This override will automatically \c shutdown() the
148                                            socket whenever it is called. Additionally it will
149                                            disable SO_LINGER to ensure, that v_terminate will not
150                                            block. Like the overridden method, this member will
151                                            ignore failures and will never throw. It therefore
152                                            safe to be called from a destructor. */
153         virtual bool v_eof() const;     ///< Check for eof condition
154                                         /**< Since the eof check for sockets is very protocol
155                                            dependent, this member will forward the call to
156                                            senf::SocketPolicy::eof() */
157
158         virtual SocketProtocol const & v_protocol() const = 0;
159         virtual std::string v_protocolName() const = 0;
160
161         bool isServer_;
162     };
163
164     template <class SProtocol>
165     class ProtocolSocketBody
166         : public SocketBody,
167           private SProtocol,
168           public senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >
169     {
170     public:
171         typedef SProtocol Protocol;
172
173         using senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >::operator new;
174         using senf::pool_alloc_mixin< ProtocolSocketBody<SProtocol> >::operator delete;
175
176         ProtocolSocketBody(bool isServer); /**< \param isServer \c true, if this socket is a server
177                                              socket, false otherwise */
178         ProtocolSocketBody(bool isServer, int fd);
179                                         /**< \param isServer \c true, if this socket is a server
180                                              socket, false otherwise
181                                              \param fd socket file descriptor */
182
183     private:
184         virtual SocketProtocol const & v_protocol() const;
185         virtual std::string v_protocolName() const;
186
187         friend class ConcreteSocketProtocol<typename SProtocol::Policy, SProtocol>;
188     };
189
190 }
191
192 //-/////////////////////////////////////////////////////////////////////////////////////////////////
193 #endif
194
195 \f
196 // Local Variables:
197 // mode: c++
198 // fill-column: 100
199 // c-file-style: "senf"
200 // indent-tabs-mode: nil
201 // ispell-local-dictionary: "american"
202 // compile-command: "scons -u test"
203 // comment-column: 40
204 // End: