fa9ed46a50a86c81c76dfa1fdf15f0ec128fee9c
[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         void 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         friend void senf::intrusive_ptr_add_ref(PacketInterpreterBase const *);
231         friend void senf::intrusive_ptr_release(PacketInterpreterBase const *);
232     };
233
234     void intrusive_ptr_add_ref(PacketInterpreterBase const * p);
235     void intrusive_ptr_release(PacketInterpreterBase const * p);
236
237     /** \brief Internal: Concrete packet interpreter
238
239         \internal
240
241         Instantiations of this class build the interpreter chain. This class is accessed by the
242         packet handles. It provides the packet-type specific functionality in addition to the
243         interface defined in the PacketInterpreterBase class.
244
245         \see PacketTypeBase for the \a PacketType interface
246       */
247     template <class PacketType>
248     class PacketInterpreter
249         : public PacketInterpreterBase,
250           public pool_alloc_mixin< PacketInterpreter<PacketType> >
251     {
252     public:
253         ///////////////////////////////////////////////////////////////////////////
254         // Types
255
256         typedef typename senf::detail::packet::smart_pointer<
257             PacketInterpreter>::ptr_t ptr;
258         typedef PacketType type;
259         typedef typename type::parser parser;
260
261         ///////////////////////////////////////////////////////////////////////////
262         ///\name Structors and default members
263         ///@{
264
265         // private constructors
266         // no copy
267         // no conversion constructors
268
269         static factory_t factory();
270
271         // Create completely new packet
272
273         static ptr create();
274         static ptr create(senf::NoInit_t);
275         static ptr create(size_type size);
276         static ptr create(size_type size, senf::NoInit_t);
277         template <class ForwardReadableRange>
278         static ptr create(ForwardReadableRange const & range);
279
280         // Create packet as new packet after a given packet
281
282         static ptr createAfter(PacketInterpreterBase::ptr packet);
283         static ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t);
284         static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
285         static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, senf::NoInit_t);
286         template <class ForwardReadableRange>
287         static ptr createAfter(PacketInterpreterBase::ptr packet,
288                                ForwardReadableRange const & range);
289
290         // Create packet as new packet (header) before a given packet
291
292         static ptr createBefore(PacketInterpreterBase::ptr packet);
293         static ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
294
295         static ptr createInsertBefore(PacketInterpreterBase::ptr packet);
296         static ptr createInsertBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
297
298         // Create a clone of the current packet
299
300         ptr clone();
301
302         ///@}
303         ///////////////////////////////////////////////////////////////////////////
304
305         // Packet field access
306
307         parser fields();
308
309         // PacketType access
310
311         static size_type initSize();
312         static size_type initHeadSize();
313
314     protected:
315
316     private:
317         // Private structors
318
319         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
320         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
321         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e,
322                           PacketInterpreterBase::ptr before);
323
324         static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
325         static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
326         static ptr create(detail::PacketImpl * impl, iterator b, iterator e,
327                           PacketInterpreterBase::ptr before);
328
329         // PacketType access
330
331         void init();
332
333         // virtual interface
334
335         virtual optional_range v_nextPacketRange();
336         virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl,
337                                                          iterator base, iterator new_base);
338         virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
339         virtual void v_finalize();
340         virtual void v_dump(std::ostream & os);
341         virtual TypeIdValue v_type();
342         virtual factory_t v_factory();
343         virtual factory_t v_nextPacketType();
344
345         // factory
346
347         /** \brief Internal: Implementation of abstract factory interface
348
349             \internal
350
351             Implements the abstract factory interface for \a PacketType
352          */
353         struct FactoryImpl : public Factory {
354             // Create completely new packet
355
356             virtual PacketInterpreterBase::ptr create() const;
357             virtual PacketInterpreterBase::ptr create(senf::NoInit_t) const;
358             virtual PacketInterpreterBase::ptr create(size_type size) const;
359             virtual PacketInterpreterBase::ptr create(size_type size,senf::NoInit_t) const;
360
361             // Create packet as new packet after a given packet
362
363             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet)
364                 const;
365             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
366                                                            senf::NoInit_t) const;
367             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
368                                                            size_type size) const;
369             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
370                                                            size_type size, senf::NoInit_t) const;
371
372             // Create packet as new packet (header) before a given packet
373
374             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet)
375                 const;
376             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
377                                                             senf::NoInit_t)
378                 const;
379
380             virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr packet)
381                 const;
382             virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr packet,
383                                                                   senf::NoInit_t)
384                 const;
385
386             // Parse next packet in chain
387
388             virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet)
389                 const;
390         };
391
392         static const FactoryImpl factory_;
393
394         friend class detail::packet::test::TestDriver;
395         friend class PacketInterpreterBase;
396         friend class FactoryImpl;
397     };
398
399     /** \brief Invalid packet chain operation
400
401         This exception signals an invalid operation on the chain like trying to find a non-existent
402         chain member and other similar error conditions.
403      */
404     struct InvalidPacketChainException : public senf::Exception
405     { InvalidPacketChainException() : senf::Exception("invalid packet chain") {} };
406
407 }
408
409 ///////////////////////////////hh.e////////////////////////////////////////
410 #endif
411 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketInterpreter_i_)
412 #define HH_SENF_Packets_PacketInterpreter_i_
413 #include "PacketInterpreter.cci"
414 #include "PacketInterpreter.ct"
415 #include "PacketInterpreter.cti"
416 #endif
417
418 \f
419 // Local Variables:
420 // mode: c++
421 // fill-column: 100
422 // c-file-style: "senf"
423 // indent-tabs-mode: nil
424 // ispell-local-dictionary: "american"
425 // compile-command: "scons -u test"
426 // comment-column: 40
427 // End: