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 void intrusive_ptr_add_ref(PacketInterpreterBase const * p);
52 void intrusive_ptr_release(PacketInterpreterBase const * p);
55 /** \brief Internal: Base packet interpreter class
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.
62 class PacketInterpreterBase
63 : protected PacketData,
64 public detail::packet::interpreter_list_base,
65 public intrusive_refcount_t<PacketInterpreterBase>
68 //-////////////////////////////////////////////////////////////////////////
71 typedef senf::detail::packet::smart_pointer<
72 PacketInterpreterBase>::ptr_t ptr;
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;
80 typedef boost::iterator_range<iterator> range;
81 typedef boost::optional<range> optional_range;
82 typedef optional_range no_range;
84 enum Append_t { Append };
85 enum Prepend_t { Prepend };
87 /** \brief Internal: Abstract packet factory
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.
98 // Create completely new packet
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;
107 // Create packet as new packet after a given packet
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;
118 // Create packet as new packet (header) const before a given packet
120 virtual ptr createBefore(PacketInterpreterBase::ptr const & packet) const = 0;
121 virtual ptr createBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t) const = 0;
123 virtual ptr createInsertBefore(PacketInterpreterBase::ptr const & packet) const = 0;
124 virtual ptr createInsertBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t) const = 0;
126 // Parse next packet in chain
128 virtual ptr parseNext(ptr const & packet, PacketInterpreterBase::optional_range const & range) const = 0;
131 typedef Factory const * factory_t;
133 //-////////////////////////////////////////////////////////////////////////
134 ///\name Structors and default members
137 // protected constructors
139 // no conversion constructors
141 virtual ~PacketInterpreterBase();
143 static factory_t no_factory();
148 //-////////////////////////////////////////////////////////////////////////
150 ///\name Interpreter chain access
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();
162 ptr append(ptr packet);
171 using PacketData::valid;
179 template <class Annotation>
180 Annotation & annotation();
182 void clearAnnotations();
186 ///\name Access to the abstract interface
189 optional_range nextPacketRange();
191 void finalizeTo(ptr other);
192 void dump(std::ostream & os);
193 TypeIdValue typeId();
195 factory_t nextPacketType();
200 // protected structors
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);
206 ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
207 ptr appendClone(detail::PacketImpl * impl, range r);
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;
215 // abstract packet type interface
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;
226 // reference/memory management. Only to be called by intrusive_refcount_t.
231 // containment management. Only to be called by PacketImpl.
233 void assignImpl(detail::PacketImpl *);
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;
242 friend void senf::intrusive_ptr_add_ref(PacketInterpreterBase const *);
243 friend void senf::intrusive_ptr_release(PacketInterpreterBase const *);
246 /** \brief Internal: Concrete packet interpreter
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.
254 \see PacketTypeBase for the \a PacketType interface
256 template <class PacketType>
257 class PacketInterpreter
258 : public PacketInterpreterBase,
259 public pool_alloc_mixin< PacketInterpreter<PacketType> >
262 //-////////////////////////////////////////////////////////////////////////
265 typedef typename senf::detail::packet::smart_pointer<
266 PacketInterpreter>::ptr_t ptr;
267 typedef PacketType type;
268 typedef typename type::parser parser;
270 //-////////////////////////////////////////////////////////////////////////
271 ///\name Structors and default members
274 // private constructors
276 // no conversion constructors
278 static factory_t factory();
280 // Create completely new packet
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);
289 // Create packet as new packet after a given packet
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);
299 // Create packet as new packet (header) before a given packet
301 static ptr createBefore(PacketInterpreterBase::ptr const & spacket);
302 static ptr createBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t);
304 static ptr createInsertBefore(PacketInterpreterBase::ptr const & packet);
305 static ptr createInsertBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t);
307 // Create a clone of the current packet
312 //-////////////////////////////////////////////////////////////////////////
314 // Packet field access
320 static size_type initSize();
321 static size_type initHeadSize();
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);
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);
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();
356 /** \brief Internal: Implementation of abstract factory interface
360 Implements the abstract factory interface for \a PacketType
362 struct FactoryImpl : public Factory {
365 // Create completely new packet
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;
372 // Create packet as new packet after a given packet
374 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr const & packet)
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;
383 // Create packet as new packet (header) before a given packet
385 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr const & packet)
387 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr const & packet,
391 virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr const & packet)
393 virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr const & packet,
397 // Parse next packet in chain
399 virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr const & packet, PacketInterpreterBase::optional_range const & range)
403 static const FactoryImpl factory_;
405 friend struct detail::packet::test::TestDriver;
406 friend class PacketInterpreterBase;
407 friend struct FactoryImpl;
410 /** \brief Invalid packet chain operation
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.
415 struct InvalidPacketChainException : public senf::Exception
416 { InvalidPacketChainException() : senf::Exception("invalid packet chain") {} };
420 //-/////////////////////////////////////////////////////////////////////////////////////////////////
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"
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