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