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