Packets: Completely restructured #includes, introduced central Packets.hh file
[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     public:
172         // Need this for g++ < 4.0. Since PacketInterpreter is not publically visible, it should not
173         // be a real problem to make impl() public here
174         using PacketData::impl;
175
176     private:
177         // abstract packet type interface
178
179         virtual optional_range v_nextPacketRange() = 0;
180         virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
181         virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
182         virtual void v_finalize() = 0;
183         virtual void v_dump(std::ostream & os) = 0;
184         virtual TypeIdValue v_type() = 0;
185         virtual factory_t v_factory() = 0;
186         virtual factory_t v_nextPacketType() = 0;
187
188         // reference/memory management. Only to be called by intrusive_refcount_t.
189
190         void add_ref();
191         bool release();
192
193         // containment management. Only to be called by PacketImpl.
194
195         void assignImpl(detail::PacketImpl *);
196         void releaseImpl();
197
198         friend class detail::PacketImpl;
199         friend class intrusive_refcount_t<PacketInterpreterBase>;
200         template <class PacketType> friend class PacketInterpreter;
201         friend class detail::packet::test::TestDriver;
202     };
203
204     /** \brief Concrete packet interpreter
205
206         \see PacketTypeBase for the \a PacketType interface
207       */
208     template <class PacketType>
209     class PacketInterpreter
210         : public PacketInterpreterBase,
211           public pool_alloc_mixin< PacketInterpreter<PacketType> >
212     {
213     public:
214         ///////////////////////////////////////////////////////////////////////////
215         // Types
216
217         typedef typename senf::detail::packet::smart_pointer<
218             PacketInterpreter>::ptr_t ptr;
219         typedef PacketType type;
220         typedef typename type::parser parser;
221
222         ///////////////////////////////////////////////////////////////////////////
223         ///\name Structors and default members
224         ///@{
225
226         // private constructors
227         // no copy
228         // no conversion constructors
229
230         ~PacketInterpreter();
231
232         static factory_t factory();
233
234         // Create completely new packet
235
236         static ptr create();
237         static ptr create(NoInit_t);
238         static ptr create(size_type size);
239         static ptr create(size_type size, NoInit_t);
240         template <class ForwardReadableRange>
241         static ptr create(ForwardReadableRange const & range);
242
243         // Create packet as new packet after a given packet
244
245         static ptr createAfter(PacketInterpreterBase::ptr packet);
246         static ptr createAfter(PacketInterpreterBase::ptr packet, NoInit_t);
247         static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
248         static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, NoInit_t);
249         template <class ForwardReadableRange>
250         static ptr createAfter(PacketInterpreterBase::ptr packet, 
251                                ForwardReadableRange const & range);
252
253         // Create packet as new packet (header) before a given packet
254
255         static ptr createBefore(PacketInterpreterBase::ptr packet);
256         static ptr createBefore(PacketInterpreterBase::ptr packet, NoInit_t);
257
258         // Create a clone of the current packet
259
260         ptr clone();
261
262         ///@}
263         ///////////////////////////////////////////////////////////////////////////
264
265         // Packet field access
266
267         parser fields();
268         parser * fields_p();
269
270         // PacketType access
271
272         static size_type initSize();
273         static size_type initHeadSize();
274
275     protected:
276
277     private:
278         // Private structors
279
280         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
281         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
282
283         static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
284         static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
285
286         // PacketType access
287
288         void init();
289
290         // virtual interface
291
292         virtual optional_range v_nextPacketRange();
293         virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, 
294                                                          iterator base, iterator new_base);
295         virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
296         virtual void v_finalize();
297         virtual void v_dump(std::ostream & os);
298         virtual TypeIdValue v_type();
299         virtual factory_t v_factory();
300         virtual factory_t v_nextPacketType();
301
302         // factory
303
304         struct FactoryImpl : public Factory {
305             // Create completely new packet
306
307             virtual PacketInterpreterBase::ptr create() const;
308             virtual PacketInterpreterBase::ptr create(NoInit_t) const;
309             virtual PacketInterpreterBase::ptr create(size_type size) const;
310             virtual PacketInterpreterBase::ptr create(size_type size,NoInit_t) const;
311             
312             // Create packet as new packet after a given packet
313
314             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet) 
315                 const;
316             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
317                                                            NoInit_t) const;
318             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
319                                                            size_type size) const;
320             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet, 
321                                                            size_type size, NoInit_t) const;
322             
323             // Create packet as new packet (header) before a given packet
324
325             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet) 
326                 const;
327             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
328                                                             NoInit_t) 
329                 const;
330
331             // Parse next packet in chain
332
333             virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet) 
334                 const;
335         };
336
337         static const FactoryImpl factory_;
338
339         parser * parser_p();
340
341         boost::aligned_storage< sizeof(parser), 
342                                 boost::alignment_of<parser>::value > parserStorage_;
343
344         friend class detail::packet::test::TestDriver;
345         friend class PacketInterpreterBase;
346         friend class FactoryImpl;
347     };
348
349     struct InvalidPacketChainException : public std::exception
350     { virtual char const * what() const throw() { return "invalid packet chain"; } };
351     
352 }
353
354 ///////////////////////////////hh.e////////////////////////////////////////
355 #endif
356 #if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketInterpreter_i_)
357 #define HH_PacketInterpreter_i_
358 #include "PacketInterpreter.cci"
359 #include "PacketInterpreter.ct"
360 #include "PacketInterpreter.cti"
361 #endif
362
363 \f
364 // Local Variables:
365 // mode: c++
366 // fill-column: 100
367 // c-file-style: "senf"
368 // indent-tabs-mode: nil
369 // ispell-local-dictionary: "american"
370 // compile-command: "scons -u test"
371 // comment-column: 40
372 // End: