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 //-/////////////////////////////////////////////////////////////////////////////////////////////////
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);
163 using PacketData::valid;
171 template <class Annotation>
172 Annotation & annotation();
174 void clearAnnotations();
178 ///\name Access to the abstract interface
181 optional_range nextPacketRange();
183 void finalizeTo(ptr other);
184 void dump(std::ostream & os);
185 TypeIdValue typeId();
187 factory_t nextPacketType();
192 // protected structors
194 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
195 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
196 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, ptr before);
198 ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
199 ptr appendClone(detail::PacketImpl * impl, range r);
202 // Need this for g++ < 4.0. Since PacketInterpreter is not publicly visible, it should not
203 // be a real problem to make impl() public here
204 using PacketData::impl;
207 // abstract packet type interface
209 virtual optional_range v_nextPacketRange() = 0;
210 virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
211 virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
212 virtual void v_finalize() = 0;
213 virtual void v_dump(std::ostream & os) = 0;
214 virtual TypeIdValue v_type() = 0;
215 virtual factory_t v_factory() = 0;
216 virtual factory_t v_nextPacketType() = 0;
218 // reference/memory management. Only to be called by intrusive_refcount_t.
223 // containment management. Only to be called by PacketImpl.
225 void assignImpl(detail::PacketImpl *);
228 friend class detail::PacketImpl;
229 friend class intrusive_refcount_base;
230 template <class PacketType> friend class PacketInterpreter;
231 friend class detail::packet::test::TestDriver;
232 friend class PacketParserBase;
234 friend void senf::intrusive_ptr_add_ref(PacketInterpreterBase const *);
235 friend void senf::intrusive_ptr_release(PacketInterpreterBase const *);
238 void intrusive_ptr_add_ref(PacketInterpreterBase const * p);
239 void intrusive_ptr_release(PacketInterpreterBase const * p);
241 /** \brief Internal: Concrete packet interpreter
245 Instantiations of this class build the interpreter chain. This class is accessed by the
246 packet handles. It provides the packet-type specific functionality in addition to the
247 interface defined in the PacketInterpreterBase class.
249 \see PacketTypeBase for the \a PacketType interface
251 template <class PacketType>
252 class PacketInterpreter
253 : public PacketInterpreterBase,
254 public pool_alloc_mixin< PacketInterpreter<PacketType> >
257 //-////////////////////////////////////////////////////////////////////////
260 typedef typename senf::detail::packet::smart_pointer<
261 PacketInterpreter>::ptr_t ptr;
262 typedef PacketType type;
263 typedef typename type::parser parser;
265 //-////////////////////////////////////////////////////////////////////////
266 ///\name Structors and default members
269 // private constructors
271 // no conversion constructors
273 static factory_t factory();
275 // Create completely new packet
278 static ptr create(senf::NoInit_t);
279 static ptr create(size_type size);
280 static ptr create(size_type size, senf::NoInit_t);
281 template <class ForwardReadableRange>
282 static ptr create(ForwardReadableRange const & range);
284 // Create packet as new packet after a given packet
286 static ptr createAfter(PacketInterpreterBase::ptr packet);
287 static ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t);
288 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
289 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, senf::NoInit_t);
290 template <class ForwardReadableRange>
291 static ptr createAfter(PacketInterpreterBase::ptr packet,
292 ForwardReadableRange const & range);
294 // Create packet as new packet (header) before a given packet
296 static ptr createBefore(PacketInterpreterBase::ptr packet);
297 static ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
299 static ptr createInsertBefore(PacketInterpreterBase::ptr packet);
300 static ptr createInsertBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
302 // Create a clone of the current packet
307 //-////////////////////////////////////////////////////////////////////////
309 // Packet field access
315 static size_type initSize();
316 static size_type initHeadSize();
323 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
324 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
325 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e,
326 PacketInterpreterBase::ptr before);
328 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
329 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
330 static ptr create(detail::PacketImpl * impl, iterator b, iterator e,
331 PacketInterpreterBase::ptr before);
339 virtual optional_range v_nextPacketRange();
340 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl,
341 iterator base, iterator new_base);
342 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
343 virtual void v_finalize();
344 virtual void v_dump(std::ostream & os);
345 virtual TypeIdValue v_type();
346 virtual factory_t v_factory();
347 virtual factory_t v_nextPacketType();
351 /** \brief Internal: Implementation of abstract factory interface
355 Implements the abstract factory interface for \a PacketType
357 struct FactoryImpl : public Factory {
358 // Create completely new packet
360 virtual PacketInterpreterBase::ptr create() const;
361 virtual PacketInterpreterBase::ptr create(senf::NoInit_t) const;
362 virtual PacketInterpreterBase::ptr create(size_type size) const;
363 virtual PacketInterpreterBase::ptr create(size_type size,senf::NoInit_t) const;
365 // Create packet as new packet after a given packet
367 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet)
369 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
370 senf::NoInit_t) const;
371 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
372 size_type size) const;
373 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
374 size_type size, senf::NoInit_t) const;
376 // Create packet as new packet (header) before a given packet
378 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet)
380 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
384 virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr packet)
386 virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr packet,
390 // Parse next packet in chain
392 virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet)
396 static const FactoryImpl factory_;
398 friend class detail::packet::test::TestDriver;
399 friend class PacketInterpreterBase;
400 friend class FactoryImpl;
403 /** \brief Invalid packet chain operation
405 This exception signals an invalid operation on the chain like trying to find a non-existent
406 chain member and other similar error conditions.
408 struct InvalidPacketChainException : public senf::Exception
409 { InvalidPacketChainException() : senf::Exception("invalid packet chain") {} };
413 //-/////////////////////////////////////////////////////////////////////////////////////////////////
415 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketInterpreter_i_)
416 #define HH_SENF_Packets_PacketInterpreter_i_
417 #include "PacketInterpreter.cci"
418 #include "PacketInterpreter.ct"
419 #include "PacketInterpreter.cti"
426 // c-file-style: "senf"
427 // indent-tabs-mode: nil
428 // ispell-local-dictionary: "american"
429 // compile-command: "scons -u test"
430 // comment-column: 40