1 // $Id:SocketHandle.hh 218 2007-03-20 14:39:32Z tho $
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
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
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.
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.
19 // The Original Code is Fraunhofer FOKUS code.
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.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief SocketHandle public header
32 #ifndef HH_SENF_Socket_SocketHandle_
33 #define HH_SENF_Socket_SocketHandle_ 1
35 //#include "SocketHandle.mpp"
36 #include "SocketHandle.ih"
39 #include <memory> // std::auto_ptr
40 #include "FileHandle.hh"
41 #include "SocketPolicy.hh"
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
47 /// \addtogroup handle_group
50 /** \brief basic SocketHandle supporting protocol and policy abstraction
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.
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).
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
66 \tparam SPolicy socket policy
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.
71 \todo Create a SocketHandleBase class and move some non-Policy dependent code there
73 template <class SPolicy>
78 //-////////////////////////////////////////////////////////////////////////
81 typedef SPolicy Policy;
83 /** \brief Check policy compatibility
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.
89 template <class OtherPolicy>
91 : public boost::enable_if< SocketPolicyIsBaseOf<Policy,OtherPolicy>, SocketHandle >
94 //-////////////////////////////////////////////////////////////////////////
95 ///\name Structors and default members
98 // default default constructor
99 // default copy constructor
100 // default copy assignment
101 // default destructor
106 // conversion constructors
108 template <class OtherPolicy>
109 SocketHandle(SocketHandle<OtherPolicy> other,
110 typename IsCompatible<OtherPolicy>::type * = 0);
111 ///< Convert from other socket handle checking policy
115 //-////////////////////////////////////////////////////////////////////////
117 template <class OtherPolicy>
118 typename IsCompatible<OtherPolicy>::type const & operator=(SocketHandle<OtherPolicy> other);
119 ///< Assign from other socket handle checking policy
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.
130 See senf::SocketProtocol::state() for more information,
131 how the Information is generated.
133 \param map string to string mapping to be filled with
135 \param lod level of %detail requested. The
136 interpretation of this value is protocol specific
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.
148 \param lod level of %detail requested. The
149 interpretation of this value is protocol specific
151 \implementation This member will be re-implemented in
152 every derived class. See the state()
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
161 \throws std::bad_cast if \a Facet is not a protocol
163 \returns the \a Facet protocol facet of this socket */
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
175 /**< This constructor is used to support up- and downcasting
176 of SocketHandle instances.
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
184 \param other FileHandle to assign
185 \param isChecked has to be \c true
187 \todo Answer, why the heck I need the \c isChecked
190 SocketBody & body(); ///< Access socket body
191 /**< This member replaces the corresponding FileHandle
192 member and returns an appropriately cast body
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
198 SocketProtocol & protocol() const;
199 ///< Access protocol class
201 void assign(FileHandle other); /**< \internal */
204 static SocketHandle cast_static(FileHandle handle);
206 static SocketHandle cast_dynamic(FileHandle handle);
213 /** \brief Write stream status dump to output stream
215 Write senf::SocketHandle::dumpState() to \c os
217 \related senf::SocketHandle
219 template <class SPolicy>
220 std::ostream & operator<<(std::ostream & os, SocketHandle<SPolicy> handle);
222 /** \brief static socket (down-)cast
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.
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
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).
237 \related senf::SocketHandle
239 template <class Target, class Source>
240 Target static_socket_cast(Source handle);
242 /** \brief dynamic socket (down-)cast
244 This function is like \c dynamic_cast but for socket handles. It is a runtime typechecked
245 version of static_socket_cast.
247 \throws std::bad_cast You have tried to perform an invalid down- or crosscast.
249 \related senf::SocketHandle
251 template <class Target, class Source>
252 Target dynamic_socket_cast(Source handle);
254 /** \brief dynamically check cast validity
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.
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.
262 \related senf::SocketHandle
264 template <class Target, class Source>
265 bool check_socket_cast(Source handle);
270 //-/////////////////////////////////////////////////////////////////////////////////////////////////
271 #include "SocketHandle.cci"
272 #include "SocketHandle.ct"
273 #include "SocketHandle.cti"
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