4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief PacketInterpreter public header */
26 #ifndef HH_SENF_Packets_PacketInterpreter_
27 #define HH_SENF_Packets_PacketInterpreter_ 1
30 #include "../boost/intrusive/ilist.hpp"
31 #include <boost/optional.hpp>
32 #include <boost/range.hpp>
33 #include <boost/type_traits/aligned_storage.hpp>
34 #include <boost/type_traits/alignment_of.hpp>
35 #include "../Utils/intrusive_refcount.hh"
36 #include "../Utils/pool_alloc_mixin.hh"
37 #include "../Utils/Tags.hh"
38 #include "PacketData.hh"
39 #include "../Utils/TypeIdValue.hh"
41 //#include "PacketInterpreter.mpp"
42 ///////////////////////////////hh.p////////////////////////////////////////
46 template <class PacketType> class PacketInterpreter;
48 /** \brief Internal: Base packet interpreter class
52 This is the base class for the persistent interpreter. This class encapsulates all the
53 functionality accessible via the packet handle, most handle operations are just forwarded.
55 class PacketInterpreterBase
56 : protected PacketData,
57 public detail::packet::interpreter_list_base,
58 public intrusive_refcount_t<PacketInterpreterBase>
61 ///////////////////////////////////////////////////////////////////////////
64 typedef senf::detail::packet::smart_pointer<
65 PacketInterpreterBase>::ptr_t ptr;
67 typedef senf::detail::packet::iterator iterator;
68 typedef senf::detail::packet::const_iterator const_iterator;
69 typedef senf::detail::packet::size_type size_type;
70 typedef senf::detail::packet::difference_type difference_type;
71 typedef senf::detail::packet::byte byte;
73 typedef boost::iterator_range<iterator> range;
74 typedef boost::optional< boost::iterator_range<iterator> > optional_range;
75 typedef optional_range no_range;
77 enum Append_t { Append };
78 enum Prepend_t { Prepend };
80 /** \brief Internal: Abstract packet factory
84 This abstract class provides an abstract packet factory interface. It allows to call
85 almost any one of the create / createAfter / createBefore static PacketInterpreter
86 without static information on the type of packet to create.
91 // Create completely new packet
93 virtual ptr create() const = 0;
94 virtual ptr create(senf::NoInit_t) const = 0;
95 virtual ptr create(size_type size) const = 0;
96 virtual ptr create(size_type size, senf::NoInit_t) const = 0;
97 template <class ForwardReadableRange>
98 ptr create(ForwardReadableRange const & range) const;
100 // Create packet as new packet after a given packet
102 virtual ptr createAfter(PacketInterpreterBase::ptr packet) const = 0;
103 virtual ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t) const = 0;
104 virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size) const = 0;
105 virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size,
106 senf::NoInit_t) const = 0;
107 template <class ForwardReadableRange>
108 ptr createAfter(PacketInterpreterBase::ptr packet,
109 ForwardReadableRange const & range) const;
111 // Create packet as new packet (header) const before a given packet
113 virtual ptr createBefore(PacketInterpreterBase::ptr packet) const = 0;
114 virtual ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t) const = 0;
116 // Parse next packet in chain
118 virtual ptr parseNext(ptr packet) const = 0;
121 typedef Factory const * factory_t;
123 ///////////////////////////////////////////////////////////////////////////
124 ///\name Structors and default members
127 // protected constructors
129 // no conversion constructors
131 virtual ~PacketInterpreterBase();
133 static factory_t no_factory();
138 ///////////////////////////////////////////////////////////////////////////
140 ///\name Interpreter chain access
148 template <class Type> typename PacketInterpreter<Type>::ptr parseNextAs();
149 ptr parseNextAs(factory_t factory);
150 template <class Type> bool is();
151 template <class Type> typename PacketInterpreter<Type>::ptr as();
153 ptr append(ptr packet);
160 using PacketData::valid;
168 template <class Annotation>
169 Annotation & annotation();
173 ///\name Access to the abstract interface
176 optional_range nextPacketRange();
178 void finalizeTo(ptr other);
179 void dump(std::ostream & os);
180 TypeIdValue typeId();
182 factory_t nextPacketType();
187 // protected structors
189 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
190 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
192 ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
193 ptr appendClone(detail::PacketImpl * impl, range r);
196 // Need this for g++ < 4.0. Since PacketInterpreter is not publicly visible, it should not
197 // be a real problem to make impl() public here
198 using PacketData::impl;
201 // abstract packet type interface
203 virtual optional_range v_nextPacketRange() = 0;
204 virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
205 virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
206 virtual void v_finalize() = 0;
207 virtual void v_dump(std::ostream & os) = 0;
208 virtual TypeIdValue v_type() = 0;
209 virtual factory_t v_factory() = 0;
210 virtual factory_t v_nextPacketType() = 0;
212 // reference/memory management. Only to be called by intrusive_refcount_t.
217 // containment management. Only to be called by PacketImpl.
219 void assignImpl(detail::PacketImpl *);
222 friend class detail::PacketImpl;
223 friend class intrusive_refcount_base;
224 template <class PacketType> friend class PacketInterpreter;
225 friend class detail::packet::test::TestDriver;
226 friend class PacketParserBase;
229 /** \brief Internal: Concrete packet interpreter
233 Instantiations of this class build the interpreter chain. This class is accessed by the
234 packet handles. It provides the packet-type specific functionality in addition to the
235 interface defined in the PacketInterpreterBase class.
237 \see PacketTypeBase for the \a PacketType interface
239 template <class PacketType>
240 class PacketInterpreter
241 : public PacketInterpreterBase,
242 public pool_alloc_mixin< PacketInterpreter<PacketType> >
245 ///////////////////////////////////////////////////////////////////////////
248 typedef typename senf::detail::packet::smart_pointer<
249 PacketInterpreter>::ptr_t ptr;
250 typedef PacketType type;
251 typedef typename type::parser parser;
253 ///////////////////////////////////////////////////////////////////////////
254 ///\name Structors and default members
257 // private constructors
259 // no conversion constructors
261 ~PacketInterpreter();
263 static factory_t factory();
265 // Create completely new packet
268 static ptr create(senf::NoInit_t);
269 static ptr create(size_type size);
270 static ptr create(size_type size, senf::NoInit_t);
271 template <class ForwardReadableRange>
272 static ptr create(ForwardReadableRange const & range);
274 // Create packet as new packet after a given packet
276 static ptr createAfter(PacketInterpreterBase::ptr packet);
277 static ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t);
278 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
279 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, senf::NoInit_t);
280 template <class ForwardReadableRange>
281 static ptr createAfter(PacketInterpreterBase::ptr packet,
282 ForwardReadableRange const & range);
284 // Create packet as new packet (header) before a given packet
286 static ptr createBefore(PacketInterpreterBase::ptr packet);
287 static ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
289 // Create a clone of the current packet
294 ///////////////////////////////////////////////////////////////////////////
296 // Packet field access
303 static size_type initSize();
304 static size_type initHeadSize();
311 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
312 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
314 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
315 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
323 virtual optional_range v_nextPacketRange();
324 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl,
325 iterator base, iterator new_base);
326 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
327 virtual void v_finalize();
328 virtual void v_dump(std::ostream & os);
329 virtual TypeIdValue v_type();
330 virtual factory_t v_factory();
331 virtual factory_t v_nextPacketType();
335 /** \brief Internal: Implementation of abstract factory interface
339 Implements the abstract factory interface for \a PacketType
341 struct FactoryImpl : public Factory {
342 // Create completely new packet
344 virtual PacketInterpreterBase::ptr create() const;
345 virtual PacketInterpreterBase::ptr create(senf::NoInit_t) const;
346 virtual PacketInterpreterBase::ptr create(size_type size) const;
347 virtual PacketInterpreterBase::ptr create(size_type size,senf::NoInit_t) const;
349 // Create packet as new packet after a given packet
351 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet)
353 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
354 senf::NoInit_t) const;
355 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
356 size_type size) const;
357 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
358 size_type size, senf::NoInit_t) const;
360 // Create packet as new packet (header) before a given packet
362 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet)
364 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
368 // Parse next packet in chain
370 virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet)
374 static const FactoryImpl factory_;
378 boost::aligned_storage< sizeof(parser),
379 boost::alignment_of<parser>::value > parserStorage_;
381 friend class detail::packet::test::TestDriver;
382 friend class PacketInterpreterBase;
383 friend class FactoryImpl;
386 /** \brief Invalid packet chain operation
388 This exception signals an invalid operation on the chain like trying to find a non-existent
389 chain member and other similar error conditions.
391 struct InvalidPacketChainException : public senf::Exception
392 { InvalidPacketChainException() : senf::Exception("invalid packet chain"){} };
396 ///////////////////////////////hh.e////////////////////////////////////////
398 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketInterpreter_i_)
399 #define HH_SENF_Packets_PacketInterpreter_i_
400 #include "PacketInterpreter.cci"
401 #include "PacketInterpreter.ct"
402 #include "PacketInterpreter.cti"
409 // c-file-style: "senf"
410 // indent-tabs-mode: nil
411 // ispell-local-dictionary: "american"
412 // compile-command: "scons -u test"
413 // comment-column: 40