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