2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 // Stefan Bund <g0dil@berlios.de>
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 \brief PacketInterpreter public header */
24 #ifndef HH_PacketInterpreter_
25 #define HH_PacketInterpreter_ 1
28 #include "../boost/intrusive/ilist.hpp"
29 #include <boost/optional.hpp>
30 #include <boost/range.hpp>
31 #include <boost/type_traits/aligned_storage.hpp>
32 #include <boost/type_traits/alignment_of.hpp>
33 #include "../Utils/intrusive_refcount.hh"
34 #include "../Utils/pool_alloc_mixin.hh"
35 #include "PacketData.hh"
36 #include "../Utils/TypeIdValue.hh"
38 //#include "PacketInterpreter.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
43 template <class PacketType> class PacketInterpreter;
45 /** \brief Internal: Base packet interpreter class
49 This is the base class for the persistent interpreter. This class encapsulates all the
50 functionality accessible via the packet handle, most handle operations are just forwarded.
52 class PacketInterpreterBase
53 : protected PacketData,
54 public detail::packet::interpreter_list_base,
55 public intrusive_refcount_t<PacketInterpreterBase>
58 ///////////////////////////////////////////////////////////////////////////
61 typedef senf::detail::packet::smart_pointer<
62 PacketInterpreterBase>::ptr_t ptr;
64 typedef senf::detail::packet::iterator iterator;
65 typedef senf::detail::packet::const_iterator const_iterator;
66 typedef senf::detail::packet::size_type size_type;
67 typedef senf::detail::packet::difference_type difference_type;
68 typedef senf::detail::packet::byte byte;
70 typedef boost::iterator_range<iterator> range;
71 typedef boost::optional< boost::iterator_range<iterator> > optional_range;
72 typedef optional_range no_range;
74 enum Append_t { Append };
75 enum Prepend_t { Prepend };
76 enum NoInit_t { noinit };
78 /** \brief Internal: Abstract packet factory
82 This abstract class provides an abstract packet factory interface. It allows to call
83 almost any one of the create / createAfter / createBefore static PacketInterpreter
84 without static information on the type of packet to create.
89 // Create completely new packet
91 virtual ptr create() const = 0;
92 virtual ptr create(NoInit_t) const = 0;
93 virtual ptr create(size_type size) const = 0;
94 virtual ptr create(size_type size, NoInit_t) const = 0;
95 template <class ForwardReadableRange>
96 ptr create(ForwardReadableRange const & range) const;
98 // Create packet as new packet after a given packet
100 virtual ptr createAfter(PacketInterpreterBase::ptr packet) const = 0;
101 virtual ptr createAfter(PacketInterpreterBase::ptr packet, NoInit_t) const = 0;
102 virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size) const = 0;
103 virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size,
105 template <class ForwardReadableRange>
106 ptr createAfter(PacketInterpreterBase::ptr packet,
107 ForwardReadableRange const & range) const;
109 // Create packet as new packet (header) const before a given packet
111 virtual ptr createBefore(PacketInterpreterBase::ptr packet) const = 0;
112 virtual ptr createBefore(PacketInterpreterBase::ptr packet, NoInit_t) const = 0;
114 // Parse next packet in chain
116 virtual ptr parseNext(ptr packet) const = 0;
119 typedef Factory const * factory_t;
121 ///////////////////////////////////////////////////////////////////////////
122 ///\name Structors and default members
125 // protected constructors
127 // no conversion constructors
129 virtual ~PacketInterpreterBase();
131 static factory_t no_factory();
136 ///////////////////////////////////////////////////////////////////////////
138 ///\name Interpreter chain access
146 template <class Type> typename PacketInterpreter<Type>::ptr parseNextAs();
147 ptr parseNextAs(factory_t factory);
148 template <class Type> bool is();
149 template <class Type> typename PacketInterpreter<Type>::ptr as();
151 ptr append(ptr packet);
158 using PacketData::valid;
163 ///\name Access to the abstract interface
166 optional_range nextPacketRange();
168 void dump(std::ostream & os);
169 TypeIdValue typeId();
171 factory_t nextPacketType();
176 // protected structors
178 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
179 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
181 ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
182 ptr appendClone(detail::PacketImpl * impl, range r);
185 // Need this for g++ < 4.0. Since PacketInterpreter is not publicly visible, it should not
186 // be a real problem to make impl() public here
187 using PacketData::impl;
190 // abstract packet type interface
192 virtual optional_range v_nextPacketRange() = 0;
193 virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
194 virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
195 virtual void v_finalize() = 0;
196 virtual void v_dump(std::ostream & os) = 0;
197 virtual TypeIdValue v_type() = 0;
198 virtual factory_t v_factory() = 0;
199 virtual factory_t v_nextPacketType() = 0;
201 // reference/memory management. Only to be called by intrusive_refcount_t.
206 // containment management. Only to be called by PacketImpl.
208 void assignImpl(detail::PacketImpl *);
211 friend class detail::PacketImpl;
212 friend class intrusive_refcount_t<PacketInterpreterBase>;
213 template <class PacketType> friend class PacketInterpreter;
214 friend class detail::packet::test::TestDriver;
217 /** \brief Internal: Concrete packet interpreter
221 Instantiations of this class build the interpreter chain. This class is accessed by the
222 packet handles. It provides the packet-type specific functionality in addition to the
223 interface defined in the PacketInterpreterBase class.
225 \see PacketTypeBase for the \a PacketType interface
227 template <class PacketType>
228 class PacketInterpreter
229 : public PacketInterpreterBase,
230 public pool_alloc_mixin< PacketInterpreter<PacketType> >
233 ///////////////////////////////////////////////////////////////////////////
236 typedef typename senf::detail::packet::smart_pointer<
237 PacketInterpreter>::ptr_t ptr;
238 typedef PacketType type;
239 typedef typename type::parser parser;
241 ///////////////////////////////////////////////////////////////////////////
242 ///\name Structors and default members
245 // private constructors
247 // no conversion constructors
249 ~PacketInterpreter();
251 static factory_t factory();
253 // Create completely new packet
256 static ptr create(NoInit_t);
257 static ptr create(size_type size);
258 static ptr create(size_type size, NoInit_t);
259 template <class ForwardReadableRange>
260 static ptr create(ForwardReadableRange const & range);
262 // Create packet as new packet after a given packet
264 static ptr createAfter(PacketInterpreterBase::ptr packet);
265 static ptr createAfter(PacketInterpreterBase::ptr packet, NoInit_t);
266 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
267 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, NoInit_t);
268 template <class ForwardReadableRange>
269 static ptr createAfter(PacketInterpreterBase::ptr packet,
270 ForwardReadableRange const & range);
272 // Create packet as new packet (header) before a given packet
274 static ptr createBefore(PacketInterpreterBase::ptr packet);
275 static ptr createBefore(PacketInterpreterBase::ptr packet, NoInit_t);
277 // Create a clone of the current packet
282 ///////////////////////////////////////////////////////////////////////////
284 // Packet field access
291 static size_type initSize();
292 static size_type initHeadSize();
299 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
300 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
302 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
303 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
311 virtual optional_range v_nextPacketRange();
312 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl,
313 iterator base, iterator new_base);
314 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
315 virtual void v_finalize();
316 virtual void v_dump(std::ostream & os);
317 virtual TypeIdValue v_type();
318 virtual factory_t v_factory();
319 virtual factory_t v_nextPacketType();
323 /** \brief Internal: Implementation of abstract factory interface
327 Implements the abstract factory interface for \a PacketType
329 struct FactoryImpl : public Factory {
330 // Create completely new packet
332 virtual PacketInterpreterBase::ptr create() const;
333 virtual PacketInterpreterBase::ptr create(NoInit_t) const;
334 virtual PacketInterpreterBase::ptr create(size_type size) const;
335 virtual PacketInterpreterBase::ptr create(size_type size,NoInit_t) const;
337 // Create packet as new packet after a given packet
339 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet)
341 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
343 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
344 size_type size) const;
345 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
346 size_type size, NoInit_t) const;
348 // Create packet as new packet (header) before a given packet
350 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet)
352 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
356 // Parse next packet in chain
358 virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet)
362 static const FactoryImpl factory_;
366 boost::aligned_storage< sizeof(parser),
367 boost::alignment_of<parser>::value > parserStorage_;
369 friend class detail::packet::test::TestDriver;
370 friend class PacketInterpreterBase;
371 friend class FactoryImpl;
374 /** \brief Invalid packet chain operation
376 This exception signals an invalid operation on the chain like trying to find a non-existent
377 chain member and other similar error conditions.
379 struct InvalidPacketChainException : public std::exception
380 { virtual char const * what() const throw() { return "invalid packet chain"; } };
384 ///////////////////////////////hh.e////////////////////////////////////////
386 #if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketInterpreter_i_)
387 #define HH_PacketInterpreter_i_
388 #include "PacketInterpreter.cci"
389 #include "PacketInterpreter.ct"
390 #include "PacketInterpreter.cti"
397 // c-file-style: "senf"
398 // indent-tabs-mode: nil
399 // ispell-local-dictionary: "american"
400 // compile-command: "scons -u test"
401 // comment-column: 40