minor fixes for clang++
[senf.git] / senf / Packets / PacketInterpreter.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief PacketInterpreter public header */
30
31 #ifndef HH_SENF_Packets_PacketInterpreter_
32 #define HH_SENF_Packets_PacketInterpreter_ 1
33
34 // Custom includes
35 #include <senf/boost_intrusive/ilist.hpp>
36 #include <boost/optional.hpp>
37 #include <boost/range.hpp>
38 #include <senf/Utils/intrusive_refcount.hh>
39 #include <senf/Utils/pool_alloc_mixin.hh>
40 #include <senf/Utils/Tags.hh>
41 #include "PacketData.hh"
42 #include <senf/Utils/TypeIdValue.hh>
43
44 //#include "PacketInterpreter.mpp"
45 //-/////////////////////////////////////////////////////////////////////////////////////////////////
46
47 namespace senf {
48
49     template <class PacketType> class PacketInterpreter;
50     
51     void intrusive_ptr_add_ref(PacketInterpreterBase const * p);
52     void intrusive_ptr_release(PacketInterpreterBase const * p);
53
54     
55     /** \brief Internal: Base packet interpreter class
56
57         \internal
58
59         This is the base class for the persistent interpreter. This class encapsulates all the
60         functionality accessible via the packet handle, most handle operations are just forwarded.
61       */
62     class PacketInterpreterBase
63         : protected PacketData,
64           public detail::packet::interpreter_list_base,
65           public intrusive_refcount_t<PacketInterpreterBase>
66     {
67     public:
68         //-////////////////////////////////////////////////////////////////////////
69         // Types
70
71         typedef senf::detail::packet::smart_pointer<
72             PacketInterpreterBase>::ptr_t ptr;
73
74         typedef senf::detail::packet::iterator iterator;
75         typedef senf::detail::packet::const_iterator const_iterator;
76         typedef senf::detail::packet::size_type size_type;
77         typedef senf::detail::packet::difference_type difference_type;
78         typedef senf::detail::packet::byte byte;
79
80         typedef boost::iterator_range<iterator> range;
81         typedef boost::optional<range> optional_range;
82         typedef optional_range no_range;
83
84         enum Append_t { Append };
85         enum Prepend_t { Prepend };
86
87         /** \brief Internal: Abstract packet factory
88
89             \internal
90
91             This abstract class provides an abstract packet factory interface. It allows to call
92             almost any one of the create / createAfter / createBefore static PacketInterpreter
93             without static information on the type of packet to create.
94          */
95         struct Factory {
96             virtual ~Factory();
97
98             // Create completely new packet
99
100             virtual ptr create() const = 0;
101             virtual ptr create(senf::NoInit_t) const = 0;
102             virtual ptr create(size_type size) const = 0;
103             virtual ptr create(size_type size, senf::NoInit_t) const = 0;
104             template <class ForwardReadableRange>
105             ptr create(ForwardReadableRange const & range) const;
106
107             // Create packet as new packet after a given packet
108
109             virtual ptr createAfter(PacketInterpreterBase::ptr const & packet) const = 0;
110             virtual ptr createAfter(PacketInterpreterBase::ptr const & packet, senf::NoInit_t) const = 0;
111             virtual ptr createAfter(PacketInterpreterBase::ptr const & packet, size_type size) const = 0;
112             virtual ptr createAfter(PacketInterpreterBase::ptr const & packet, size_type size,
113                                     senf::NoInit_t) const = 0;
114             template <class ForwardReadableRange>
115             ptr createAfter(PacketInterpreterBase::ptr const & packet,
116                             ForwardReadableRange const & range) const;
117
118             // Create packet as new packet (header) const before a given packet
119
120             virtual ptr createBefore(PacketInterpreterBase::ptr const & packet) const = 0;
121             virtual ptr createBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t) const = 0;
122
123             virtual ptr createInsertBefore(PacketInterpreterBase::ptr const & packet) const = 0;
124             virtual ptr createInsertBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t) const = 0;
125
126             // Parse next packet in chain
127
128             virtual ptr parseNext(ptr const & packet, PacketInterpreterBase::optional_range const & range) const = 0;
129         };
130
131         typedef Factory const * factory_t;
132
133         //-////////////////////////////////////////////////////////////////////////
134         ///\name Structors and default members
135         //\{
136
137         // protected constructors
138         // no copy
139         // no conversion constructors
140
141         virtual ~PacketInterpreterBase();
142
143         static factory_t no_factory();
144
145         ptr clone();
146
147         //\}
148         //-////////////////////////////////////////////////////////////////////////
149
150         ///\name Interpreter chain access
151         //\{
152
153         ptr next();
154         ptr prev();
155         ptr first();
156         ptr last();
157
158         template <class Type> typename PacketInterpreter<Type>::ptr parseNextAs();
159                                        ptr                          parseNextAs(factory_t factory, PacketInterpreterBase::optional_range const & range);
160         template <class Type> typename PacketInterpreter<Type>::ptr as();
161
162         ptr append(ptr packet);
163
164         void reparse();
165
166         //\}
167
168         ///\name Data access
169         //\{
170
171         using PacketData::valid;
172         PacketData & data();
173
174         //\}
175
176         ///\name Annotations
177         //\{
178
179         template <class Annotation>
180         Annotation & annotation();
181
182         void clearAnnotations();
183
184         //\}
185
186         ///\name Access to the abstract interface
187         //\{
188
189         optional_range nextPacketRange();
190         void finalizeThis();
191         void finalizeTo(ptr other);
192         void dump(std::ostream & os);
193         TypeIdValue typeId();
194         factory_t factory();
195         factory_t nextPacketType();
196
197         //\}
198
199     protected:
200         // protected structors
201
202         PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
203         PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
204         PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, ptr before);
205
206         ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
207         ptr appendClone(detail::PacketImpl * impl, range r);
208
209     public:
210         // Need this for g++ < 4.0. Since PacketInterpreter is not publicly visible, it should not
211         // be a real problem to make impl() public here
212         using PacketData::impl;
213
214     private:
215         // abstract packet type interface
216
217         virtual optional_range v_nextPacketRange() = 0;
218         virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
219         virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
220         virtual void v_finalize() = 0;
221         virtual void v_dump(std::ostream & os) = 0;
222         virtual TypeIdValue v_type() = 0;
223         virtual factory_t v_factory() = 0;
224         virtual factory_t v_nextPacketType() = 0;
225
226         // reference/memory management. Only to be called by intrusive_refcount_t.
227
228         void add_ref();
229         void release();
230
231         // containment management. Only to be called by PacketImpl.
232
233         void assignImpl(detail::PacketImpl *);
234         void releaseImpl();
235
236         friend class detail::PacketImpl;
237         friend class intrusive_refcount_base;
238         template <class PacketType> friend class PacketInterpreter;
239         friend struct detail::packet::test::TestDriver;
240         friend class PacketParserBase;
241
242         friend void senf::intrusive_ptr_add_ref(PacketInterpreterBase const *);
243         friend void senf::intrusive_ptr_release(PacketInterpreterBase const *);
244     };
245
246     /** \brief Internal: Concrete packet interpreter
247
248         \internal
249
250         Instantiations of this class build the interpreter chain. This class is accessed by the
251         packet handles. It provides the packet-type specific functionality in addition to the
252         interface defined in the PacketInterpreterBase class.
253
254         \see PacketTypeBase for the \a PacketType interface
255       */
256     template <class PacketType>
257     class PacketInterpreter
258         : public PacketInterpreterBase,
259           public pool_alloc_mixin< PacketInterpreter<PacketType> >
260     {
261     public:
262         //-////////////////////////////////////////////////////////////////////////
263         // Types
264
265         typedef typename senf::detail::packet::smart_pointer<
266             PacketInterpreter>::ptr_t ptr;
267         typedef PacketType type;
268         typedef typename type::parser parser;
269
270         //-////////////////////////////////////////////////////////////////////////
271         ///\name Structors and default members
272         //\{
273
274         // private constructors
275         // no copy
276         // no conversion constructors
277
278         static factory_t factory();
279
280         // Create completely new packet
281
282         static ptr create();
283         static ptr create(senf::NoInit_t);
284         static ptr create(size_type size);
285         static ptr create(size_type size, senf::NoInit_t);
286         template <class ForwardReadableRange>
287         static ptr create(ForwardReadableRange const & range);
288
289         // Create packet as new packet after a given packet
290
291         static ptr createAfter(PacketInterpreterBase::ptr const & packet);
292         static ptr createAfter(PacketInterpreterBase::ptr const & packet, senf::NoInit_t);
293         static ptr createAfter(PacketInterpreterBase::ptr const & packet, size_type size);
294         static ptr createAfter(PacketInterpreterBase::ptr const & packet, size_type size, senf::NoInit_t);
295         template <class ForwardReadableRange>
296         static ptr createAfter(PacketInterpreterBase::ptr const & packet,
297                                ForwardReadableRange const & range);
298
299         // Create packet as new packet (header) before a given packet
300
301         static ptr createBefore(PacketInterpreterBase::ptr const & spacket);
302         static ptr createBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t);
303
304         static ptr createInsertBefore(PacketInterpreterBase::ptr const & packet);
305         static ptr createInsertBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t);
306
307         // Create a clone of the current packet
308
309         ptr clone();
310
311         //\}
312         //-////////////////////////////////////////////////////////////////////////
313
314         // Packet field access
315
316         parser fields();
317
318         // PacketType access
319
320         static size_type initSize();
321         static size_type initHeadSize();
322
323     protected:
324
325     private:
326         // Private structors
327
328         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
329         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
330         PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e,
331                           PacketInterpreterBase::ptr const & before);
332
333         static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
334         static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
335         static ptr create(detail::PacketImpl * impl, iterator b, iterator e,
336                           PacketInterpreterBase::ptr const & before);
337
338         // PacketType access
339
340         void init();
341
342         // virtual interface
343
344         virtual optional_range v_nextPacketRange();
345         virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl,
346                                                          iterator base, iterator new_base);
347         virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
348         virtual void v_finalize();
349         virtual void v_dump(std::ostream & os);
350         virtual TypeIdValue v_type();
351         virtual factory_t v_factory();
352         virtual factory_t v_nextPacketType();
353
354         // factory
355
356         /** \brief Internal: Implementation of abstract factory interface
357
358             \internal
359
360             Implements the abstract factory interface for \a PacketType
361          */
362         struct FactoryImpl : public Factory {
363             FactoryImpl() {}
364
365             // Create completely new packet
366
367             virtual PacketInterpreterBase::ptr create() const;
368             virtual PacketInterpreterBase::ptr create(senf::NoInit_t) const;
369             virtual PacketInterpreterBase::ptr create(size_type size) const;
370             virtual PacketInterpreterBase::ptr create(size_type size,senf::NoInit_t) const;
371
372             // Create packet as new packet after a given packet
373
374             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr const & packet)
375                 const;
376             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr const & packet,
377                                                            senf::NoInit_t) const;
378             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr const & packet,
379                                                            size_type size) const;
380             virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr const & packet,
381                                                            size_type size, senf::NoInit_t) const;
382
383             // Create packet as new packet (header) before a given packet
384
385             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr const & packet)
386                 const;
387             virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr const & packet,
388                                                             senf::NoInit_t)
389                 const;
390
391             virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr const & packet)
392                 const;
393             virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr const & packet,
394                                                                   senf::NoInit_t)
395                 const;
396
397             // Parse next packet in chain
398
399             virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr const & packet, PacketInterpreterBase::optional_range const & range)
400                 const;
401         };
402
403         static const FactoryImpl factory_;
404
405         friend struct detail::packet::test::TestDriver;
406         friend class PacketInterpreterBase;
407         friend struct FactoryImpl;
408     };
409
410     /** \brief Invalid packet chain operation
411
412         This exception signals an invalid operation on the chain like trying to find a non-existent
413         chain member and other similar error conditions.
414      */
415     struct InvalidPacketChainException : public senf::Exception
416     { InvalidPacketChainException() : senf::Exception("invalid packet chain") {} };
417
418 }
419
420 //-/////////////////////////////////////////////////////////////////////////////////////////////////
421 #endif
422 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketInterpreter_i_)
423 #define HH_SENF_Packets_PacketInterpreter_i_
424 #include "PacketInterpreter.cci"
425 #include "PacketInterpreter.ct"
426 #include "PacketInterpreter.cti"
427 #endif
428
429 \f
430 // Local Variables:
431 // mode: c++
432 // fill-column: 100
433 // c-file-style: "senf"
434 // indent-tabs-mode: nil
435 // ispell-local-dictionary: "american"
436 // compile-command: "scons -u test"
437 // comment-column: 40
438 // End: