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