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 // Need this for g++ < 4.0. Since PacketInterpreter is not publically visible, it should not
173 // be a real problem to make impl() public here
174 using PacketData::impl;
177 // abstract packet type interface
179 virtual optional_range v_nextPacketRange() = 0;
180 virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
181 virtual ptr v_appendClone(detail::PacketImpl * impl, range r) =0;
182 virtual void v_finalize() = 0;
183 virtual void v_dump(std::ostream & os) = 0;
184 virtual TypeIdValue v_type() = 0;
185 virtual factory_t v_factory() = 0;
186 virtual factory_t v_nextPacketType() = 0;
188 // reference/memory management. Only to be called by intrusive_refcount_t.
193 // containment management. Only to be called by PacketImpl.
195 void assignImpl(detail::PacketImpl *);
198 friend class detail::PacketImpl;
199 friend class intrusive_refcount_t<PacketInterpreterBase>;
200 template <class PacketType> friend class PacketInterpreter;
201 friend class detail::packet::test::TestDriver;
204 /** \brief Concrete packet interpreter
206 \see PacketTypeBase for the \a PacketType interface
208 template <class PacketType>
209 class PacketInterpreter
210 : public PacketInterpreterBase,
211 public pool_alloc_mixin< PacketInterpreter<PacketType> >
214 ///////////////////////////////////////////////////////////////////////////
217 typedef typename senf::detail::packet::smart_pointer<
218 PacketInterpreter>::ptr_t ptr;
219 typedef PacketType type;
220 typedef typename type::parser parser;
222 ///////////////////////////////////////////////////////////////////////////
223 ///\name Structors and default members
226 // private constructors
228 // no conversion constructors
230 ~PacketInterpreter();
232 static factory_t factory();
234 // Create completely new packet
237 static ptr create(NoInit_t);
238 static ptr create(size_type size);
239 static ptr create(size_type size, NoInit_t);
240 template <class ForwardReadableRange>
241 static ptr create(ForwardReadableRange const & range);
243 // Create packet as new packet after a given packet
245 static ptr createAfter(PacketInterpreterBase::ptr packet);
246 static ptr createAfter(PacketInterpreterBase::ptr packet, NoInit_t);
247 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size);
248 static ptr createAfter(PacketInterpreterBase::ptr packet, size_type size, NoInit_t);
249 template <class ForwardReadableRange>
250 static ptr createAfter(PacketInterpreterBase::ptr packet,
251 ForwardReadableRange const & range);
253 // Create packet as new packet (header) before a given packet
255 static ptr createBefore(PacketInterpreterBase::ptr packet);
256 static ptr createBefore(PacketInterpreterBase::ptr packet, NoInit_t);
258 // Create a clone of the current packet
263 ///////////////////////////////////////////////////////////////////////////
265 // Packet field access
272 static size_type initSize();
273 static size_type initHeadSize();
280 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
281 PacketInterpreter(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
283 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
284 static ptr create(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
292 virtual optional_range v_nextPacketRange();
293 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl,
294 iterator base, iterator new_base);
295 virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
296 virtual void v_finalize();
297 virtual void v_dump(std::ostream & os);
298 virtual TypeIdValue v_type();
299 virtual factory_t v_factory();
300 virtual factory_t v_nextPacketType();
304 struct FactoryImpl : public Factory {
305 // Create completely new packet
307 virtual PacketInterpreterBase::ptr create() const;
308 virtual PacketInterpreterBase::ptr create(NoInit_t) const;
309 virtual PacketInterpreterBase::ptr create(size_type size) const;
310 virtual PacketInterpreterBase::ptr create(size_type size,NoInit_t) const;
312 // Create packet as new packet after a given packet
314 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet)
316 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
318 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
319 size_type size) const;
320 virtual PacketInterpreterBase::ptr createAfter(PacketInterpreterBase::ptr packet,
321 size_type size, NoInit_t) const;
323 // Create packet as new packet (header) before a given packet
325 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet)
327 virtual PacketInterpreterBase::ptr createBefore(PacketInterpreterBase::ptr packet,
331 // Parse next packet in chain
333 virtual PacketInterpreterBase::ptr parseNext(PacketInterpreterBase::ptr packet)
337 static const FactoryImpl factory_;
341 boost::aligned_storage< sizeof(parser),
342 boost::alignment_of<parser>::value > parserStorage_;
344 friend class detail::packet::test::TestDriver;
345 friend class PacketInterpreterBase;
346 friend class FactoryImpl;
349 struct InvalidPacketChainException : public std::exception
350 { virtual char const * what() const throw() { return "invalid packet chain"; } };
354 ///////////////////////////////hh.e////////////////////////////////////////
355 #include "PacketInterpreter.cci"
356 #include "PacketInterpreter.ct"
357 #include "PacketInterpreter.cti"
364 // c-file-style: "senf"
365 // indent-tabs-mode: nil
366 // ispell-local-dictionary: "american"
367 // compile-command: "scons -u test"
368 // comment-column: 40