Packets: extended description of bad_cast exception in Packet.as()
[senf.git] / senf / PPI / DebugModules.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 DebugModules public header */
25
26 #ifndef HH_SENF_PPI_DebugModules_
27 #define HH_SENF_PPI_DebugModules_ 1
28
29 // Custom includes
30 #include <deque>
31 #include <senf/Utils/safe_bool.hh>
32 #include "MonitorModule.hh"
33 #include "ActiveFeeder.hh"
34 #include <senf/Utils/Logger/SenfLog.hh>
35
36 //#include "DebugModules.mpp"
37 //-/////////////////////////////////////////////////////////////////////////////////////////////////
38
39 namespace senf {
40 namespace ppi {
41 namespace module {
42 namespace debug {
43
44     /** \namespace senf::ppi::module::debug
45         \brief Debug modules
46
47         This namespace collects several modules helpful for PPI debugging. The modules allow to
48         manually pass packets into a network and read back the output packets.
49
50         There are three categories of modules:
51
52         \li <i>Active modules</i> (ActiveSource, ActiveSink) are triggered by external
53             calls. Calling \c submit() / \c request() will send the request into the module network
54             synchronously. From this it follows, that senf::ppi::run() should \e not be
55             called. Instead senf::ppi::init() is used to initialize the network and explicit calls
56             to the active debug modules drive the execution.
57         \li <i>Passive modules</i> (PassiveSource, PassiveSink) contain a queue to save packets
58             (either packets to be transmitted or packets received) and are driven by the network.
59         \li <i>Feeder (almost-)modules</i> (ActiveFeederSource, ActiveFeederSink) are a hybrid of
60             both types of modules: They contain a packet queue but actively drive the network and
61             are used together with senf::ppi::run(). senf::ppi::run() will automatically terminate
62             if all available packets have been processed. These are not modules, they are
63             collections combining a passive debug module and a senf::ppi::ActiveFeeder.
64      */
65
66     /** \brief Debug packet source with active output
67
68         This module provides packets into the network. Each call to submit() will process the packet
69         synchronously.
70
71         \note This module should not be used together with senf::ppi::run(). Instead use
72             senf::ppi::init() and explicit submit() calls. It follows, that <em>no events will be
73             signaled in the network</em>.
74      */
75     class ActiveSource
76         : public Module,
77           public safe_bool<ActiveSource>
78     {
79         SENF_PPI_MODULE(ActiveSource);
80
81     public:
82         connector::ActiveOutput<> output;
83
84         ActiveSource();
85
86         void submit(Packet const & packet);     ///< Submit packet
87                                         /**< \pre boolean_test() is \c true */
88
89         bool boolean_test() const;      ///< \c true if \a output is not throttled
90     };
91
92     /** \brief Debug packet source with passive output
93
94         This module provides a queue of packets for reading by the network. Each submit() call adds
95         a packet to the queue which will be sent into the network when requested. The output is
96         automatically throttled when the queue becomes empty.
97      */
98     class PassiveSource
99         : public Module
100     {
101         SENF_PPI_MODULE(PassiveSource);
102
103         typedef std::deque<Packet> Queue;
104
105     public:
106         typedef Queue::size_type size_type;
107
108         connector::PassiveOutput<> output;
109
110         PassiveSource();
111
112         void throttle();                ///< Throttle output connector
113         void unthrottle();              ///< Unthrottle output connector
114
115         void submit(Packet const & packet);     ///< Enqueue packet
116
117         bool empty();                   ///< \c true if queue is empty
118         size_type size();               ///< Number of packets in queue
119
120     private:
121         void request();
122         virtual void v_init();
123
124         Queue packets_;
125     };
126
127     /** \brief Debug packet sink with active input
128
129         This module requests packets from the network. Each call to request() will pass a packet
130         request into the network.
131
132         \note This module should not be used together with senf::ppi::run(). Instead use
133             senf::ppi::init() and explicit request() calls. It follows, that <em>no events will be
134             signaled in the network</em>.
135      */
136     class ActiveSink
137         : public Module,
138           public safe_bool<ActiveSink>
139     {
140         SENF_PPI_MODULE(ActiveSink);
141
142     public:
143         connector::ActiveInput<> input;
144
145         ActiveSink();
146
147         Packet request();               ///< Request packet
148                                         /**< \pre boolean_test() is \c true */
149
150         bool boolean_test() const;      ///< \c true, if \a input is not throttled
151     };
152
153     /** \brief Debug packet sink with passive input
154
155         This module provides a queue for the network to write packets into. The packets can then
156         later be analyzed.
157      */
158     class PassiveSink
159         : public Module
160     {
161         SENF_PPI_MODULE(PassiveSink);
162
163         typedef std::deque<Packet> Queue;
164
165     public:
166         typedef Queue::size_type size_type;
167         typedef Queue::const_iterator iterator;
168
169         connector::PassiveInput<> input;
170
171         PassiveSink();
172
173         void throttle();                ///< Throttle input connection
174         void unthrottle();              ///< Unthrottle input connection
175
176         bool empty();                   ///< \c true, if queue is empty
177         size_type size();               ///< number of packets in the queue
178         iterator begin();               ///< begin iterator of packets in the queue
179         iterator end();                 ///< past-the-end iterator of packets in the queue
180
181         Packet front();                 ///< first packet in the queue
182         Packet pop_front();             ///< remove and return first packet in the queue
183
184         void clear();                   ///< clear the queue
185
186     private:
187         void request();
188
189         Queue packets_;
190     };
191
192     /** \brief Active, queue-based packet source
193
194         The ActiveFeederSource contains a packet queue containing the packets to be processed. These
195         packets are actively fed into the network when it is run with senf::ppi::run() until it is
196         empty, when senf::ppi::run() will return.
197
198         \note senf::ppi::run will return as soon as no events are active. If want you want is to
199             Process a set of packets placed into the ActiveFeederSource queue you must make sure,
200             that eventually all events in the module are disabled by throttling or other
201             activities. Otherwise, senf::ppi::run() will \e not return.
202
203         ActiveFeederSource is not a module but a collection of two modules: a PassiveSource and an
204         ActiveFeeder.
205      */
206     class ActiveFeederSource
207     {
208     private:
209         PassiveSource source;
210         ActiveFeeder feeder;
211
212     public:
213         typedef PassiveSource::size_type size_type;
214
215         connector::ActiveOutput<> & output;
216
217         ActiveFeederSource();
218
219         void submit(Packet packet);     ///< enqueue packet
220         bool empty();                   ///< \c true, if queue is empty
221         size_type size();               ///< number of packets in the queue
222     };
223
224     /** \brief Active, queue-based packet sink
225
226         The ActiveFeederSink contains a packet queue to receive the packets from the network. The
227         ActiveFeederSink will actively request packets from the network until it's input is
228         throttled.
229
230         \note ActiveFeederSink does \e not have a termination condition like ActiveFeederSource, it
231             relies on the network to throttle it's input. Additionally, the restrictions of
232             ActiveFeederSource apply here too: You need to ensure, that no (additional) events are
233             active (eventually) or senf::ppi::run will not return.
234
235         ActiveFeederSink is not a module but a collection of two modules: a PassiveSink and an
236         ActiveFeeder.
237      */
238     class ActiveFeederSink
239     {
240     private:
241         PassiveSink sink;
242         ActiveFeeder feeder;
243
244     public:
245         typedef PassiveSink::size_type size_type;
246         typedef PassiveSink::iterator iterator;
247
248         connector::ActiveInput<> & input;
249
250         ActiveFeederSink();
251
252         bool empty();
253         size_type size();
254         iterator begin();
255         iterator end();
256
257         Packet front();
258         Packet pop_front();
259
260         void clear();
261     };
262
263     /** \brief Log received packets
264
265         This module will %log all packets sent to it's input using SENF_LOG to the given %log
266         \a Stream, \a Area and \a Level.
267      */
268     template < class Stream = log::Debug,
269                class Area   = log::DefaultArea,
270                class Level  = log::VERBOSE >
271     class Logger
272         : public MonitorModule<>
273     {
274         SENF_PPI_MODULE(Logger);
275     public:
276         Logger();
277         explicit Logger(std::string label);
278
279     private:
280         virtual void v_handlePacket(Packet const & packet);
281
282         std::string label_;
283     };
284
285 }}}}
286
287 //-/////////////////////////////////////////////////////////////////////////////////////////////////
288 #include "DebugModules.cci"
289 //#include "DebugModules.ct"
290 #include "DebugModules.cti"
291 #endif
292
293 \f
294 // Local Variables:
295 // mode: c++
296 // fill-column: 100
297 // comment-column: 40
298 // c-file-style: "senf"
299 // indent-tabs-mode: nil
300 // ispell-local-dictionary: "american"
301 // compile-command: "scons -u test"
302 // End: