4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
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
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.
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.
19 // The Original Code is Fraunhofer FOKUS code.
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.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief PacketInterpreter public header */
31 #ifndef HH_SENF_Packets_PacketInterpreter_
32 #define HH_SENF_Packets_PacketInterpreter_ 1
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>
44 //#include "PacketInterpreter.mpp"
45 //-/////////////////////////////////////////////////////////////////////////////////////////////////
49 template <class PacketType> class PacketInterpreter;
51 /** \brief Internal: Base packet interpreter class
55 This is the base class for the persistent interpreter. This class encapsulates all the
56 functionality accessible via the packet handle, most handle operations are just forwarded.
58 class PacketInterpreterBase
59 : protected PacketData,
60 public detail::packet::interpreter_list_base,
61 public intrusive_refcount_t<PacketInterpreterBase>
64 //-////////////////////////////////////////////////////////////////////////
67 typedef senf::detail::packet::smart_pointer<
68 PacketInterpreterBase>::ptr_t ptr;
70 typedef senf::detail::packet::iterator iterator;
71 typedef senf::detail::packet::const_iterator const_iterator;
72 typedef senf::detail::packet::size_type size_type;
73 typedef senf::detail::packet::difference_type difference_type;
74 typedef senf::detail::packet::byte byte;
76 typedef boost::iterator_range<iterator> range;
77 typedef boost::optional<range> optional_range;
78 typedef optional_range no_range;
80 enum Append_t { Append };
81 enum Prepend_t { Prepend };
83 /** \brief Internal: Abstract packet factory
87 This abstract class provides an abstract packet factory interface. It allows to call
88 almost any one of the create / createAfter / createBefore static PacketInterpreter
89 without static information on the type of packet to create.
94 // Create completely new packet
96 virtual ptr create() const = 0;
97 virtual ptr create(senf::NoInit_t) const = 0;
98 virtual ptr create(size_type size) const = 0;
99 virtual ptr create(size_type size, senf::NoInit_t) const = 0;
100 template <class ForwardReadableRange>
101 ptr create(ForwardReadableRange const & range) const;
103 // Create packet as new packet after a given packet
105 virtual ptr createAfter(PacketInterpreterBase::ptr const & packet) const = 0;
106 virtual ptr createAfter(PacketInterpreterBase::ptr const & packet, senf::NoInit_t) const = 0;
107 virtual ptr createAfter(PacketInterpreterBase::ptr const & packet, size_type size) const = 0;
108 virtual ptr createAfter(PacketInterpreterBase::ptr const & packet, size_type size,
109 senf::NoInit_t) const = 0;
110 template <class ForwardReadableRange>
111 ptr createAfter(PacketInterpreterBase::ptr const & packet,
112 ForwardReadableRange const & range) const;
114 // Create packet as new packet (header) const before a given packet
116 virtual ptr createBefore(PacketInterpreterBase::ptr const & packet) const = 0;
117 virtual ptr createBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t) const = 0;
119 virtual ptr createInsertBefore(PacketInterpreterBase::ptr const & packet) const = 0;
120 virtual ptr createInsertBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t) const = 0;
122 // Parse next packet in chain
124 virtual ptr parseNext(ptr const & packet, PacketInterpreterBase::optional_range const & range) const = 0;
127 typedef Factory const * factory_t;
129 //-////////////////////////////////////////////////////////////////////////
130 ///\name Structors and default members
133 // protected constructors
135 // no conversion constructors
137 virtual ~PacketInterpreterBase();
139 static factory_t no_factory();
144 //-////////////////////////////////////////////////////////////////////////
146 ///\name Interpreter chain access
154 template <class Type> typename PacketInterpreter<Type>::ptr parseNextAs();
155 ptr parseNextAs(factory_t factory, PacketInterpreterBase::optional_range const & range);
156 template <class Type> typename PacketInterpreter<Type>::ptr as();
158 ptr append(ptr packet);
167 using PacketData::valid;
175 template <class Annotation>
176 Annotation & annotation();
178 void clearAnnotations();
182 ///\name Access to the abstract interface
185 optional_range nextPacketRange();
187 void finalizeTo(ptr other);
188 void dump(std::ostream & os);
189 TypeIdValue typeId();
191 factory_t nextPacketType();
196 // protected structors
198 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
199 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
200 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, ptr before);
202 ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
203 ptr appendClone(detail::PacketImpl * impl, range r);
206 // Need this for g++ < 4.0. Since PacketInterpreter is not publicly visible, it should not
207 // be a real problem to make impl() public here
208 using PacketData::impl;
211 // abstract packet type interface
213 virtual optional_range v_nextPacketRange() = 0;
214 virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
215 virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
216 virtual void v_finalize() = 0;
217 virtual void v_dump(std::ostream & os) = 0;
218 virtual TypeIdValue v_type() = 0;
219 virtual factory_t v_factory() = 0;
220 virtual factory_t v_nextPacketType() = 0;
222 // reference/memory management. Only to be called by intrusive_refcount_t.
227 // containment management. Only to be called by PacketImpl.
229 void assignImpl(detail::PacketImpl *);
232 friend class detail::PacketImpl;
233 friend class intrusive_refcount_base;
234 template <class PacketType> friend class PacketInterpreter;
235 friend class detail::packet::test::TestDriver;
236 friend class PacketParserBase;
238 friend void senf::intrusive_ptr_add_ref(PacketInterpreterBase const *);
239 friend void senf::intrusive_ptr_release(PacketInterpreterBase const *);
242 void intrusive_ptr_add_ref(PacketInterpreterBase const * p);
243 void intrusive_ptr_release(PacketInterpreterBase const * p);
245 /** \brief Internal: Concrete packet interpreter
249 Instantiations of this class build the interpreter chain. This class is accessed by the
250 packet handles. It provides the packet-type specific functionality in addition to the
251 interface defined in the PacketInterpreterBase class.
253 \see PacketTypeBase for the \a PacketType interface
255 template <class PacketType>
256 class PacketInterpreter
257 : public PacketInterpreterBase,
258 public pool_alloc_mixin< PacketInterpreter<PacketType> >
261 //-////////////////////////////////////////////////////////////////////////
264 typedef typename senf::detail::packet::smart_pointer<
265 PacketInterpreter>::ptr_t ptr;
266 typedef PacketType type;
267 typedef typename type::parser parser;
269 //-////////////////////////////////////////////////////////////////////////
270 ///\name Structors and default members
273 // private constructors
275 // no conversion constructors
277 static factory_t factory();
279 // Create completely new packet
282 static ptr create(senf::NoInit_t);
283 static ptr create(size_type size);
284 static ptr create(size_type size, senf::NoInit_t);
285 template <class ForwardReadableRange>
286 static ptr create(ForwardReadableRange const & range);
288 // Create packet as new packet after a given packet
290 static ptr createAfter(PacketInterpreterBase::ptr const & packet);
291 static ptr createAfter(PacketInterpreterBase::ptr const & packet, senf::NoInit_t);
292 static ptr createAfter(PacketInterpreterBase::ptr const & packet, size_type size);
293 static ptr createAfter(PacketInterpreterBase::ptr const & packet, size_type size, senf::NoInit_t);
294 template <class ForwardReadableRange>
295 static ptr createAfter(PacketInterpreterBase::ptr const & packet,
296 ForwardReadableRange const & range);
298 // Create packet as new packet (header) before a given packet
300 static ptr createBefore(PacketInterpreterBase::ptr const & spacket);
301 static ptr createBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t);
303 static ptr createInsertBefore(PacketInterpreterBase::ptr const & packet);
304 static ptr createInsertBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t);
306 // Create a clone of the current packet
311 //-////////////////////////////////////////////////////////////////////////
313 // Packet field access
319 static size_type initSize();
320 static size_type initHeadSize();
327 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
328 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
329 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e,
330 PacketInterpreterBase::ptr const & before);
332 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
333 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
334 static ptr create(detail::PacketImpl * impl, iterator b, iterator e,
335 PacketInterpreterBase::ptr const & before);
343 virtual optional_range v_nextPacketRange();
344 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl,
345 iterator base, iterator new_base);
346 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
347 virtual void v_finalize();
348 virtual void v_dump(std::ostream & os);
349 virtual TypeIdValue v_type();
350 virtual factory_t v_factory();
351 virtual factory_t v_nextPacketType();
355 /** \brief Internal: Implementation of abstract factory interface
359 Implements the abstract factory interface for \a PacketType
361 struct FactoryImpl : public Factory {
364 // Create completely new packet
366 virtual PacketInterpreterBase::ptr create() const;
367 virtual PacketInterpreterBase::ptr create(senf::NoInit_t) const;
368 virtual PacketInterpreterBase::ptr create(size_type size) const;
369 virtual PacketInterpreterBase::ptr create(size_type size,senf::NoInit_t) const;
371 // Create packet as new packet after a given packet
373 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr const & packet)
375 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr const & packet,
376 senf::NoInit_t) const;
377 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr const & packet,
378 size_type size) const;
379 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr const & packet,
380 size_type size, senf::NoInit_t) const;
382 // Create packet as new packet (header) before a given packet
384 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr const & packet)
386 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr const & packet,
390 virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr const & packet)
392 virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr const & packet,
396 // Parse next packet in chain
398 virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr const & packet, PacketInterpreterBase::optional_range const & range)
402 static const FactoryImpl factory_;
404 friend class detail::packet::test::TestDriver;
405 friend class PacketInterpreterBase;
406 friend class FactoryImpl;
409 /** \brief Invalid packet chain operation
411 This exception signals an invalid operation on the chain like trying to find a non-existent
412 chain member and other similar error conditions.
414 struct InvalidPacketChainException : public senf::Exception
415 { InvalidPacketChainException() : senf::Exception("invalid packet chain") {} };
419 //-/////////////////////////////////////////////////////////////////////////////////////////////////
421 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketInterpreter_i_)
422 #define HH_SENF_Packets_PacketInterpreter_i_
423 #include "PacketInterpreter.cci"
424 #include "PacketInterpreter.ct"
425 #include "PacketInterpreter.cti"
432 // c-file-style: "senf"
433 // indent-tabs-mode: nil
434 // ispell-local-dictionary: "american"
435 // compile-command: "scons -u test"
436 // comment-column: 40