PacketInterpreter.hh
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #ifndef HH_SENF_Packets_PacketInterpreter_
18 #define HH_SENF_Packets_PacketInterpreter_ 1
19 
20 // Custom includes
21 #include <boost/optional.hpp>
22 #include <boost/range/iterator_range.hpp>
25 #include <senf/Utils/Tags.hh>
26 #include "PacketData.hh"
27 
28 //#include "PacketInterpreter.mpp"
29 //-/////////////////////////////////////////////////////////////////////////////////////////////////
30 
31 namespace senf {
32 
34 
35 
36  template <class PacketType> class PacketInterpreter;
37 
40 
41 
50  : protected PacketData,
52  public intrusive_refcount_t<PacketInterpreterBase>
53  {
54  public:
55  //-////////////////////////////////////////////////////////////////////////
56  // Types
57 
59 
65 
66  typedef boost::iterator_range<iterator> range;
67  typedef boost::optional<range> optional_range;
68  typedef optional_range no_range;
69 
70  enum Append_t { Append };
71  enum Prepend_t { Prepend };
72 
81  struct Factory {
82  virtual ~Factory();
83 
84  // Create completely new packet
85 
86  virtual ptr create() const = 0;
87  virtual ptr create(senf::NoInit_t) const = 0;
88  virtual ptr create(size_type size) const = 0;
89  virtual ptr create(size_type size, senf::NoInit_t) const = 0;
90  template <class ForwardReadableRange>
91  ptr create(ForwardReadableRange const & range) const;
92  virtual ptr create(byte * data, size_type size, size_type chunkSize = 0u,
93  size_type offset = 0u) = 0;
94 
95  // Create packet as new packet after a given packet
96 
97  virtual ptr createAfter(PacketInterpreterBase::ptr const & packet) const = 0;
98  virtual ptr createAfter(PacketInterpreterBase::ptr const & packet, senf::NoInit_t) const = 0;
99  virtual ptr createAfter(PacketInterpreterBase::ptr const & packet, size_type size) const = 0;
100  virtual ptr createAfter(PacketInterpreterBase::ptr const & packet, size_type size,
101  senf::NoInit_t) const = 0;
102  template <class ForwardReadableRange>
103  ptr createAfter(PacketInterpreterBase::ptr const & packet,
104  ForwardReadableRange const & range) const;
105 
106  // Create packet as new packet (header) const before a given packet
107 
108  virtual ptr createBefore(PacketInterpreterBase::ptr const & packet) const = 0;
109  virtual ptr createBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t) const = 0;
110 
111  virtual ptr createInsertBefore(PacketInterpreterBase::ptr const & packet) const = 0;
112  virtual ptr createInsertBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t) const = 0;
113 
114  // Parse next packet in chain
115 
116  virtual ptr parseNext(ptr const & packet, PacketInterpreterBase::optional_range const & range) const = 0;
117  };
118 
119  typedef Factory const * factory_t;
120 
121  //-////////////////////////////////////////////////////////////////////////
123  //\{
124 
125  // protected constructors
126  // no copy
127  // no conversion constructors
128 
129  virtual ~PacketInterpreterBase();
130 
131  static factory_t no_factory();
132 
133  ptr clone();
134 
135  //\}
136  //-////////////////////////////////////////////////////////////////////////
137 
139  //\{
140 
141  ptr next();
142  ptr prev();
143  ptr first();
144  ptr last();
145 
146  template <class Type>
148  ptr parseNextAs(ptr const & self, factory_t factory, PacketInterpreterBase::optional_range const & range);
149  template <class Type>
150  typename PacketInterpreter<Type>::ptr as();
151 
152  ptr append(ptr packet);
153 
154  void reparse();
155 
156  template <class Type>
157  typename PacketInterpreter<Type>::ptr replaceAs(difference_type offset, difference_type tailOffset);
158 
159  //\}
160 
162  //\{
163 
164  using PacketData::valid;
165  PacketData & data();
166 
167  //\}
168 
170  //\{
171 
172  template <class Annotation>
173  Annotation & annotation();
174 
175  void clearAnnotations();
176 
177  //\}
178 
180  //\{
181 
182  optional_range nextPacketRange();
183  void finalizeThis();
184  void finalizeTo(ptr other);
185  void dump(std::ostream & os, DumpPacketAnnotations_t dumpAnnotationsSwitch);
186  void memDebug(std::ostream & os);
188  factory_t factory();
189  factory_t nextPacketType();
190 
191  //\}
192 
193  protected:
194  // protected structors
195 
196  PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Append_t);
197  PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, Prepend_t);
198  PacketInterpreterBase(detail::PacketImpl * impl, iterator b, iterator e, ptr before);
199 
200  ptr appendClone(detail::PacketImpl * impl, iterator base, iterator new_base);
201  ptr appendClone(detail::PacketImpl * impl, range r);
202 
205 
206  public:
207  // Need this public for g++ < 4.0. Since PacketInterpreter is not publicly visible, it should not
208  // be a real problem to make impl() public here
209  detail::PacketImpl & impl() const;
210 
211  private:
212  // abstract packet type interface
213 
214  virtual optional_range v_nextPacketRange() = 0;
215  virtual ptr v_appendClone(detail::PacketImpl * impl, iterator base, iterator new_base) = 0;
216  virtual ptr v_appendClone(detail::PacketImpl * impl, range r) = 0;
217  virtual void v_finalize() = 0;
218  virtual void v_dump(std::ostream & os) = 0;
219  virtual TypeIdValue v_type() = 0;
220  virtual factory_t v_factory() = 0;
221  virtual factory_t v_nextPacketType() = 0;
222 
223  // reference/memory management. Only to be called by intrusive_refcount_t.
224 
225  void add_ref();
226  void release();
227 
228  // containment management. Only to be called by PacketImpl.
229 
230  void assignImpl(detail::PacketImpl *);
231  void releaseImpl();
232 
233  friend class detail::PacketImpl;
235  template <class PacketType> friend class PacketInterpreter;
236  friend struct detail::packet::test::TestDriver;
237  friend class PacketParserBase;
238 
241  };
242 
253  template <class PacketType>
254  class PacketInterpreter
255  : public PacketInterpreterBase
256  {
257  public:
258  //-////////////////////////////////////////////////////////////////////////
259  // Types
260 
261  typedef typename senf::detail::packet::smart_pointer<
263  typedef PacketType type;
264  typedef typename type::parser parser;
265 
266  //-////////////////////////////////////////////////////////////////////////
268  //\{
269 
270  // private constructors
271  // no copy
272  // no conversion constructors
273 
274  static factory_t factory();
275 
276  // Create completely new packet
277 
278  static ptr create();
279  static ptr create(senf::NoInit_t);
280  static ptr create(size_type size);
281  static ptr create(size_type size, senf::NoInit_t);
282  template <class ForwardReadableRange>
283  static ptr create(ForwardReadableRange const & range);
284  static ptr create(byte * data, size_type size, size_type chunkSize = 0u,
285  size_type offset = 0u);
286 
287  // Create packet as new packet after a given packet
288 
289  static ptr createAfter(PacketInterpreterBase::ptr const & packet);
290  static ptr createAfter(PacketInterpreterBase::ptr const & packet, senf::NoInit_t);
291  static ptr createAfter(PacketInterpreterBase::ptr const & packet, size_type size);
292  static ptr createAfter(PacketInterpreterBase::ptr const & packet, size_type size,
294  template <class ForwardReadableRange>
295  static ptr createAfter(PacketInterpreterBase::ptr const & packet,
296  ForwardReadableRange const & range);
297 
298  // Create packet as new packet (header) before a given packet
299 
300  static ptr createBefore(PacketInterpreterBase::ptr const & spacket);
301  static ptr createBeforeNoZero(PacketInterpreterBase::ptr const & spacket);
302  static ptr createBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t,
303  size_type space=0, size_type tailSpace=0);
304 
305  static ptr createInsertBefore(PacketInterpreterBase::ptr const & packet);
307 
308  // Create a clone of the current packet
309 
310  ptr clone();
311 
312  //\}
313  //-////////////////////////////////////////////////////////////////////////
314 
315  // Packet field access
316 
317  parser fields();
318 
319  // PacketType access
320 
321  static size_type initSize();
322  static size_type initHeadSize();
323 
324  protected:
325 
326  private:
327  // Private structors
328 
332  PacketInterpreterBase::ptr const & before);
333 
336  static ptr create(detail::PacketImpl * impl, iterator b, iterator e,
337  PacketInterpreterBase::ptr const & before);
338 
339  // PacketType access
340 
341  void init();
342 
343  // virtual interface
344 
345  virtual optional_range v_nextPacketRange();
346  virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl,
347  iterator base, iterator new_base);
348  virtual PacketInterpreterBase::ptr v_appendClone(detail::PacketImpl * impl, range r);
349  virtual void v_finalize();
350  virtual void v_dump(std::ostream & os);
351  virtual TypeIdValue v_type();
352  virtual factory_t v_factory();
353  virtual factory_t v_nextPacketType();
354 
355  // factory
356 
363  struct FactoryImpl : public Factory {
364  FactoryImpl() {}
365 
366  // Create completely new packet
367 
368  virtual PacketInterpreterBase::ptr create() const;
373  size_type chunkSize = 0u, size_type offset = 0u);
374 
375  // Create packet as new packet after a given packet
376 
378  const;
380  senf::NoInit_t) const;
382  size_type size) const;
384  size_type size, senf::NoInit_t) const;
385 
386  // Create packet as new packet (header) before a given packet
387 
389  const;
392  const;
393 
395  const;
398  const;
399 
400  // Parse next packet in chain
401 
403  const;
404  };
405 
406  friend struct detail::packet::test::TestDriver;
407  friend class PacketInterpreterBase;
408  friend struct FactoryImpl;
409  };
410 
417  { InvalidPacketChainException() : senf::Exception("invalid packet chain") {} };
418 
419 }
420 
421 //-/////////////////////////////////////////////////////////////////////////////////////////////////
422 #endif
423 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketInterpreter_i_)
424 #define HH_SENF_Packets_PacketInterpreter_i_
425 #include "PacketInterpreter.cci"
426 #include "PacketInterpreter.ct"
427 #include "PacketInterpreter.cti"
428 #endif
429 
430 
431 // Local Variables:
432 // mode: c++
433 // fill-column: 100
434 // c-file-style: "senf"
435 // indent-tabs-mode: nil
436 // ispell-local-dictionary: "american"
437 // compile-command: "scons -u test"
438 // comment-column: 40
439 // End:
void dump(std::ostream &os, DumpPacketAnnotations_t dumpAnnotationsSwitch)
void init()
static factory_t no_factory()
DumpPacketAnnotations_t
Internal: Abstract packet factory.
senf::detail::packet::smart_pointer< PacketInterpreter >::ptr_t ptr
detail::PacketImpl & impl() const
PacketInterpreterBase * nextP()
PacketData public header.
senf::detail::packet::iterator iterator
Definition: PacketData.hh:68
PacketInterpreter< Type >::ptr parseNextAs()
void intrusive_ptr_add_ref(PacketInterpreterBase const *p)
virtual ptr createAfter(PacketInterpreterBase::ptr const &packet) const =0
Internal: Concrete packet interpreter.
Definition: PacketImpl.hh:99
senf::detail::packet::difference_type difference_type
Internal: Base packet interpreter class.
NoInit_t
PacketInterpreter< Type >::ptr as()
virtual ptr createInsertBefore(PacketInterpreterBase::ptr const &packet) const =0
raw_container::const_iterator const_iterator
Definition: PacketTypes.hh:70
boost::intrusive::list_base_hook< boost::intrusive::tag< interpreter_list_tag > > interpreter_list_base
Definition: PacketTypes.hh:54
Invalid packet chain operation.
Packet data STL-sequence view.
Definition: PacketData.hh:61
raw_container::size_type size_type
Definition: PacketTypes.hh:66
Internal: Packet data storage.
Definition: PacketImpl.hh:112
virtual ptr createBefore(PacketInterpreterBase::ptr const &packet) const =0
raw_container::iterator iterator
Definition: PacketTypes.hh:69
senf::detail::packet::smart_pointer< PacketInterpreterBase >::ptr_t ptr
senf::detail::packet::byte byte
ptr appendClone(detail::PacketImpl *impl, iterator base, iterator new_base)
senf::detail::packet::size_type size_type
Definition: PacketData.hh:70
Internal: Template typedef for used smart pointer.
Definition: PacketTypes.hh:50
size_type size() const
Returns the number of bytes in the packet data.
raw_container::difference_type difference_type
Definition: PacketTypes.hh:67
boost::intrusive_ptr< T > ptr_t
Definition: PacketTypes.hh:51
virtual ptr parseNext(ptr const &packet, PacketInterpreterBase::optional_range const &range) const =0
boost::optional< range > optional_range
senf::detail::packet::size_type size_type
void intrusive_ptr_release(PacketInterpreterBase const *p)
Parser Base class.
PacketInterpreterBase * prevP()
boost::iterator_range< iterator > range
boost::uint8_t byte
Definition: PacketTypes.hh:60
senf::detail::packet::byte byte
Definition: PacketData.hh:72
void memDebug(std::ostream &os)
PacketInterpreter< Type >::ptr replaceAs(difference_type offset, difference_type tailOffset)
PacketInterpreterBase(detail::PacketImpl *impl, iterator b, iterator e, Append_t)
senf::detail::packet::const_iterator const_iterator
optional_range nextPacketRange()
senf::detail::packet::iterator iterator