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 "typeidvalue.hh"
38 //#include "PacketInterpreter.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
43 template <class PacketType> class PacketInterpreter;
47 class PacketInterpreterBase
48 : protected PacketData,
49 public detail::packet::interpreter_list_base,
50 public intrusive_refcount_t<PacketInterpreterBase>
53 ///////////////////////////////////////////////////////////////////////////
56 typedef senf::detail::packet::smart_pointer<
57 PacketInterpreterBase>::ptr_t ptr;
59 typedef senf::detail::packet::iterator iterator;
60 typedef senf::detail::packet::const_iterator const_iterator;
61 typedef senf::detail::packet::size_type size_type;
62 typedef senf::detail::packet::difference_type difference_type;
63 typedef senf::detail::packet::byte byte;
65 typedef boost::iterator_range<iterator> range;
66 typedef boost::optional< boost::iterator_range<iterator> > optional_range;
67 typedef optional_range no_range;
69 enum Append_t { Append };
70 enum Prepend_t { Prepend };
71 enum NoInit_t { noinit };
76 // Create completely new packet
78 virtual ptr create() const = 0;
79 virtual ptr create(NoInit_t) const = 0;
80 virtual ptr create(size_type size) const = 0;
81 virtual ptr create(size_type size, NoInit_t) const = 0;
82 template <class ForwardReadableRange>
83 ptr create(ForwardReadableRange const & range) const;
85 // Create packet as new packet after a given packet
87 virtual ptr createAfter(PacketInterpreterBase::ptr packet) const = 0;
88 virtual ptr createAfter(PacketInterpreterBase::ptr packet, NoInit_t) const = 0;
89 virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size) const = 0;
90 virtual ptr createAfter(PacketInterpreterBase::ptr packet, size_type size,
92 template <class ForwardReadableRange>
93 ptr createAfter(PacketInterpreterBase::ptr packet,
94 ForwardReadableRange const & range) const;
96 // Create packet as new packet (header) const before a given packet
98 virtual ptr createBefore(PacketInterpreterBase::ptr packet) const = 0;
99 virtual ptr createBefore(PacketInterpreterBase::ptr packet, NoInit_t) const = 0;
101 // Parse next packet in chain
103 virtual ptr parseNext(ptr packet) const = 0;
106 typedef Factory const * factory_t;
108 ///////////////////////////////////////////////////////////////////////////
109 ///\name Structors and default members
112 // protected constructors
114 // no conversion constructors
116 virtual ~PacketInterpreterBase();
118 static factory_t no_factory();
123 ///////////////////////////////////////////////////////////////////////////
125 ///\name Interpreter chain access
133 template <class Type> typename PacketInterpreter<Type>::ptr parseNextAs();
134 ptr parseNextAs(factory_t factory);
135 template <class Type> bool is();
136 template <class Type> typename PacketInterpreter<Type>::ptr as();
138 ptr append(ptr packet);
145 using PacketData::valid;
150 ///\name Access to the abstract interface
153 optional_range nextPacketRange();
155 void dump(std::ostream & os);
156 TypeIdValue typeId();
158 factory_t nextPacketType();
163 // protected structors
165 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
166 PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
168 ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
169 ptr appendClone(detail::PacketImpl * impl, range r);
172 // abstract packet type interface
174 virtual optional_range v_nextPacketRange() = 0;
175 virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
176 virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
177 virtual void v_finalize() = 0;
178 virtual void v_dump(std::ostream & os) = 0;
179 virtual TypeIdValue v_type() = 0;
180 virtual factory_t v_factory() = 0;
181 virtual factory_t v_nextPacketType() = 0;
183 // reference/memory management. Only to be called by intrusive_refcount_t.
188 // containment management. Only to be called by PacketImpl.
190 void assignImpl(detail::PacketImpl *);
193 friend class detail::PacketImpl;
194 friend class intrusive_refcount_t<PacketInterpreterBase>;
195 template <class PacketType> friend class PacketInterpreter;
196 friend class detail::packet::test::TestDriver;
199 /** \brief Concrete packet interpreter
201 \see PacketTypeBase for the \a PacketType interface
203 template <class PacketType>
204 class PacketInterpreter
205 : public PacketInterpreterBase,
206 public pool_alloc_mixin< PacketInterpreter<PacketType> >
209 ///////////////////////////////////////////////////////////////////////////
212 typedef typename senf::detail::packet::smart_pointer<
213 PacketInterpreter>::ptr_t ptr;
214 typedef PacketType type;
215 typedef typename type::parser parser;
217 ///////////////////////////////////////////////////////////////////////////
218 ///\name Structors and default members
221 // private constructors
223 // no conversion constructors
225 ~PacketInterpreter();
227 static factory_t factory();
229 // Create completely new packet
232 static ptr create(NoInit_t);
233 static ptr create(size_type size);
234 static ptr create(size_type size, NoInit_t);
235 template <class ForwardReadableRange>
236 static ptr create(ForwardReadableRange const & range);
238 // Create packet as new packet after a given packet
240 static ptr createAfter(PacketInterpreterBase::ptr packet);
241 static ptr createAfter(PacketInterpreterBase::ptr packet, NoInit_t);
242 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
243 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, NoInit_t);
244 template <class ForwardReadableRange>
245 static ptr createAfter(PacketInterpreterBase::ptr packet,
246 ForwardReadableRange const & range);
248 // Create packet as new packet (header) before a given packet
250 static ptr createBefore(PacketInterpreterBase::ptr packet);
251 static ptr createBefore(PacketInterpreterBase::ptr packet, NoInit_t);
253 // Create a clone of the current packet
258 ///////////////////////////////////////////////////////////////////////////
260 // Packet field access
267 static size_type initSize();
268 static size_type initHeadSize();
275 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
276 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
278 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
279 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
287 virtual optional_range v_nextPacketRange();
288 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl,
289 iterator base, iterator new_base);
290 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
291 virtual void v_finalize();
292 virtual void v_dump(std::ostream & os);
293 virtual TypeIdValue v_type();
294 virtual factory_t v_factory();
295 virtual factory_t v_nextPacketType();
299 struct FactoryImpl : public Factory {
300 // Create completely new packet
302 virtual PacketInterpreterBase::ptr create() const;
303 virtual PacketInterpreterBase::ptr create(NoInit_t) const;
304 virtual PacketInterpreterBase::ptr create(size_type size) const;
305 virtual PacketInterpreterBase::ptr create(size_type size,NoInit_t) const;
307 // Create packet as new packet after a given packet
309 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet)
311 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
313 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
314 size_type size) const;
315 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
316 size_type size, NoInit_t) const;
318 // Create packet as new packet (header) before a given packet
320 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet)
322 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
326 // Parse next packet in chain
328 virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet)
332 static const FactoryImpl factory_;
336 boost::aligned_storage< sizeof(parser),
337 boost::alignment_of<parser>::value > parserStorage_;
339 friend class detail::packet::test::TestDriver;
340 friend class PacketInterpreterBase;
341 friend class FactoryImpl;
344 struct InvalidPacketChainException : public std::exception
345 { virtual char const * what() const throw() { return "invalid packet chain"; } };
349 ///////////////////////////////hh.e////////////////////////////////////////
350 #include "PacketInterpreter.cci"
351 #include "PacketInterpreter.ct"
352 #include "PacketInterpreter.cti"
359 // c-file-style: "senf"
360 // indent-tabs-mode: nil
361 // ispell-local-dictionary: "american"