Finished Socket library file handle hierarchy documentation
[senf.git] / Socket / SocketHandle.hh
1 // $Id$
2 //
3 // Copyright (C) 2006 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.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 senf::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 copy constructor
93         // default copy assignment
94         // default destructor
95
96         // conversion constructors
97         
98         template <class OtherPolicy>
99         SocketHandle(SocketHandle<OtherPolicy> other, 
100                      typename IsCompatible<OtherPolicy>::type * = 0);
101                                         ///< Convert from other socket handle checking policy
102                                         ///< compatibility
103
104         ///@}
105         ///////////////////////////////////////////////////////////////////////////
106
107         template <class OtherPolicy>
108         typename IsCompatible<OtherPolicy>::type const & operator=(SocketHandle<OtherPolicy> other);
109                                         ///< Assign from other socket handle checking policy
110                                         ///< compatibility
111
112         void state(SocketStateMap & map, unsigned lod=0);
113                                         ///< Inquire state information of socket handle
114                                         /**< The map argument (a string to string mapping) will be
115                                            filled with information coverning the current state of
116                                            the socket. The information provided depends on the
117                                            socket protocol. The amount of information returned can
118                                            be controlled using the \p lod value.
119
120                                            See senf::SocketProtocol::state() for more information,
121                                            how the Information is generated.
122
123                                            \param map string to string mapping to be filled with
124                                                state information
125                                            \param lod level of detail requesten. The interpretation
126                                                of this value is protocol specific 
127
128                                            \implementation This member will be re-implemented in
129                                            every derived class. This is very important since state()
130                                            is \e not a virtual function (which we don't want since
131                                            we don't want to add a vtable pointer to every handle
132                                            instance). */
133         std::string dumpState(unsigned lod=0);
134                                         ///< Format complete state information as string
135                                         /**< Formats the complete state map value and returns it as
136                                            a single multi-line string.
137
138                                            \implementation This member will be re-implemented in
139                                            every derived class. See the state() documentation. */
140
141     protected:
142         explicit SocketHandle(std::auto_ptr<SocketProtocol> protocol, bool isServer);
143                                         ///< Initialize SocketHandle providing the protocol
144                                         /**< \param protocol Protocol class of the protocol
145                                                  implemented by this socket handle
146                                              \param isServer \c true, if this SocketHandle instance
147                                                  implements a server handle, \c false otherwise */
148         SocketHandle(FileHandle other, bool isChecked);
149                                         ///< Initialize SocketHandle from arbitrary checked
150                                         ///< FileHandle
151                                         /**< This constructor is used to support up- and downcasting
152                                            of SocketHandle instances.
153
154                                            \warning It is absolutely necessary to ensure, that the
155                                            FileHandle passed in is \e really a SocketHandle holding
156                                            a SocketBody (and not a simple FileBody)
157                                            instance. Additionally. the SocketPolicy absolutely must
158                                            be compatible.
159
160                                            \param other FileHandle to assign
161                                            \param isChecked has to be \c true
162
163                                            \todo Answer, why the heck I need the \c isChecked
164                                            parameter ??
165                                         */
166
167         SocketBody & body();            ///< Access socket body
168                                         /**< This member replaces the corresponding FileHandle
169                                            member and returns an appropriately cast body reference */
170         SocketBody const & body() const; ///< Access socket body in const context
171                                         /**< This member replaces the corresponding FileHandle
172                                            member and returns an appropriately cast body reference */
173         SocketProtocol const & protocol() const;
174                                         ///< Access protocol class
175
176         void assign(FileHandle other);  /**< \internal */
177
178     public:
179         static SocketHandle cast_static(FileHandle handle);
180                                         /**< \internal */
181         static SocketHandle cast_dynamic(FileHandle handle);
182                                         /**< \internal */
183
184     private:
185
186     };
187
188     /** \brief Write stream status dump to output stream
189
190         Write senf::SocketHandle::dumpState() to \c os
191
192         \related senf::SocketHandle
193      */
194     template <class Policy>
195     std::ostream & operator<<(std::ostream & os, SocketHandle<Policy> handle);
196
197     /** \brief static socket (down-)cast
198         
199         This function is like \c static_cast but for socket handles. It allows to downcast any
200         FileHandle to any SocketHandle (and its derived types). static_socket_cast will \e not check
201         the validity of the cast, it will assume, that the cast is valid.
202
203         The function will however check, that the cast is possible. Casting between (at compile
204         time) known incompatible types (like casting a SocketHandle with a communication policy of
205         ConnectedCommunicationPolicy to a SocketHandle with UnconnectedCommunicationPolicy will fail
206         at compile time).
207
208         \warning
209         If the type you cast to is not really a compatible socket handle type you will get undefined
210         behavior, probably your program will crash (You will get an assertion in debug builds).
211
212         \related senf::SocketHandle
213      */
214     template <class Target, class Source>
215     Target static_socket_cast(Source handle);
216
217     /** \brief dynamic socket (down-)cast
218
219         This function is like \c dynamic_cast but for socket handles. It is a runtime typechecked
220         version of static_socket_cast.
221         
222         \throws std::bad_cast You have tried to perform an invalid down- or crosscast.
223         
224         \related senf::SocketHandle
225      */
226     template <class Target, class Source>
227     Target dynamic_socket_cast(Source handle);
228
229     /** \brief dynamically check cast validity
230
231         This function will check, wether the given cast is valid. This is the same as checking, that
232         dynamic_socket_cast does not throw.
233
234         This member is needed, since there is no 'null' SocketHandle (comparable to a null pointer)
235         which could be returned by a non-throwing variant of dynamic_socket_cast.
236
237         \related senf::SocketHandle
238      */
239     template <class Target, class Source>
240     bool check_socket_cast(Source handle);
241
242     /// @}
243 }
244
245 ///////////////////////////////hh.e////////////////////////////////////////
246 #include "SocketHandle.cci"
247 #include "SocketHandle.ct"
248 #include "SocketHandle.cti"
249 #endif
250
251 \f
252 // Local Variables:
253 // mode: c++
254 // c-file-style: "senf"
255 // fill-column: 100
256 // End: