6e5cfb92a382ebf120440d2f1332094a7ec9580b
[senf.git] / PPI / SocketSink.hh
1 // $Id$
2 //
3 // Copyright (C) 2007 
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 SocketSink public header */
25
26 #ifndef HH_SocketSink_
27 #define HH_SocketSink_ 1
28
29 // Custom includes
30 #include "../Packets/Packets.hh"
31 #include "../Socket/ClientSocketHandle.hh"
32 #include "../Socket/SocketPolicy.hh"
33 #include "../Socket/ReadWritePolicy.hh"
34 #include "../Socket/FramingPolicy.hh"
35 #include "../Socket/CommunicationPolicy.hh"
36 #include "Module.hh"
37 #include "Connectors.hh"
38
39 //#include "SocketSink.mpp"
40 ///////////////////////////////hh.p////////////////////////////////////////
41
42 namespace senf {
43 namespace ppi {
44
45     /** \brief Writer for module::ActiveSocketSink / module::PassiveSocketSink
46         
47         This writer will write the packets completely as datagrams to the given socket which must be connected. 
48      */
49     class ConnectedDgramWriter
50     {
51     public:
52         typedef senf::ClientSocketHandle<
53             senf::MakeSocketPolicy< senf::WriteablePolicy,
54                                     senf::DatagramFramingPolicy,
55                                     senf::ConnectedCommunicationPolicy>::policy > Handle;
56                                         ///< Handle type supported by this writer
57         
58         void operator()(Handle handle, Packet packet);
59                                         ///< Write \a packet to \a handle
60                                         /**< Write the complete \a packet as a datagram to \a
61                                              handle.
62                                              \param[in] handle Handle to write data to
63                                              \param[in] packet Packet to write */
64     };
65
66 }}
67
68 namespace senf {
69 namespace ppi {
70 namespace module {
71
72     /** \brief Output module writing data to a FileHandle using the provided Writer.
73         If using the default ConnectedDgramWriter the filehandle must be writable, connected and 
74         able to handle complete datagrams.  
75         
76         This output module will write data to a FileHandle object using a given \a Writer. This
77         output module is active. This requires the file handle to be able to signal its readiness to
78         accept more data via the Scheduler.
79
80         The default \a Writer is senf::ppi::ConnectedDgramWriter which will write out the complete packet to
81         the file handle.
82
83         A \a Writer must fulfill the following interface:
84         \code
85           class SomeWriter
86           {
87           public:
88               typedef unspecified Handle;                          // type of handle requested
89
90               SomeWriter();                                          // EITHER default constructible OR
91               SomeWriter(SomeWriter const & other);                    // copy constructible
92
93               void operator()(Handle handle, Packet packet);       // insertion function
94           };
95         \endcode
96         Whenever a packet is received for sending, the \a Writer's \c operator() is called.
97
98         \ingroup io_modules
99      */
100     template <class Writer=ConnectedDgramWriter>
101     class ActiveSocketSink : public Module
102     {
103         SENF_PPI_MODULE(ActiveSocketSink);
104
105     public:
106         typedef typename Writer::Handle Handle; ///< Handle type requested by writer
107
108         connector::ActiveInput<> input; ///< Input connector from which data is received
109         
110         ActiveSocketSink(Handle handle); ///< Create new writer for the given handle
111                                         /**< Data will be written to \a handle using \a Writer.
112                                              \pre Requires \a Writer to be default constructible
113                                              \param[in] handle Handle to write data to */
114         ActiveSocketSink(Handle handle, Writer const & writer); 
115                                         ///< Create new writer for the given handle
116                                         /**< Data will be written to \a handle using \a Writer.
117                                              \pre Requires \a Writer to be copy constructible
118                                              \param[in] handle Handle to write data to 
119                                              \param[in] writer Writer helper writing packet date to the
120                                                  socket */
121
122         Writer & writer();                  ///< Access the Writer
123     private:
124         void write();
125
126         Handle handle_;
127         IOEvent event_;
128         Writer writer_;
129     };
130
131     /** \brief Output module writing data to a FileHandle using the provided \a Writer.
132         If using the default ConnectedDgramWriter the filehandle must be writable, connected and 
133         able to handle complete datagrams.  
134         
135         This output module will write data to a FileHandle object using a given \a Writer. This
136         output module is passive. This implies, that the output handle may not block. This also
137         implies, that data will probably get lost if written to fast for the underlying transport
138         mechanism. Either this is desired (like for a UDP socket) or some additional bandwidth
139         shaping needs to be used.
140
141         The default \a Writer is senf::ppi::ConnectedDgramWriter which will write out the complete packet to
142         the file handle.
143
144         The \a Writer must fulfill the following interface:
145         \code
146           class SomeWriter
147           {
148           public:
149               typedef unspecified Handle;                          // type of handle requested
150
151               SomeWriter();                                          // EITHER default constructible
152               SomeWriter(SomeWriter const & other);                    // OR copy constructible
153
154               void operator()(Handle handle, Packet packet);       // insertion function
155           };
156         \endcode
157         Whenever a packet is received for sending, the \a Writer's \c operator() is called.
158
159         \ingroup io_modules
160      */
161     template <class Writer=ConnectedDgramWriter>
162     class PassiveSocketSink : public Module
163     {
164         SENF_PPI_MODULE(PassiveSocketSink);
165
166     public:
167         typedef typename Writer::Handle Handle; ///< Handle type requested by writer
168
169         connector::PassiveInput<> input; ///< Input connector from which data is received
170         
171         PassiveSocketSink(Handle handle); ///< Create new writer for the given handle
172                                         /**< Data will be written to \a handle using \a Writer.
173                                              \pre Requires \a Writer to be default constructible
174                                              \param[in] handle Handle to write data to */
175         PassiveSocketSink(Handle handle, Writer const & writer);
176                                         ///< Create new writer for the given handle
177                                         /**< Data will be written to \a handle using \a Writer.
178                                              \pre Requires \a Writer to be copy constructible
179                                              \param[in] handle Handle to write data to */
180
181         Writer & writer();      ///< Access the Writer
182         Handle & handle();      /**< Access the handle. This is intendet to be mainly used to reconnect 
183                                      the underlying socket. */
184        /* void reconnect(senf::SocketAddress newAddress);
185         ///< Reconnect the handle to which the packets are written
186        */
187         void replaceHandle(Handle newHandle);
188                                         /**< Replace the handle to which the packets are written
189                                          * Normally you should access the handle and call connect with
190                                          * the new address. This also works for other 
191                                          * (active) ConnectedSocketSinks/Sources */
192                                         
193     private:
194         void write();
195
196         Handle handle_;
197         Writer writer_;
198     };
199
200 }}}
201
202
203 ///////////////////////////////hh.e////////////////////////////////////////
204 #include "SocketSink.cci"
205 #include "SocketSink.ct"
206 #include "SocketSink.cti"
207 #endif
208
209 \f
210 // Local Variables:
211 // mode: c++
212 // fill-column: 100
213 // c-file-style: "senf"
214 // indent-tabs-mode: nil
215 // ispell-local-dictionary: "american"
216 // compile-command: "scons -u test"
217 // comment-column: 40
218 // End: