switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Socket / SocketHandle.hh
1 // $Id:SocketHandle.hh 218 2007-03-20 14:39:32Z tho $
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 public header
30  */
31
32 #ifndef HH_SENF_Socket_SocketHandle_
33 #define HH_SENF_Socket_SocketHandle_ 1
34
35 //#include "SocketHandle.mpp"
36 #include "SocketHandle.ih"
37
38 // Custom includes
39 #include <memory> // std::auto_ptr
40 #include "FileHandle.hh"
41 #include "SocketPolicy.hh"
42
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
44
45 namespace senf {
46
47     /// \addtogroup handle_group
48     //\{
49
50     /** \brief basic SocketHandle supporting protocol and policy abstraction
51
52         The %senf::SocketHandle class introduces the two abstraction layers of the socket
53         library. senf::SocketHandle does \e not provide socket functions it only provides the
54         infrastructure necessary to support both, the protocol and the policy interface.
55
56         %SocketHandle takes the socket policy as a template argument. %SocketHandle also
57         introduces the protocol class. However, the class has no public constructors (see the
58         derived classes senf::ProtocolClientSocketHandle and senf::ProtocolServerSocketHandle).
59
60         The most important functionality provided by %SocketHandle is the conversion
61         constructor. This allows to implicitly convert between compatible socket handle types as
62         specified by the socket policy. The conversion constructor is defined in such a way, that
63         only valid conversions are possible (see the implementation source for a more complete
64         discussion).
65
66         \tparam SPolicy socket policy
67
68         \note This class is \e not meant to be used as a base-class outside the library
69         implementation; The protected interface is for internal use only.
70
71         \todo Create a SocketHandleBase class and move some non-Policy dependent code there
72      */
73     template <class SPolicy>
74     class SocketHandle
75         : public FileHandle
76     {
77     public:
78         //-////////////////////////////////////////////////////////////////////////
79         // Types
80
81         typedef SPolicy Policy;
82
83         /** \brief Check policy compatibility
84
85             IsCompatible is a template meta-function which will check some other socket policy for
86             conversion compatibility. This check is used in the senf::SocketPolicy implementation to
87             restrict the conversion operator.
88          */
89         template <class OtherPolicy>
90         struct IsCompatible
91             : public boost::enable_if< SocketPolicyIsBaseOf<Policy,OtherPolicy>, SocketHandle >
92         {};
93
94         //-////////////////////////////////////////////////////////////////////////
95         ///\name Structors and default members
96         //\{
97
98         // default default constructor
99         // default copy constructor
100         // default copy assignment
101         // default destructor
102
103         // here to implement
104         SocketHandle();
105
106         // conversion constructors
107
108         template <class OtherPolicy>
109         SocketHandle(SocketHandle<OtherPolicy> other,
110                      typename IsCompatible<OtherPolicy>::type * = 0);
111                                         ///< Convert from other socket handle checking policy
112                                         ///< compatibility
113
114         //\}
115         //-////////////////////////////////////////////////////////////////////////
116
117         template <class OtherPolicy>
118         typename IsCompatible<OtherPolicy>::type const & operator=(SocketHandle<OtherPolicy> other);
119                                         ///< Assign from other socket handle checking policy
120                                         ///< compatibility
121
122         void state(SocketStateMap & map, unsigned lod=0);
123                                         ///< Inquire state information of socket handle
124                                         /**< The map argument (a string to string mapping) will be
125                                              filled with information covering the current state of
126                                              the socket. The information provided depends on the
127                                              socket protocol. The amount of information returned can
128                                              be controlled using the \p lod value.
129
130                                              See senf::SocketProtocol::state() for more information,
131                                              how the Information is generated.
132
133                                              \param map string to string mapping to be filled with
134                                                  state information
135                                              \param lod level of %detail requested. The
136                                                  interpretation of this value is protocol specific
137
138                                              \implementation This member will be re-implemented in
139                                                  every derived class. This is very important since
140                                                  state() is \e not a virtual function (which we
141                                                  don't want since we don't want to add a vtable
142                                                  pointer to every handle instance). */
143         std::string dumpState(unsigned lod=0);
144                                         ///< Format complete state information as string
145                                         /**< Formats the complete state map value and returns it as
146                                              a single multi-line string.
147
148                                              \param lod level of %detail requested. The
149                                                 interpretation of this value is protocol specific
150
151                                              \implementation This member will be re-implemented in
152                                                  every derived class. See the state()
153                                                  documentation. */
154
155         template <class Facet>
156         Facet & facet();                ///< Access a protocol facet
157                                         /**< This member will try to access the given protocol facet
158                                              of the socket. If \a Facet is a valid facet of the
159                                              protocol, it is returned, otherwise \c std::bad_cast
160                                              will be thrown.
161                                              \throws std::bad_cast if \a Facet is not a protocol
162                                                  facet of this socket
163                                              \returns the \a Facet protocol facet of this socket */
164
165     protected:
166         explicit SocketHandle(std::auto_ptr<SocketBody> body);
167                                         ///< Initialize SocketHandle providing the protocol
168                                         /**< \param protocol Protocol class of the protocol
169                                                  implemented by this socket handle
170                                              \param isServer \c true, if this SobcketHandle instance
171                                                  implements a server handle, \c false otherwise */
172         SocketHandle(FileHandle other, bool isChecked);
173                                         ///< Initialize SocketHandle from arbitrary checked
174                                         ///< FileHandle
175                                         /**< This constructor is used to support up- and downcasting
176                                              of SocketHandle instances.
177
178                                              \warning It is absolutely necessary to ensure, that the
179                                                  FileHandle passed in is \e really a SocketHandle
180                                                  holding a SocketBody (and not a simple FileBody)
181                                                  instance. Additionally. the SocketPolicy absolutely
182                                                  must be compatible.
183
184                                              \param other FileHandle to assign
185                                              \param isChecked has to be \c true
186
187                                              \todo Answer, why the heck I need the \c isChecked
188                                                  parameter ?? */
189
190         SocketBody & body();            ///< Access socket body
191                                         /**< This member replaces the corresponding FileHandle
192                                              member and returns an appropriately cast body
193                                              reference */
194         SocketBody const & body() const; ///< Access socket body in const context
195                                         /**< This member replaces the corresponding FileHandle
196                                              member and returns an appropriately cast body
197                                              reference */
198         SocketProtocol & protocol() const;
199                                         ///< Access protocol class
200
201         void assign(FileHandle other);  /**< \internal */
202
203     public:
204         static SocketHandle cast_static(FileHandle handle);
205                                         /**< \internal */
206         static SocketHandle cast_dynamic(FileHandle handle);
207                                         /**< \internal */
208
209     private:
210
211     };
212
213     /** \brief Write stream status dump to output stream
214
215         Write senf::SocketHandle::dumpState() to \c os
216
217         \related senf::SocketHandle
218      */
219     template <class SPolicy>
220     std::ostream & operator<<(std::ostream & os, SocketHandle<SPolicy> handle);
221
222     /** \brief static socket (down-)cast
223
224         This function is like \c static_cast but for socket handles. It allows to downcast any
225         FileHandle to any SocketHandle (and its derived types). static_socket_cast will \e not check
226         the validity of the cast, it will assume, that the cast is valid.
227
228         The function will however check, that the cast is possible. Casting between (at compile
229         time) known incompatible types (like casting a SocketHandle with a communication policy of
230         ConnectedCommunicationPolicy to a SocketHandle with UnconnectedCommunicationPolicy will fail
231         at compile time).
232
233         \warning
234         If the type you cast to is not really a compatible socket handle type you will get undefined
235         behavior, probably your program will crash (You will get an assertion in debug builds).
236
237         \related senf::SocketHandle
238      */
239     template <class Target, class Source>
240     Target static_socket_cast(Source handle);
241
242     /** \brief dynamic socket (down-)cast
243
244         This function is like \c dynamic_cast but for socket handles. It is a runtime typechecked
245         version of static_socket_cast.
246
247         \throws std::bad_cast You have tried to perform an invalid down- or crosscast.
248
249         \related senf::SocketHandle
250      */
251     template <class Target, class Source>
252     Target dynamic_socket_cast(Source handle);
253
254     /** \brief dynamically check cast validity
255
256         This function will check, whether the given cast is valid. This is the same as checking, that
257         dynamic_socket_cast does not throw.
258
259         This member is needed, since there is no 'null' SocketHandle (comparable to a null pointer)
260         which could be returned by a non-throwing variant of dynamic_socket_cast.
261
262         \related senf::SocketHandle
263      */
264     template <class Target, class Source>
265     bool check_socket_cast(Source handle);
266
267     //\}
268 }
269
270 //-/////////////////////////////////////////////////////////////////////////////////////////////////
271 #include "SocketHandle.cci"
272 #include "SocketHandle.ct"
273 #include "SocketHandle.cti"
274 #endif
275
276 \f
277 // Local Variables:
278 // mode: c++
279 // fill-column: 100
280 // c-file-style: "senf"
281 // indent-tabs-mode: nil
282 // ispell-local-dictionary: "american"
283 // compile-command: "scons -u test"
284 // comment-column: 40
285 // End: