Packets: Extend finalize() API
[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 Access to the abstract interface
166         ///@{
167
168         optional_range nextPacketRange();
169         void finalizeThis();
170         void finalizeTo(ptr other);
171         void dump(std::ostream & os);
172         TypeIdValue typeId();
173         factory_t factory();
174         factory_t nextPacketType();
175
176         ///@}
177
178     protected:
179         // protected structors
180
181         PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
182         PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
183
184         ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
185         ptr appendClone(detail::PacketImpl * impl, range r);
186
187     public:
188         // Need this for g++ < 4.0. Since PacketInterpreter is not publicly visible, it should not
189         // be a real problem to make impl() public here
190         using PacketData::impl;
191
192     private:
193         // abstract packet type interface
194
195         virtual optional_range v_nextPacketRange() = 0;
196         virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
197         virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
198         virtual void v_finalize() = 0;
199         virtual void v_dump(std::ostream & os) = 0;
200         virtual TypeIdValue v_type() = 0;
201         virtual factory_t v_factory() = 0;
202         virtual factory_t v_nextPacketType() = 0;
203
204         // reference/memory management. Only to be called by intrusive_refcount_t.
205
206         void add_ref();
207         bool release();
208
209         // containment management. Only to be called by PacketImpl.
210
211         void assignImpl(detail::PacketImpl *);
212         void releaseImpl();
213
214         friend class detail::PacketImpl;
215         friend class intrusive_refcount_base;
216         template <class PacketType> friend class PacketInterpreter;
217         friend class detail::packet::test::TestDriver;
218         friend class PacketParserBase;
219     };
220
221     /** \brief Internal: Concrete packet interpreter
222
223         \internal
224
225         Instantiations of this class build the interpreter chain. This class is accessed by the
226         packet handles. It provides the packet-type specific functionality in addition to the
227         interface defined in the PacketInterpreterBase class.
228
229         \see PacketTypeBase for the \a PacketType interface
230       */
231     template <class PacketType>
232     class PacketInterpreter
233         : public PacketInterpreterBase,
234           public pool_alloc_mixin< PacketInterpreter<PacketType> >
235     {
236     public:
237         ///////////////////////////////////////////////////////////////////////////
238         // Types
239
240         typedef typename senf::detail::packet::smart_pointer<
241             PacketInterpreter>::ptr_t ptr;
242         typedef PacketType type;
243         typedef typename type::parser parser;
244
245         ///////////////////////////////////////////////////////////////////////////
246         ///\name Structors and default members
247         ///@{
248
249         // private constructors
250         // no copy
251         // no conversion constructors
252
253         ~PacketInterpreter();
254
255         static factory_t factory();
256
257         // Create completely new packet
258
259         static ptr create();
260         static ptr create(senf::NoInit_t);
261         static ptr create(size_type size);
262         static ptr create(size_type size, senf::NoInit_t);
263         template <class ForwardReadableRange>
264         static ptr create(ForwardReadableRange const & range);
265
266         // Create packet as new packet after a given packet
267
268         static ptr createAfter(PacketInterpreterBase::ptr packet);
269         static ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t);
270         static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
271         static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, senf::NoInit_t);
272         template <class ForwardReadableRange>
273         static ptr createAfter(PacketInterpreterBase::ptr packet, 
274                                ForwardReadableRange const & range);
275
276         // Create packet as new packet (header) before a given packet
277
278         static ptr createBefore(PacketInterpreterBase::ptr packet);
279         static ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
280
281         // Create a clone of the current packet
282
283         ptr clone();
284
285         ///@}
286         ///////////////////////////////////////////////////////////////////////////
287
288         // Packet field access
289
290         parser fields();
291         parser * fields_p();
292
293         // PacketType access
294
295         static size_type initSize();
296         static size_type initHeadSize();
297
298     protected:
299
300     private:
301         // Private structors
302
303         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
304         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
305
306         static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
307         static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
308
309         // PacketType access
310
311         void init();
312
313         // virtual interface
314
315         virtual optional_range v_nextPacketRange();
316         virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, 
317                                                          iterator base, iterator new_base);
318         virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
319         virtual void v_finalize();
320         virtual void v_dump(std::ostream & os);
321         virtual TypeIdValue v_type();
322         virtual factory_t v_factory();
323         virtual factory_t v_nextPacketType();
324
325         // factory
326
327         /** \brief Internal: Implementation of abstract factory interface
328             
329             \internal
330
331             Implements the abstract factory interface for \a PacketType
332          */
333         struct FactoryImpl : public Factory {
334             // Create completely new packet
335
336             virtual PacketInterpreterBase::ptr create() const;
337             virtual PacketInterpreterBase::ptr create(senf::NoInit_t) const;
338             virtual PacketInterpreterBase::ptr create(size_type size) const;
339             virtual PacketInterpreterBase::ptr create(size_type size,senf::NoInit_t) const;
340             
341             // Create packet as new packet after a given packet
342
343             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet) 
344                 const;
345             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
346                                                            senf::NoInit_t) const;
347             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
348                                                            size_type size) const;
349             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
350                                                            size_type size, senf::NoInit_t) const;
351             
352             // Create packet as new packet (header) before a given packet
353
354             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet) 
355                 const;
356             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
357                                                             senf::NoInit_t) 
358                 const;
359
360             // Parse next packet in chain
361
362             virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet) 
363                 const;
364         };
365
366         static const FactoryImpl factory_;
367
368         parser * parser_p();
369
370         boost::aligned_storage< sizeof(parser), 
371                                 boost::alignment_of<parser>::value > parserStorage_;
372
373         friend class detail::packet::test::TestDriver;
374         friend class PacketInterpreterBase;
375         friend class FactoryImpl;
376     };
377
378     /** \brief Invalid packet chain operation
379
380         This exception signals an invalid operation on the chain like trying to find a non-existent
381         chain member and other similar error conditions. 
382      */
383     struct InvalidPacketChainException : public senf::Exception
384     { InvalidPacketChainException() : senf::Exception("invalid packet chain"){} };
385     
386 }
387
388 ///////////////////////////////hh.e////////////////////////////////////////
389 #endif
390 #if !defined(HH_Packets__decls_) && !defined(HH_PacketInterpreter_i_)
391 #define HH_PacketInterpreter_i_
392 #include "PacketInterpreter.cci"
393 #include "PacketInterpreter.ct"
394 #include "PacketInterpreter.cti"
395 #endif
396
397 \f
398 // Local Variables:
399 // mode: c++
400 // fill-column: 100
401 // c-file-style: "senf"
402 // indent-tabs-mode: nil
403 // ispell-local-dictionary: "american"
404 // compile-command: "scons -u test"
405 // comment-column: 40
406 // End: