4a126c0a1f360c5f4b84338225f67c4b60d6c658
[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 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief SocketHandle public header
25  */
26
27 #ifndef HH_SENF_Socket_SocketHandle_
28 #define HH_SENF_Socket_SocketHandle_ 1
29
30 //#include "SocketHandle.mpp"
31 #include "SocketHandle.ih"
32
33 // Custom includes
34 #include <memory> // std::auto_ptr
35 #include "FileHandle.hh"
36 #include "SocketPolicy.hh"
37
38 //-/////////////////////////////////////////////////////////////////////////////////////////////////
39
40 namespace senf {
41
42     /// \addtogroup handle_group
43     //\{
44
45     /** \brief basic SocketHandle supporting protocol and policy abstraction
46
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.
50
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).
54
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
59         discussion).
60
61         \tparam SPolicy socket policy
62
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.
65
66         \todo Create a SocketHandleBase class and move some non-Policy dependent code there
67      */
68     template <class SPolicy>
69     class SocketHandle
70         : public FileHandle
71     {
72     public:
73         //-////////////////////////////////////////////////////////////////////////
74         // Types
75
76         typedef SPolicy Policy;
77
78         /** \brief Check policy compatibility
79
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.
83          */
84         template <class OtherPolicy>
85         struct IsCompatible
86             : public boost::enable_if< SocketPolicyIsBaseOf<Policy,OtherPolicy>, SocketHandle >
87         {};
88
89         //-////////////////////////////////////////////////////////////////////////
90         ///\name Structors and default members
91         //\{
92
93         // default default constructor
94         // default copy constructor
95         // default copy assignment
96         // default destructor
97
98         // here to implement
99         SocketHandle();
100
101         // conversion constructors
102
103         template <class OtherPolicy>
104         SocketHandle(SocketHandle<OtherPolicy> other,
105                      typename IsCompatible<OtherPolicy>::type * = 0);
106                                         ///< Convert from other socket handle checking policy
107                                         ///< compatibility
108
109         //\}
110         //-////////////////////////////////////////////////////////////////////////
111
112         template <class OtherPolicy>
113         typename IsCompatible<OtherPolicy>::type const & operator=(SocketHandle<OtherPolicy> other);
114                                         ///< Assign from other socket handle checking policy
115                                         ///< compatibility
116
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.
124
125                                              See senf::SocketProtocol::state() for more information,
126                                              how the Information is generated.
127
128                                              \param map string to string mapping to be filled with
129                                                  state information
130                                              \param lod level of %detail requested. The
131                                                  interpretation of this value is protocol specific
132
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.
142
143                                              \param lod level of %detail requested. The
144                                                 interpretation of this value is protocol specific
145
146                                              \implementation This member will be re-implemented in
147                                                  every derived class. See the state()
148                                                  documentation. */
149
150         template <class Facet>
151         Facet & 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
155                                              will be thrown.
156                                              \throws std::bad_cast if \a Facet is not a protocol
157                                                  facet of this socket
158                                              \returns the \a Facet protocol facet of this socket */
159
160     protected:
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
169                                         ///< FileHandle
170                                         /**< This constructor is used to support up- and downcasting
171                                              of SocketHandle instances.
172
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
177                                                  must be compatible.
178
179                                              \param other FileHandle to assign
180                                              \param isChecked has to be \c true
181
182                                              \todo Answer, why the heck I need the \c isChecked
183                                                  parameter ?? */
184
185         SocketBody & body();            ///< Access socket body
186                                         /**< This member replaces the corresponding FileHandle
187                                              member and returns an appropriately cast body
188                                              reference */
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
192                                              reference */
193         SocketProtocol & protocol() const;
194                                         ///< Access protocol class
195
196         void assign(FileHandle other);  /**< \internal */
197
198     public:
199         static SocketHandle cast_static(FileHandle handle);
200                                         /**< \internal */
201         static SocketHandle cast_dynamic(FileHandle handle);
202                                         /**< \internal */
203
204     private:
205
206     };
207
208     /** \brief Write stream status dump to output stream
209
210         Write senf::SocketHandle::dumpState() to \c os
211
212         \related senf::SocketHandle
213      */
214     template <class SPolicy>
215     std::ostream & operator<<(std::ostream & os, SocketHandle<SPolicy> handle);
216
217     /** \brief static socket (down-)cast
218
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.
222
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
226         at compile time).
227
228         \warning
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).
231
232         \related senf::SocketHandle
233      */
234     template <class Target, class Source>
235     Target static_socket_cast(Source handle);
236
237     /** \brief dynamic socket (down-)cast
238
239         This function is like \c dynamic_cast but for socket handles. It is a runtime typechecked
240         version of static_socket_cast.
241
242         \throws std::bad_cast You have tried to perform an invalid down- or crosscast.
243
244         \related senf::SocketHandle
245      */
246     template <class Target, class Source>
247     Target dynamic_socket_cast(Source handle);
248
249     /** \brief dynamically check cast validity
250
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.
253
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.
256
257         \related senf::SocketHandle
258      */
259     template <class Target, class Source>
260     bool check_socket_cast(Source handle);
261
262     //\}
263 }
264
265 //-/////////////////////////////////////////////////////////////////////////////////////////////////
266 #include "SocketHandle.cci"
267 #include "SocketHandle.ct"
268 #include "SocketHandle.cti"
269 #endif
270
271 \f
272 // Local Variables:
273 // mode: c++
274 // fill-column: 100
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
280 // End: