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