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 <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 // 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;
166 template <class Annotation>
167 Annotation & annotation();
171 ///\name Access to the abstract interface
174 optional_range nextPacketRange();
176 void finalizeTo(ptr other);
177 void dump(std::ostream & os);
178 TypeIdValue typeId();
180 factory_t nextPacketType();
185 // protected structors
187 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
188 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
190 ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
191 ptr appendClone(detail::PacketImpl * impl, range r);
194 // Need this for g++ < 4.0. Since PacketInterpreter is not publicly visible, it should not
195 // be a real problem to make impl() public here
196 using PacketData::impl;
199 // abstract packet type interface
201 virtual optional_range v_nextPacketRange() = 0;
202 virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
203 virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
204 virtual void v_finalize() = 0;
205 virtual void v_dump(std::ostream & os) = 0;
206 virtual TypeIdValue v_type() = 0;
207 virtual factory_t v_factory() = 0;
208 virtual factory_t v_nextPacketType() = 0;
210 // reference/memory management. Only to be called by intrusive_refcount_t.
215 // containment management. Only to be called by PacketImpl.
217 void assignImpl(detail::PacketImpl *);
220 friend class detail::PacketImpl;
221 friend class intrusive_refcount_base;
222 template <class PacketType> friend class PacketInterpreter;
223 friend class detail::packet::test::TestDriver;
224 friend class PacketParserBase;
227 /** \brief Internal: Concrete packet interpreter
231 Instantiations of this class build the interpreter chain. This class is accessed by the
232 packet handles. It provides the packet-type specific functionality in addition to the
233 interface defined in the PacketInterpreterBase class.
235 \see PacketTypeBase for the \a PacketType interface
237 template <class PacketType>
238 class PacketInterpreter
239 : public PacketInterpreterBase,
240 public pool_alloc_mixin< PacketInterpreter<PacketType> >
243 ///////////////////////////////////////////////////////////////////////////
246 typedef typename senf::detail::packet::smart_pointer<
247 PacketInterpreter>::ptr_t ptr;
248 typedef PacketType type;
249 typedef typename type::parser parser;
251 ///////////////////////////////////////////////////////////////////////////
252 ///\name Structors and default members
255 // private constructors
257 // no conversion constructors
259 static factory_t factory();
261 // Create completely new packet
264 static ptr create(senf::NoInit_t);
265 static ptr create(size_type size);
266 static ptr create(size_type size, senf::NoInit_t);
267 template <class ForwardReadableRange>
268 static ptr create(ForwardReadableRange const & range);
270 // Create packet as new packet after a given packet
272 static ptr createAfter(PacketInterpreterBase::ptr packet);
273 static ptr createAfter(PacketInterpreterBase::ptr packet, senf::NoInit_t);
274 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
275 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, senf::NoInit_t);
276 template <class ForwardReadableRange>
277 static ptr createAfter(PacketInterpreterBase::ptr packet,
278 ForwardReadableRange const & range);
280 // Create packet as new packet (header) before a given packet
282 static ptr createBefore(PacketInterpreterBase::ptr packet);
283 static ptr createBefore(PacketInterpreterBase::ptr packet, senf::NoInit_t);
285 // Create a clone of the current packet
290 ///////////////////////////////////////////////////////////////////////////
292 // Packet field access
298 static size_type initSize();
299 static size_type initHeadSize();
306 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
307 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
309 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
310 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
318 virtual optional_range v_nextPacketRange();
319 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl,
320 iterator base, iterator new_base);
321 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
322 virtual void v_finalize();
323 virtual void v_dump(std::ostream & os);
324 virtual TypeIdValue v_type();
325 virtual factory_t v_factory();
326 virtual factory_t v_nextPacketType();
330 /** \brief Internal: Implementation of abstract factory interface
334 Implements the abstract factory interface for \a PacketType
336 struct FactoryImpl : public Factory {
337 // Create completely new packet
339 virtual PacketInterpreterBase::ptr create() const;
340 virtual PacketInterpreterBase::ptr create(senf::NoInit_t) const;
341 virtual PacketInterpreterBase::ptr create(size_type size) const;
342 virtual PacketInterpreterBase::ptr create(size_type size,senf::NoInit_t) const;
344 // Create packet as new packet after a given packet
346 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet)
348 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
349 senf::NoInit_t) const;
350 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
351 size_type size) const;
352 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
353 size_type size, senf::NoInit_t) const;
355 // Create packet as new packet (header) before a given packet
357 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet)
359 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
363 // Parse next packet in chain
365 virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet)
369 static const FactoryImpl factory_;
371 friend class detail::packet::test::TestDriver;
372 friend class PacketInterpreterBase;
373 friend class FactoryImpl;
376 /** \brief Invalid packet chain operation
378 This exception signals an invalid operation on the chain like trying to find a non-existent
379 chain member and other similar error conditions.
381 struct InvalidPacketChainException : public senf::Exception
382 { InvalidPacketChainException() : senf::Exception("invalid packet chain") {} };
386 ///////////////////////////////hh.e////////////////////////////////////////
388 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketInterpreter_i_)
389 #define HH_SENF_Packets_PacketInterpreter_i_
390 #include "PacketInterpreter.cci"
391 #include "PacketInterpreter.ct"
392 #include "PacketInterpreter.cti"
399 // c-file-style: "senf"
400 // indent-tabs-mode: nil
401 // ispell-local-dictionary: "american"
402 // compile-command: "scons -u test"
403 // comment-column: 40