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< boost::iterator_range<iterator> > 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 packet) const = 0;
106 virtual ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t) const = 0;
107 virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size) const = 0;
108 virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size,
109 senf::NoInit_t) const = 0;
110 template <class ForwardReadableRange>
111 ptr createAfter(PacketInterpreterBase::ptr packet,
112 ForwardReadableRange const & range) const;
114 // Create packet as new packet (header) const before a given packet
116 virtual ptr createBefore(PacketInterpreterBase::ptr packet) const = 0;
117 virtual ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t) const = 0;
119 virtual ptr createInsertBefore(PacketInterpreterBase::ptr packet) const = 0;
120 virtual ptr createInsertBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t) const = 0;
122 // Parse next packet in chain
124 virtual ptr parseNext(ptr packet) 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);
156 template <class Type> bool is();
157 template <class Type> typename PacketInterpreter<Type>::ptr as();
159 ptr append(ptr packet);
168 using PacketData::valid;
176 template <class Annotation>
177 Annotation & annotation();
179 void clearAnnotations();
183 ///\name Access to the abstract interface
186 optional_range nextPacketRange();
188 void finalizeTo(ptr other);
189 void dump(std::ostream & os);
190 TypeIdValue typeId();
192 factory_t nextPacketType();
197 // protected structors
199 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
200 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
201 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, ptr before);
203 ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
204 ptr appendClone(detail::PacketImpl * impl, range r);
207 // Need this for g++ < 4.0. Since PacketInterpreter is not publicly visible, it should not
208 // be a real problem to make impl() public here
209 using PacketData::impl;
212 // abstract packet type interface
214 virtual optional_range v_nextPacketRange() = 0;
215 virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
216 virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
217 virtual void v_finalize() = 0;
218 virtual void v_dump(std::ostream & os) = 0;
219 virtual TypeIdValue v_type() = 0;
220 virtual factory_t v_factory() = 0;
221 virtual factory_t v_nextPacketType() = 0;
223 // reference/memory management. Only to be called by intrusive_refcount_t.
228 // containment management. Only to be called by PacketImpl.
230 void assignImpl(detail::PacketImpl *);
233 friend class detail::PacketImpl;
234 friend class intrusive_refcount_base;
235 template <class PacketType> friend class PacketInterpreter;
236 friend class detail::packet::test::TestDriver;
237 friend class PacketParserBase;
239 friend void senf::intrusive_ptr_add_ref(PacketInterpreterBase const *);
240 friend void senf::intrusive_ptr_release(PacketInterpreterBase const *);
243 void intrusive_ptr_add_ref(PacketInterpreterBase const * p);
244 void intrusive_ptr_release(PacketInterpreterBase const * p);
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 packet);
292 static ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t);
293 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
294 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, senf::NoInit_t);
295 template <class ForwardReadableRange>
296 static ptr createAfter(PacketInterpreterBase::ptr packet,
297 ForwardReadableRange const & range);
299 // Create packet as new packet (header) before a given packet
301 static ptr createBefore(PacketInterpreterBase::ptr packet);
302 static ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
304 static ptr createInsertBefore(PacketInterpreterBase::ptr packet);
305 static ptr createInsertBefore(PacketInterpreterBase::ptr 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 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 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 packet)
376 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
377 senf::NoInit_t) const;
378 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
379 size_type size) const;
380 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr 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 packet)
387 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
391 virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr packet)
393 virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr packet,
397 // Parse next packet in chain
399 virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet)
403 static const FactoryImpl factory_;
405 friend class detail::packet::test::TestDriver;
406 friend class PacketInterpreterBase;
407 friend class 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