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 <senf/boost_intrusive/ilist.hpp>
31 #include <boost/optional.hpp>
32 #include <boost/range.hpp>
33 #include <senf/Utils/intrusive_refcount.hh>
34 #include <senf/Utils/pool_alloc_mixin.hh>
35 #include <senf/Utils/Tags.hh>
36 #include "PacketData.hh"
37 #include <senf/Utils/TypeIdValue.hh>
39 //#include "PacketInterpreter.mpp"
40 ///////////////////////////////hh.p////////////////////////////////////////
44 template <class PacketType> class PacketInterpreter;
46 /** \brief Internal: Base packet interpreter class
50 This is the base class for the persistent interpreter. This class encapsulates all the
51 functionality accessible via the packet handle, most handle operations are just forwarded.
53 class PacketInterpreterBase
54 : protected PacketData,
55 public detail::packet::interpreter_list_base,
56 public intrusive_refcount_t<PacketInterpreterBase>
59 ///////////////////////////////////////////////////////////////////////////
62 typedef senf::detail::packet::smart_pointer<
63 PacketInterpreterBase>::ptr_t ptr;
65 typedef senf::detail::packet::iterator iterator;
66 typedef senf::detail::packet::const_iterator const_iterator;
67 typedef senf::detail::packet::size_type size_type;
68 typedef senf::detail::packet::difference_type difference_type;
69 typedef senf::detail::packet::byte byte;
71 typedef boost::iterator_range<iterator> range;
72 typedef boost::optional< boost::iterator_range<iterator> > optional_range;
73 typedef optional_range no_range;
75 enum Append_t { Append };
76 enum Prepend_t { Prepend };
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(senf::NoInit_t) const = 0;
93 virtual ptr create(size_type size) const = 0;
94 virtual ptr create(size_type size, senf::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, senf::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,
104 senf::NoInit_t) const = 0;
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, senf::NoInit_t) const = 0;
114 virtual ptr createInsertBefore(PacketInterpreterBase::ptr packet) const = 0;
115 virtual ptr createInsertBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t) const = 0;
117 // Parse next packet in chain
119 virtual ptr parseNext(ptr packet) const = 0;
122 typedef Factory const * factory_t;
124 ///////////////////////////////////////////////////////////////////////////
125 ///\name Structors and default members
128 // protected constructors
130 // no conversion constructors
132 virtual ~PacketInterpreterBase();
134 static factory_t no_factory();
139 ///////////////////////////////////////////////////////////////////////////
141 ///\name Interpreter chain access
149 template <class Type> typename PacketInterpreter<Type>::ptr parseNextAs();
150 ptr parseNextAs(factory_t factory);
151 template <class Type> bool is();
152 template <class Type> typename PacketInterpreter<Type>::ptr as();
154 ptr append(ptr packet);
161 using PacketData::valid;
169 template <class Annotation>
170 Annotation & annotation();
174 ///\name Access to the abstract interface
177 optional_range nextPacketRange();
179 void finalizeTo(ptr other);
180 void dump(std::ostream & os);
181 TypeIdValue typeId();
183 factory_t nextPacketType();
188 // protected structors
190 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
191 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
192 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, ptr before);
194 ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
195 ptr appendClone(detail::PacketImpl * impl, range r);
198 // Need this for g++ < 4.0. Since PacketInterpreter is not publicly visible, it should not
199 // be a real problem to make impl() public here
200 using PacketData::impl;
203 // abstract packet type interface
205 virtual optional_range v_nextPacketRange() = 0;
206 virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
207 virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
208 virtual void v_finalize() = 0;
209 virtual void v_dump(std::ostream & os) = 0;
210 virtual TypeIdValue v_type() = 0;
211 virtual factory_t v_factory() = 0;
212 virtual factory_t v_nextPacketType() = 0;
214 // reference/memory management. Only to be called by intrusive_refcount_t.
219 // containment management. Only to be called by PacketImpl.
221 void assignImpl(detail::PacketImpl *);
224 friend class detail::PacketImpl;
225 friend class intrusive_refcount_base;
226 template <class PacketType> friend class PacketInterpreter;
227 friend class detail::packet::test::TestDriver;
228 friend class PacketParserBase;
231 /** \brief Internal: Concrete packet interpreter
235 Instantiations of this class build the interpreter chain. This class is accessed by the
236 packet handles. It provides the packet-type specific functionality in addition to the
237 interface defined in the PacketInterpreterBase class.
239 \see PacketTypeBase for the \a PacketType interface
241 template <class PacketType>
242 class PacketInterpreter
243 : public PacketInterpreterBase,
244 public pool_alloc_mixin< PacketInterpreter<PacketType> >
247 ///////////////////////////////////////////////////////////////////////////
250 typedef typename senf::detail::packet::smart_pointer<
251 PacketInterpreter>::ptr_t ptr;
252 typedef PacketType type;
253 typedef typename type::parser parser;
255 ///////////////////////////////////////////////////////////////////////////
256 ///\name Structors and default members
259 // private constructors
261 // no conversion constructors
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 static ptr createInsertBefore(PacketInterpreterBase::ptr packet);
290 static ptr createInsertBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
292 // Create a clone of the current packet
297 ///////////////////////////////////////////////////////////////////////////
299 // Packet field access
305 static size_type initSize();
306 static size_type initHeadSize();
313 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
314 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
315 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e,
316 PacketInterpreterBase::ptr before);
318 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
319 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
320 static ptr create(detail::PacketImpl * impl, iterator b, iterator e,
321 PacketInterpreterBase::ptr before);
329 virtual optional_range v_nextPacketRange();
330 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl,
331 iterator base, iterator new_base);
332 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
333 virtual void v_finalize();
334 virtual void v_dump(std::ostream & os);
335 virtual TypeIdValue v_type();
336 virtual factory_t v_factory();
337 virtual factory_t v_nextPacketType();
341 /** \brief Internal: Implementation of abstract factory interface
345 Implements the abstract factory interface for \a PacketType
347 struct FactoryImpl : public Factory {
348 // Create completely new packet
350 virtual PacketInterpreterBase::ptr create() const;
351 virtual PacketInterpreterBase::ptr create(senf::NoInit_t) const;
352 virtual PacketInterpreterBase::ptr create(size_type size) const;
353 virtual PacketInterpreterBase::ptr create(size_type size,senf::NoInit_t) const;
355 // Create packet as new packet after a given packet
357 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet)
359 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
360 senf::NoInit_t) const;
361 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
362 size_type size) const;
363 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
364 size_type size, senf::NoInit_t) const;
366 // Create packet as new packet (header) before a given packet
368 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet)
370 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
374 virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr packet)
376 virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr packet,
380 // Parse next packet in chain
382 virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet)
386 static const FactoryImpl factory_;
388 friend class detail::packet::test::TestDriver;
389 friend class PacketInterpreterBase;
390 friend class FactoryImpl;
393 /** \brief Invalid packet chain operation
395 This exception signals an invalid operation on the chain like trying to find a non-existent
396 chain member and other similar error conditions.
398 struct InvalidPacketChainException : public senf::Exception
399 { InvalidPacketChainException() : senf::Exception("invalid packet chain") {} };
403 ///////////////////////////////hh.e////////////////////////////////////////
405 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketInterpreter_i_)
406 #define HH_SENF_Packets_PacketInterpreter_i_
407 #include "PacketInterpreter.cci"
408 #include "PacketInterpreter.ct"
409 #include "PacketInterpreter.cti"
416 // c-file-style: "senf"
417 // indent-tabs-mode: nil
418 // ispell-local-dictionary: "american"
419 // compile-command: "scons -u test"
420 // comment-column: 40