1 // $Id:SocketHandle.hh 218 2007-03-20 14:39:32Z tho $
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief SocketHandle public header
27 #ifndef HH_SENF_Socket_SocketHandle_
28 #define HH_SENF_Socket_SocketHandle_ 1
31 #include <memory> // std::auto_ptr
32 #include "FileHandle.hh"
33 #include "SocketPolicy.hh"
35 //#include "SocketHandle.mpp"
36 #include "SocketHandle.ih"
37 ///////////////////////////////hh.p////////////////////////////////////////
38 #include "SocketHandle.ih"
42 /// \addtogroup handle_group
45 /** \brief basic SocketHandle supporting protocol and policy abstraction
47 The %senf::SocketHandle class introduces the two abstraction layers of the socket
48 library. senf::SocketHandle does \e not provide socket functions it only provides the
49 infrastructure necessary to support both, the protocol and the policy interface.
51 %SocketHandle takes the socket policy as a template argument. %SocketHandle also
52 introduces the protocol class. However, the class has no public constructors (see the
53 derived classes senf::ProtocolClientSocketHandle and senf::ProtocolServerSocketHandle).
55 The most important functionality provided by %SocketHandle is the conversion
56 constructor. This allows to implicitly convert between compatible socket handle types as
57 specified by the socket policy. The conversion constructor is defined in such a way, that
58 only valid conversions are possible (see the implementation source for a more complete
61 \tparam SPolicy socket policy
63 \note This class is \e not meant to be used as a base-class outside the library
64 implementation; The protected interface is for internal use only.
66 \todo Create a SocketHandleBase class and move some non-Policy dependent code there
68 template <class SPolicy>
73 ///////////////////////////////////////////////////////////////////////////
76 typedef SPolicy Policy;
78 /** \brief Check policy compatibility
80 IsCompatible is a template meta-function which will check some other socket policy for
81 conversion compatibility. This check is used in the senf::SocketPolicy implementation to
82 restrict the conversion operator.
84 template <class OtherPolicy>
86 : public boost::enable_if< SocketPolicyIsBaseOf<Policy,OtherPolicy>, SocketHandle >
89 ///////////////////////////////////////////////////////////////////////////
90 ///\name Structors and default members
93 // default default constructor
94 // default copy constructor
95 // default copy assignment
101 // conversion constructors
103 template <class OtherPolicy>
104 SocketHandle(SocketHandle<OtherPolicy> other,
105 typename IsCompatible<OtherPolicy>::type * = 0);
106 ///< Convert from other socket handle checking policy
110 ///////////////////////////////////////////////////////////////////////////
112 template <class OtherPolicy>
113 typename IsCompatible<OtherPolicy>::type const & operator=(SocketHandle<OtherPolicy> other);
114 ///< Assign from other socket handle checking policy
117 void state(SocketStateMap & map, unsigned lod=0);
118 ///< Inquire state information of socket handle
119 /**< The map argument (a string to string mapping) will be
120 filled with information covering the current state of
121 the socket. The information provided depends on the
122 socket protocol. The amount of information returned can
123 be controlled using the \p lod value.
125 See senf::SocketProtocol::state() for more information,
126 how the Information is generated.
128 \param map string to string mapping to be filled with
130 \param lod level of %detail requested. The
131 interpretation of this value is protocol specific
133 \implementation This member will be re-implemented in
134 every derived class. This is very important since
135 state() is \e not a virtual function (which we
136 don't want since we don't want to add a vtable
137 pointer to every handle instance). */
138 std::string dumpState(unsigned lod=0);
139 ///< Format complete state information as string
140 /**< Formats the complete state map value and returns it as
141 a single multi-line string.
143 \param lod level of %detail requested. The
144 interpretation of this value is protocol specific
146 \implementation This member will be re-implemented in
147 every derived class. See the state()
150 template <class Facet>
151 Facet const & facet(); ///< Access a protocol facet
152 /**< This member will try to access the given protocol facet
153 of the socket. If \a Facet is a valid facet of the
154 protocol, it is returned, otherwise \c std::bad_cast
156 \throws std::bad_cast if \a Facet is not a protocol
158 \returns the \a Facet protocol facet of this socket */
161 explicit SocketHandle(std::auto_ptr<SocketBody> body);
162 ///< Initialize SocketHandle providing the protocol
163 /**< \param protocol Protocol class of the protocol
164 implemented by this socket handle
165 \param isServer \c true, if this SobcketHandle instance
166 implements a server handle, \c false otherwise */
167 SocketHandle(FileHandle other, bool isChecked);
168 ///< Initialize SocketHandle from arbitrary checked
170 /**< This constructor is used to support up- and downcasting
171 of SocketHandle instances.
173 \warning It is absolutely necessary to ensure, that the
174 FileHandle passed in is \e really a SocketHandle
175 holding a SocketBody (and not a simple FileBody)
176 instance. Additionally. the SocketPolicy absolutely
179 \param other FileHandle to assign
180 \param isChecked has to be \c true
182 \todo Answer, why the heck I need the \c isChecked
185 SocketBody & body(); ///< Access socket body
186 /**< This member replaces the corresponding FileHandle
187 member and returns an appropriately cast body
189 SocketBody const & body() const; ///< Access socket body in const context
190 /**< This member replaces the corresponding FileHandle
191 member and returns an appropriately cast body
193 SocketProtocol const & protocol() const;
194 ///< Access protocol class
196 void assign(FileHandle other); /**< \internal */
199 static SocketHandle cast_static(FileHandle handle);
201 static SocketHandle cast_dynamic(FileHandle handle);
208 /** \brief Write stream status dump to output stream
210 Write senf::SocketHandle::dumpState() to \c os
212 \related senf::SocketHandle
214 template <class SPolicy>
215 std::ostream & operator<<(std::ostream & os, SocketHandle<SPolicy> handle);
217 /** \brief static socket (down-)cast
219 This function is like \c static_cast but for socket handles. It allows to downcast any
220 FileHandle to any SocketHandle (and its derived types). static_socket_cast will \e not check
221 the validity of the cast, it will assume, that the cast is valid.
223 The function will however check, that the cast is possible. Casting between (at compile
224 time) known incompatible types (like casting a SocketHandle with a communication policy of
225 ConnectedCommunicationPolicy to a SocketHandle with UnconnectedCommunicationPolicy will fail
229 If the type you cast to is not really a compatible socket handle type you will get undefined
230 behavior, probably your program will crash (You will get an assertion in debug builds).
232 \related senf::SocketHandle
234 template <class Target, class Source>
235 Target static_socket_cast(Source handle);
237 /** \brief dynamic socket (down-)cast
239 This function is like \c dynamic_cast but for socket handles. It is a runtime typechecked
240 version of static_socket_cast.
242 \throws std::bad_cast You have tried to perform an invalid down- or crosscast.
244 \related senf::SocketHandle
246 template <class Target, class Source>
247 Target dynamic_socket_cast(Source handle);
249 /** \brief dynamically check cast validity
251 This function will check, whether the given cast is valid. This is the same as checking, that
252 dynamic_socket_cast does not throw.
254 This member is needed, since there is no 'null' SocketHandle (comparable to a null pointer)
255 which could be returned by a non-throwing variant of dynamic_socket_cast.
257 \related senf::SocketHandle
259 template <class Target, class Source>
260 bool check_socket_cast(Source handle);
265 ///////////////////////////////hh.e////////////////////////////////////////
266 #include "SocketHandle.cci"
267 #include "SocketHandle.ct"
268 #include "SocketHandle.cti"
275 // c-file-style: "senf"
276 // indent-tabs-mode: nil
277 // ispell-local-dictionary: "american"
278 // compile-command: "scons -u test"
279 // comment-column: 40