b9abd4716b5473f3eac433e7e06e57e30cdeec5e
[senf.git] / senf / Socket / FileHandle.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
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
10 //
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.
14 //
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.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
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.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief FileHandle public header
30  */
31
32 /** \defgroup handle_group The Handle Hierarchy
33
34     \diaimage FhHierarchy.dia
35
36     The senf::FileHandle class is the base of a hierarchy of socket handle classes (realized as
37     templates). These classes provide an interface to the complete socket API. While going down the
38     inheritance hierarchy, the interface will be more and more complete.
39
40     The most complete interface is provided by senf::ProtocolClientSocketHandle and
41     senf::ProtocolServerSocketHandle. The template Arguments specifies the Protocol class of the
42     underlying socket type. These are the \e only classes having public constructors and are
43     therefore the only classes, which may be created by the library user. You will normally use
44     these classes by naming a specific socket typedef (e.g. senf::TCPv4ClientSocketHandle).
45
46     However, to aid writing flexible and generic code, the socket library provides the
47     senf::ClientSocketHandle and senf::ServerSocketHandle class templates. These templates implement
48     a family of closely related classes based on the specification of the socket policy. This policy
49     specification may be \e incomplete (see below). Instances of
50     senf::ClientSocketHandle/senf::ServerSocketHandle can be assigned and converted to different
51     ClientSocketHandle/ServerSocketHandle types as long as the policy specifications are compatible.
52
53     \attention It is very important, to (almost) always pass the socket handle <em>by
54     value</em>. The socket handle is a very lightweight class and designed to be used like an
55     ordinary built-in type. This is very important in combination with the policy interface.
56
57     \note The FileHandle hierarchy below the SocketHandle template is \e not meant to be user
58     extensible. To add new socket types, you should introduce new protocol and/or policy classes,
59     the SocketHandle classes should not be changed.
60  */
61
62 #ifndef HH_SENF_Socket_FileHandle_
63 #define HH_SENF_Socket_FileHandle_ 1
64
65 // Custom includes
66 #include <memory> // std::auto_ptr
67 #include <senf/Utils/safe_bool.hh>
68 #include <senf/Scheduler/ClockService.hh>
69
70 //#include "FileHandle.mpp"
71 //-/////////////////////////////////////////////////////////////////////////////////////////////////
72 #include "FileHandle.ih"
73
74 namespace senf {
75
76     /// \addtogroup handle_group
77     //\{
78
79     /** \brief Basic file handle wrapper
80
81         senf::FileHandle provides a simple wrapper for arbitrary file handles. It exposes only a
82         minimal interface which does \e not include reading or writing (since some filehandles are
83         not readable or writable or only using special function calls like sendto).
84
85         The FileHandle class provides handle/body handling and uses automatic reference
86         counting. The senf::FileHandle instance is very lightweight and should be used like a
87         built-in type.
88
89         \attention You should mostly pass around senf::FileHandle objects by \e value and not by
90         reference.
91
92         The FileHandle abstraction is only applicable to real filehandles. It is \e not possible to
93         wrap any provider or consumer into a filehandle like interface using this wrapper. The
94         wrapper will forward some calls directly to the underlying API without relying on virtual
95         methods. This allows important members to be inlined.
96
97         It is not possible to use the senf::FileHandle class directly since it does not have any
98         public constructor. The FileHandle class is however the baseclass of all handle classes of
99         the socket library.
100
101         \section filehandle_new Writing senf::FileHandle derived classes
102
103         To build a new FileHandle type you need to derive from senf::FileHandle. The derived class
104         will have to call the protected FileHandle constructor passing a new senf::FileBody
105         instance. This instance may either be a simple senf::FileBody or a class derived from
106         senf::FileBody.
107      */
108     class FileHandle
109         : public safe_bool<FileHandle>
110     {
111     public:
112         //-////////////////////////////////////////////////////////////////////////
113         // Types
114
115         //-////////////////////////////////////////////////////////////////////////
116         ///\name Structors and default members
117         //\{
118
119         FileHandle();
120         ~FileHandle();
121
122         // my default constructor
123         // default copy constructor
124         // default copy assignment
125         // default destructor
126
127         // no conversion constructors
128
129         //\}
130         //-////////////////////////////////////////////////////////////////////////
131
132         void close();                ///< Close filehandle
133                                      /**< \throws senf::SystemException */
134         void terminate();            ///< Close filehandle ignoring error conditions
135
136         bool readable() const;       ///< Check, whether a read on the handle would not block
137                                      ///< (ignoring blocking state)
138         bool waitReadable(senf::ClockService::clock_type timeout = -1) const;
139                                      ///< Wait, until read on the handle would not block (ignoring
140                                      ///< blocking state)
141                                      /**< \param[in] timeout max time to wait, default is to wait
142                                               forever.
143                                           \returns \c true, if handle became readable or \c false on
144                                               timeout. */
145         bool writeable() const;      ///< Check, whether a write on the handle would not block
146                                      ///< (ignoring blocking state)
147         bool waitWriteable(senf::ClockService::clock_type timeout = -1) const;
148                                      ///< Wait, until a write on the handle would not block
149                                      ///< (ignoring blocking state)
150                                      /**< \param[in] timeout max time to wait, default is to wait
151                                               forever.
152                                           \returns \c true, if handle became writable or \c false on
153                                               timeout. */
154         bool oobReadable() const;    ///< Check, whether a read of prioritized data on the handle
155                                      ///< would not block (ignoring blocking state)
156         bool waitOOBReadable(senf::ClockService::clock_type timeout = -1) const;
157                                      ///< Wait, until read of prioritized data on the handle does
158                                      ///< not block (ignoring blocking state)
159                                      /**< \param[in] timeout max time to wait, default is to wait
160                                               forever.
161                                           \returns \c true, if handle became readable for
162                                               out-of-band data or \c false on timeout. */
163
164         bool blocking() const;       ///< Return current blocking state
165         void blocking(bool status);  ///< Set blocking state
166
167         bool eof() const;            ///< Check EOF condition
168                                      /**< Depending on the socket type, this might never return \p
169                                         true.
170
171                                         This member is somewhat problematic performance wise if
172                                         called frequently since it relies on virtual
173                                         functions. However, since the eof() handling is extremely
174                                         protocol dependent, a policy based implementation does not
175                                         seam feasible. */
176         bool valid() const;          ///< Check filehandle validity
177                                      /**< Any operation besides valid() will fail on an invalid
178                                         FileHandle */
179
180         bool boolean_test() const;  ///< Short for valid() && ! eof()
181                                     /**< This is called when using a FileHandle instance in a boolean
182                                        context
183
184                                        See the performance comments for the eof() member */
185
186         int fd() const;             ///< Return the raw FileHandle
187
188         static FileHandle cast_static(FileHandle handle);  /**< \internal */
189         static FileHandle cast_dynamic(FileHandle handle); /**< \internal */
190
191     protected:
192         explicit FileHandle(std::auto_ptr<FileBody> body);
193                                     ///< create new FileHandle instance
194                                     /**< The FileHandle instance will take over ownership over the
195                                        given FileBody instance which must have been allocated using
196                                        \c new. To configure the FileHandle behavior, A derived class
197                                        may provide any class derived from FileBody here. */
198
199         explicit FileHandle(FileBody::ptr body);
200
201         FileBody & body();          ///< Access body
202         FileBody const & body() const; ///< Access body in const context
203         static FileBody & body(FileHandle & handle); ///< Access body of another FileHandle instance
204         static FileBody const & body(FileHandle const & handle); ///< Access body of another
205                                     ///< FileHandle instance in const context
206
207         void fd(int fd);            ///< Set raw filehandle
208
209     private:
210         FileBody::ptr body_;
211
212         friend class FileBody;
213     };
214
215     /** \brief Adapt FileHandle to senf::scheduler
216         \related senf::FileHandle
217
218         \internal
219
220         This function will be called by the Scheduler to retrieve the file descriptor of the
221         FileHandle.
222      */
223     int retrieve_filehandle(FileHandle handle);
224
225     //\}
226
227 }
228
229 //-/////////////////////////////////////////////////////////////////////////////////////////////////
230 #include "FileHandle.cci"
231 //#include "FileHandle.ct"
232 //#include "FileHandle.cti"
233 #endif
234
235 \f
236 // Local Variables:
237 // mode: c++
238 // fill-column: 100
239 // c-file-style: "senf"
240 // indent-tabs-mode: nil
241 // ispell-local-dictionary: "american"
242 // compile-command: "scons -u test"
243 // comment-column: 40
244 // End: