Utils/Daemon: Add warning when the scheduler has registered events at a fork()
[senf.git] / Packets / PacketInterpreter.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 PacketInterpreter public header */
25
26 #ifndef HH_PacketInterpreter_
27 #define HH_PacketInterpreter_ 1
28
29 // Custom includes
30 #include "../boost/intrusive/ilist.hpp"
31 #include <boost/optional.hpp>
32 #include <boost/range.hpp>
33 #include <boost/type_traits/aligned_storage.hpp>
34 #include <boost/type_traits/alignment_of.hpp>
35 #include "../Utils/intrusive_refcount.hh"
36 #include "../Utils/pool_alloc_mixin.hh"
37 #include "../Utils/Tags.hh"
38 #include "PacketData.hh"
39 #include "../Utils/TypeIdValue.hh"
40
41 //#include "PacketInterpreter.mpp"
42 ///////////////////////////////hh.p////////////////////////////////////////
43
44 namespace senf {
45
46     template <class PacketType> class PacketInterpreter;
47
48     /** \brief Internal: Base packet interpreter class
49         
50         \internal
51
52         This is the base class for the persistent interpreter. This class encapsulates all the
53         functionality accessible via the packet handle, most handle operations are just forwarded.
54       */
55     class PacketInterpreterBase
56         : protected PacketData, 
57           public detail::packet::interpreter_list_base,
58           public intrusive_refcount_t<PacketInterpreterBase>
59     {
60     public:
61         ///////////////////////////////////////////////////////////////////////////
62         // Types
63
64         typedef senf::detail::packet::smart_pointer<
65             PacketInterpreterBase>::ptr_t ptr;
66
67         typedef senf::detail::packet::iterator iterator;
68         typedef senf::detail::packet::const_iterator const_iterator;
69         typedef senf::detail::packet::size_type size_type;
70         typedef senf::detail::packet::difference_type difference_type;
71         typedef senf::detail::packet::byte byte;
72
73         typedef boost::iterator_range<iterator> range;
74         typedef boost::optional< boost::iterator_range<iterator> > optional_range;
75         typedef optional_range no_range;
76
77         enum Append_t { Append };
78         enum Prepend_t { Prepend };
79
80         /** \brief Internal: Abstract packet factory
81
82             \internal
83
84             This abstract class provides an abstract packet factory interface. It allows to call
85             almost any one of the create / createAfter / createBefore static PacketInterpreter
86             without static information on the type of packet to create.
87          */
88         struct Factory { 
89             virtual ~Factory();
90
91             // Create completely new packet
92
93             virtual ptr create() const = 0;
94             virtual ptr create(senf::NoInit_t) const = 0;
95             virtual ptr create(size_type size) const = 0;
96             virtual ptr create(size_type size, senf::NoInit_t) const = 0;
97             template <class ForwardReadableRange>
98             ptr create(ForwardReadableRange const & range) const;
99             
100             // Create packet as new packet after a given packet
101
102             virtual ptr createAfter(PacketInterpreterBase::ptr packet) const = 0;
103             virtual ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t) const = 0;
104             virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size) const = 0;
105             virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, 
106                                     senf::NoInit_t) const = 0;
107             template <class ForwardReadableRange>
108             ptr createAfter(PacketInterpreterBase::ptr packet, 
109                             ForwardReadableRange const & range) const;
110             
111             // Create packet as new packet (header) const before a given packet
112
113             virtual ptr createBefore(PacketInterpreterBase::ptr packet) const = 0;
114             virtual ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t) const = 0;
115
116             // Parse next packet in chain
117
118             virtual ptr parseNext(ptr packet) const = 0;
119         };
120
121         typedef Factory const * factory_t;
122
123         ///////////////////////////////////////////////////////////////////////////
124         ///\name Structors and default members
125         ///@{
126
127         // protected constructors
128         // no copy
129         // no conversion constructors
130
131         virtual ~PacketInterpreterBase();
132
133         static                             factory_t no_factory();
134         
135         ptr clone();
136  
137         ///@}
138         ///////////////////////////////////////////////////////////////////////////
139
140         ///\name Interpreter chain access
141         ///@{
142
143         ptr next();
144         ptr prev();
145         ptr first();
146         ptr last();
147
148         template <class Type> typename PacketInterpreter<Type>::ptr parseNextAs();
149                                        ptr                          parseNextAs(factory_t factory);
150         template <class Type>          bool                         is();
151         template <class Type> typename PacketInterpreter<Type>::ptr as();
152
153         ptr append(ptr packet);
154
155         ///@}
156
157         ///\name Data access
158         ///@{
159
160         using PacketData::valid;
161         PacketData & data();
162         
163         ///@}
164
165         ///\name Annotations
166         ///@{
167
168         template <class Annotation>
169         Annotation & annotation();
170
171         ///@}
172
173         ///\name Access to the abstract interface
174         ///@{
175
176         optional_range nextPacketRange();
177         void finalizeThis();
178         void finalizeTo(ptr other);
179         void dump(std::ostream & os);
180         TypeIdValue typeId();
181         factory_t factory();
182         factory_t nextPacketType();
183
184         ///@}
185
186     protected:
187         // protected structors
188
189         PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
190         PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
191
192         ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
193         ptr appendClone(detail::PacketImpl * impl, range r);
194
195     public:
196         // Need this for g++ < 4.0. Since PacketInterpreter is not publicly visible, it should not
197         // be a real problem to make impl() public here
198         using PacketData::impl;
199
200     private:
201         // abstract packet type interface
202
203         virtual optional_range v_nextPacketRange() = 0;
204         virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
205         virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
206         virtual void v_finalize() = 0;
207         virtual void v_dump(std::ostream & os) = 0;
208         virtual TypeIdValue v_type() = 0;
209         virtual factory_t v_factory() = 0;
210         virtual factory_t v_nextPacketType() = 0;
211
212         // reference/memory management. Only to be called by intrusive_refcount_t.
213
214         void add_ref();
215         bool release();
216
217         // containment management. Only to be called by PacketImpl.
218
219         void assignImpl(detail::PacketImpl *);
220         void releaseImpl();
221
222         friend class detail::PacketImpl;
223         friend class intrusive_refcount_base;
224         template <class PacketType> friend class PacketInterpreter;
225         friend class detail::packet::test::TestDriver;
226         friend class PacketParserBase;
227     };
228
229     /** \brief Internal: Concrete packet interpreter
230
231         \internal
232
233         Instantiations of this class build the interpreter chain. This class is accessed by the
234         packet handles. It provides the packet-type specific functionality in addition to the
235         interface defined in the PacketInterpreterBase class.
236
237         \see PacketTypeBase for the \a PacketType interface
238       */
239     template <class PacketType>
240     class PacketInterpreter
241         : public PacketInterpreterBase,
242           public pool_alloc_mixin< PacketInterpreter<PacketType> >
243     {
244     public:
245         ///////////////////////////////////////////////////////////////////////////
246         // Types
247
248         typedef typename senf::detail::packet::smart_pointer<
249             PacketInterpreter>::ptr_t ptr;
250         typedef PacketType type;
251         typedef typename type::parser parser;
252
253         ///////////////////////////////////////////////////////////////////////////
254         ///\name Structors and default members
255         ///@{
256
257         // private constructors
258         // no copy
259         // no conversion constructors
260
261         ~PacketInterpreter();
262
263         static factory_t factory();
264
265         // Create completely new packet
266
267         static ptr create();
268         static ptr create(senf::NoInit_t);
269         static ptr create(size_type size);
270         static ptr create(size_type size, senf::NoInit_t);
271         template <class ForwardReadableRange>
272         static ptr create(ForwardReadableRange const & range);
273
274         // Create packet as new packet after a given packet
275
276         static ptr createAfter(PacketInterpreterBase::ptr packet);
277         static ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t);
278         static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
279         static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, senf::NoInit_t);
280         template <class ForwardReadableRange>
281         static ptr createAfter(PacketInterpreterBase::ptr packet, 
282                                ForwardReadableRange const & range);
283
284         // Create packet as new packet (header) before a given packet
285
286         static ptr createBefore(PacketInterpreterBase::ptr packet);
287         static ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
288
289         // Create a clone of the current packet
290
291         ptr clone();
292
293         ///@}
294         ///////////////////////////////////////////////////////////////////////////
295
296         // Packet field access
297
298         parser fields();
299         parser * fields_p();
300
301         // PacketType access
302
303         static size_type initSize();
304         static size_type initHeadSize();
305
306     protected:
307
308     private:
309         // Private structors
310
311         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
312         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
313
314         static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
315         static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
316
317         // PacketType access
318
319         void init();
320
321         // virtual interface
322
323         virtual optional_range v_nextPacketRange();
324         virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, 
325                                                          iterator base, iterator new_base);
326         virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
327         virtual void v_finalize();
328         virtual void v_dump(std::ostream & os);
329         virtual TypeIdValue v_type();
330         virtual factory_t v_factory();
331         virtual factory_t v_nextPacketType();
332
333         // factory
334
335         /** \brief Internal: Implementation of abstract factory interface
336             
337             \internal
338
339             Implements the abstract factory interface for \a PacketType
340          */
341         struct FactoryImpl : public Factory {
342             // Create completely new packet
343
344             virtual PacketInterpreterBase::ptr create() const;
345             virtual PacketInterpreterBase::ptr create(senf::NoInit_t) const;
346             virtual PacketInterpreterBase::ptr create(size_type size) const;
347             virtual PacketInterpreterBase::ptr create(size_type size,senf::NoInit_t) const;
348             
349             // Create packet as new packet after a given packet
350
351             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet) 
352                 const;
353             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
354                                                            senf::NoInit_t) const;
355             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
356                                                            size_type size) const;
357             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
358                                                            size_type size, senf::NoInit_t) const;
359             
360             // Create packet as new packet (header) before a given packet
361
362             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet) 
363                 const;
364             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
365                                                             senf::NoInit_t) 
366                 const;
367
368             // Parse next packet in chain
369
370             virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet) 
371                 const;
372         };
373
374         static const FactoryImpl factory_;
375
376         parser * parser_p();
377
378         boost::aligned_storage< sizeof(parser), 
379                                 boost::alignment_of<parser>::value > parserStorage_;
380
381         friend class detail::packet::test::TestDriver;
382         friend class PacketInterpreterBase;
383         friend class FactoryImpl;
384     };
385
386     /** \brief Invalid packet chain operation
387
388         This exception signals an invalid operation on the chain like trying to find a non-existent
389         chain member and other similar error conditions. 
390      */
391     struct InvalidPacketChainException : public senf::Exception
392     { InvalidPacketChainException() : senf::Exception("invalid packet chain"){} };
393     
394 }
395
396 ///////////////////////////////hh.e////////////////////////////////////////
397 #endif
398 #if !defined(HH_Packets__decls_) && !defined(HH_PacketInterpreter_i_)
399 #define HH_PacketInterpreter_i_
400 #include "PacketInterpreter.cci"
401 #include "PacketInterpreter.ct"
402 #include "PacketInterpreter.cti"
403 #endif
404
405 \f
406 // Local Variables:
407 // mode: c++
408 // fill-column: 100
409 // c-file-style: "senf"
410 // indent-tabs-mode: nil
411 // ispell-local-dictionary: "american"
412 // compile-command: "scons -u test"
413 // comment-column: 40
414 // End: