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