Merged revisions 262,264-265,267-282,284-298,300-311 via svnmerge from
[senf.git] / Packets / PacketInterpreter.hh
1 // Copyright (C) 2007 
2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 //     Stefan Bund <g0dil@berlios.de>
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 /** \file
22     \brief PacketInterpreter public header */
23
24 #ifndef HH_PacketInterpreter_
25 #define HH_PacketInterpreter_ 1
26
27 // Custom includes
28 #include <boost/intrusive/ilist.hpp>
29 #include <boost/optional.hpp>
30 #include <boost/range.hpp>
31 #include <boost/type_traits/aligned_storage.hpp>
32 #include <boost/type_traits/alignment_of.hpp>
33 #include "Utils/intrusive_refcount.hh"
34 #include "Utils/pool_alloc_mixin.hh"
35 #include "PacketData.hh"
36 #include "typeidvalue.hh"
37
38 //#include "PacketInterpreter.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
40
41 namespace senf {
42
43     template <class PacketType> class PacketInterpreter;
44
45     /** \brief
46       */
47     class PacketInterpreterBase
48         : protected PacketData, 
49           public detail::packet::interpreter_list_base,
50           public intrusive_refcount_t<PacketInterpreterBase>
51     {
52     public:
53         ///////////////////////////////////////////////////////////////////////////
54         // Types
55
56         typedef senf::detail::packet::smart_pointer<
57             PacketInterpreterBase>::ptr_t ptr;
58
59         typedef senf::detail::packet::iterator iterator;
60         typedef senf::detail::packet::const_iterator const_iterator;
61         typedef senf::detail::packet::size_type size_type;
62         typedef senf::detail::packet::difference_type difference_type;
63         typedef senf::detail::packet::byte byte;
64
65         typedef boost::iterator_range<iterator> range;
66         typedef boost::optional< boost::iterator_range<iterator> > optional_range;
67         typedef optional_range no_range;
68
69         enum Append_t { Append };
70         enum Prepend_t { Prepend };
71         enum NoInit_t { noinit };
72
73         struct Factory { 
74             virtual ~Factory();
75
76             // Create completely new packet
77
78             virtual ptr create() const = 0;
79             virtual ptr create(NoInit_t) const = 0;
80             virtual ptr create(size_type size) const = 0;
81             virtual ptr create(size_type size, NoInit_t) const = 0;
82             template <class ForwardReadableRange>
83             ptr create(ForwardReadableRange const & range) const;
84             
85             // Create packet as new packet after a given packet
86
87             virtual ptr createAfter(PacketInterpreterBase::ptr packet) const = 0;
88             virtual ptr createAfter(PacketInterpreterBase::ptr packet, NoInit_t) const = 0;
89             virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size) const = 0;
90             virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, 
91                                     NoInit_t) const = 0;
92             template <class ForwardReadableRange>
93             ptr createAfter(PacketInterpreterBase::ptr packet, 
94                             ForwardReadableRange const & range) const;
95             
96             // Create packet as new packet (header) const before a given packet
97
98             virtual ptr createBefore(PacketInterpreterBase::ptr packet) const = 0;
99             virtual ptr createBefore(PacketInterpreterBase::ptr packet, NoInit_t) const = 0;
100
101             // Parse next packet in chain
102
103             virtual ptr parseNext(ptr packet) const = 0;
104         };
105
106         typedef Factory const * factory_t;
107
108         ///////////////////////////////////////////////////////////////////////////
109         ///\name Structors and default members
110         ///@{
111
112         // protected constructors
113         // no copy
114         // no conversion constructors
115
116         virtual ~PacketInterpreterBase();
117
118         static                             factory_t no_factory();
119         
120         ptr clone();
121  
122         ///@}
123         ///////////////////////////////////////////////////////////////////////////
124
125         ///\name Interpreter chain access
126         ///@{
127
128         ptr next();
129         ptr prev();
130         ptr first();
131         ptr last();
132
133         template <class Type> typename PacketInterpreter<Type>::ptr parseNextAs();
134                                        ptr                          parseNextAs(factory_t factory);
135         template <class Type>          bool                         is();
136         template <class Type> typename PacketInterpreter<Type>::ptr as();
137
138         ptr append(ptr packet);
139
140         ///@}
141
142         ///\name Data access
143         ///@{
144
145         using PacketData::valid;
146         PacketData & data();
147         
148         ///@}
149
150         ///\name Access to the abstract interface
151         ///@{
152
153         optional_range nextPacketRange();
154         void finalize();
155         void dump(std::ostream & os);
156         TypeIdValue typeId();
157         factory_t factory();
158         factory_t nextPacketType();
159
160         ///@}
161
162     protected:
163         // protected structors
164
165         PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
166         PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
167
168         ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
169         ptr appendClone(detail::PacketImpl * impl, range r);
170
171     private:
172         // abstract packet type interface
173
174         virtual optional_range v_nextPacketRange() = 0;
175         virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
176         virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
177         virtual void v_finalize() = 0;
178         virtual void v_dump(std::ostream & os) = 0;
179         virtual TypeIdValue v_type() = 0;
180         virtual factory_t v_factory() = 0;
181         virtual factory_t v_nextPacketType() = 0;
182
183         // reference/memory management. Only to be called by intrusive_refcount_t.
184
185         void add_ref();
186         bool release();
187
188         // containment management. Only to be called by PacketImpl.
189
190         void assignImpl(detail::PacketImpl *);
191         void releaseImpl();
192
193         friend class detail::PacketImpl;
194         friend class intrusive_refcount_t<PacketInterpreterBase>;
195         template <class PacketType> friend class PacketInterpreter;
196         friend class detail::packet::test::TestDriver;
197     };
198
199     /** \brief Concrete packet interpreter
200
201         \see PacketTypeBase for the \a PacketType interface
202       */
203     template <class PacketType>
204     class PacketInterpreter
205         : public PacketInterpreterBase,
206           public pool_alloc_mixin< PacketInterpreter<PacketType> >
207     {
208     public:
209         ///////////////////////////////////////////////////////////////////////////
210         // Types
211
212         typedef typename senf::detail::packet::smart_pointer<
213             PacketInterpreter>::ptr_t ptr;
214         typedef PacketType type;
215         typedef typename type::parser parser;
216
217         ///////////////////////////////////////////////////////////////////////////
218         ///\name Structors and default members
219         ///@{
220
221         // private constructors
222         // no copy
223         // no conversion constructors
224
225         ~PacketInterpreter();
226
227         static factory_t factory();
228
229         // Create completely new packet
230
231         static ptr create();
232         static ptr create(NoInit_t);
233         static ptr create(size_type size);
234         static ptr create(size_type size, NoInit_t);
235         template <class ForwardReadableRange>
236         static ptr create(ForwardReadableRange const & range);
237
238         // Create packet as new packet after a given packet
239
240         static ptr createAfter(PacketInterpreterBase::ptr packet);
241         static ptr createAfter(PacketInterpreterBase::ptr packet, NoInit_t);
242         static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
243         static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, NoInit_t);
244         template <class ForwardReadableRange>
245         static ptr createAfter(PacketInterpreterBase::ptr packet, 
246                                ForwardReadableRange const & range);
247
248         // Create packet as new packet (header) before a given packet
249
250         static ptr createBefore(PacketInterpreterBase::ptr packet);
251         static ptr createBefore(PacketInterpreterBase::ptr packet, NoInit_t);
252
253         // Create a clone of the current packet
254
255         ptr clone();
256
257         ///@}
258         ///////////////////////////////////////////////////////////////////////////
259
260         // Packet field access
261
262         parser fields();
263         parser * fields_p();
264
265         // PacketType access
266
267         static size_type initSize();
268         static size_type initHeadSize();
269
270     protected:
271
272     private:
273         // Private structors
274
275         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
276         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
277
278         static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
279         static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
280
281         // PacketType access
282
283         void init();
284
285         // virtual interface
286
287         virtual optional_range v_nextPacketRange();
288         virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, 
289                                                          iterator base, iterator new_base);
290         virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
291         virtual void v_finalize();
292         virtual void v_dump(std::ostream & os);
293         virtual TypeIdValue v_type();
294         virtual factory_t v_factory();
295         virtual factory_t v_nextPacketType();
296
297         // factory
298
299         struct FactoryImpl : public Factory {
300             // Create completely new packet
301
302             virtual PacketInterpreterBase::ptr create() const;
303             virtual PacketInterpreterBase::ptr create(NoInit_t) const;
304             virtual PacketInterpreterBase::ptr create(size_type size) const;
305             virtual PacketInterpreterBase::ptr create(size_type size,NoInit_t) const;
306             
307             // Create packet as new packet after a given packet
308
309             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet) 
310                 const;
311             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
312                                                            NoInit_t) const;
313             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
314                                                            size_type size) const;
315             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
316                                                            size_type size, NoInit_t) const;
317             
318             // Create packet as new packet (header) before a given packet
319
320             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet) 
321                 const;
322             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
323                                                             NoInit_t) 
324                 const;
325
326             // Parse next packet in chain
327
328             virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet) 
329                 const;
330         };
331
332         static const FactoryImpl factory_;
333
334         parser * parser_p();
335
336         boost::aligned_storage< sizeof(parser), 
337                                 boost::alignment_of<parser>::value > parserStorage_;
338
339         friend class detail::packet::test::TestDriver;
340         friend class PacketInterpreterBase;
341         friend class FactoryImpl;
342     };
343
344     struct InvalidPacketChainException : public std::exception
345     { virtual char const * what() const throw() { return "invalid packet chain"; } };
346     
347 }
348
349 ///////////////////////////////hh.e////////////////////////////////////////
350 #include "PacketInterpreter.cci"
351 #include "PacketInterpreter.ct"
352 #include "PacketInterpreter.cti"
353 #endif
354
355 \f
356 // Local Variables:
357 // mode: c++
358 // fill-column: 100
359 // c-file-style: "senf"
360 // indent-tabs-mode: nil
361 // ispell-local-dictionary: "american"
362 // End: