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