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;
230 friend void senf::intrusive_ptr_add_ref(PacketInterpreterBase const *);
231 friend void senf::intrusive_ptr_release(PacketInterpreterBase const *);
234 void intrusive_ptr_add_ref(PacketInterpreterBase const * p);
235 void intrusive_ptr_release(PacketInterpreterBase const * p);
237 /** \brief Internal: Concrete packet interpreter
241 Instantiations of this class build the interpreter chain. This class is accessed by the
242 packet handles. It provides the packet-type specific functionality in addition to the
243 interface defined in the PacketInterpreterBase class.
245 \see PacketTypeBase for the \a PacketType interface
247 template <class PacketType>
248 class PacketInterpreter
249 : public PacketInterpreterBase,
250 public pool_alloc_mixin< PacketInterpreter<PacketType> >
253 ///////////////////////////////////////////////////////////////////////////
256 typedef typename senf::detail::packet::smart_pointer<
257 PacketInterpreter>::ptr_t ptr;
258 typedef PacketType type;
259 typedef typename type::parser parser;
261 ///////////////////////////////////////////////////////////////////////////
262 ///\name Structors and default members
265 // private constructors
267 // no conversion constructors
269 static factory_t factory();
271 // Create completely new packet
274 static ptr create(senf::NoInit_t);
275 static ptr create(size_type size);
276 static ptr create(size_type size, senf::NoInit_t);
277 template <class ForwardReadableRange>
278 static ptr create(ForwardReadableRange const & range);
280 // Create packet as new packet after a given packet
282 static ptr createAfter(PacketInterpreterBase::ptr packet);
283 static ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t);
284 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
285 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, senf::NoInit_t);
286 template <class ForwardReadableRange>
287 static ptr createAfter(PacketInterpreterBase::ptr packet,
288 ForwardReadableRange const & range);
290 // Create packet as new packet (header) before a given packet
292 static ptr createBefore(PacketInterpreterBase::ptr packet);
293 static ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
295 static ptr createInsertBefore(PacketInterpreterBase::ptr packet);
296 static ptr createInsertBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
298 // Create a clone of the current packet
303 ///////////////////////////////////////////////////////////////////////////
305 // Packet field access
311 static size_type initSize();
312 static size_type initHeadSize();
319 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
320 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
321 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e,
322 PacketInterpreterBase::ptr before);
324 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
325 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
326 static ptr create(detail::PacketImpl * impl, iterator b, iterator e,
327 PacketInterpreterBase::ptr before);
335 virtual optional_range v_nextPacketRange();
336 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl,
337 iterator base, iterator new_base);
338 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
339 virtual void v_finalize();
340 virtual void v_dump(std::ostream & os);
341 virtual TypeIdValue v_type();
342 virtual factory_t v_factory();
343 virtual factory_t v_nextPacketType();
347 /** \brief Internal: Implementation of abstract factory interface
351 Implements the abstract factory interface for \a PacketType
353 struct FactoryImpl : public Factory {
354 // Create completely new packet
356 virtual PacketInterpreterBase::ptr create() const;
357 virtual PacketInterpreterBase::ptr create(senf::NoInit_t) const;
358 virtual PacketInterpreterBase::ptr create(size_type size) const;
359 virtual PacketInterpreterBase::ptr create(size_type size,senf::NoInit_t) const;
361 // Create packet as new packet after a given packet
363 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet)
365 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
366 senf::NoInit_t) const;
367 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
368 size_type size) const;
369 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
370 size_type size, senf::NoInit_t) const;
372 // Create packet as new packet (header) before a given packet
374 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet)
376 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
380 virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr packet)
382 virtual PacketInterpreterBase::ptr createInsertBefore(PacketInterpreterBase::ptr packet,
386 // Parse next packet in chain
388 virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet)
392 static const FactoryImpl factory_;
394 friend class detail::packet::test::TestDriver;
395 friend class PacketInterpreterBase;
396 friend class FactoryImpl;
399 /** \brief Invalid packet chain operation
401 This exception signals an invalid operation on the chain like trying to find a non-existent
402 chain member and other similar error conditions.
404 struct InvalidPacketChainException : public senf::Exception
405 { InvalidPacketChainException() : senf::Exception("invalid packet chain") {} };
409 ///////////////////////////////hh.e////////////////////////////////////////
411 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketInterpreter_i_)
412 #define HH_SENF_Packets_PacketInterpreter_i_
413 #include "PacketInterpreter.cci"
414 #include "PacketInterpreter.ct"
415 #include "PacketInterpreter.cti"
422 // c-file-style: "senf"
423 // indent-tabs-mode: nil
424 // ispell-local-dictionary: "american"
425 // compile-command: "scons -u test"
426 // comment-column: 40