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