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