PacketInterpreter.ct
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 
14 /** \file
15  \brief PacketInterpreter non-inline template implementation */
16 
17 //#include "PacketInterpreter.ih"
18 
19 // Custom includes
20 #include "Packet.hh"
21 
22 #define prefix_
23 //-/////////////////////////////////////////////////////////////////////////////////////////////////
24 
25 //-/////////////////////////////////////////////////////////////////////////////////////////////////
26 // senf::PacketInterpreterBase
27 
28 // Interpreter chain access
29 
30 template <class Type>
31 prefix_ typename senf::PacketInterpreter<Type>::ptr
32 senf::PacketInterpreterBase::parseNextAs()
33 {
34  optional_range r (nextPacketRange());
35  if (!r)
36  throw InvalidPacketChainException();
37 
38  if (next())
39  impl().truncateInterpreters(nextP());
40 
41  typename PacketInterpreter<Type>::ptr pi
42  (PacketInterpreter<Type>::create(&impl(),r->begin(),r->end(),Append));
43  return pi;
44 }
45 
46 template <class Type>
47 prefix_ typename senf::PacketInterpreter<Type>::ptr
48 senf::PacketInterpreterBase::replaceAs(difference_type offset, difference_type tailOffset)
49 {
50  { static typename PacketInterpreter<Type>::factory_t _ (PacketInterpreter<Type>::factory()); (void) _;}
51  iterator b (data().begin() + offset);
52  size_type sz (data().size() - offset + tailOffset);
53  detail::PacketImpl::Guard p (&impl());
54  p.p->clearInterpreters();
55  b = p.p->truncateRawDataBackwards(b);
56  return senf::PacketInterpreter<Type>::create(p.p, b, b + sz, Append);
57 }
58 
59 //-/////////////////////////////////////////////////////////////////////////////////////////////////
60 // senf::PacketInterpreter<PacketType>
61 
62 // Create completely new packet
63 
64 template <class PacketType>
65 prefix_ typename senf::PacketInterpreter<PacketType>::ptr
66 senf::PacketInterpreter<PacketType>::create(size_type size)
67 {
68  if (size < initSize())
69  throw TruncatedPacketException();
70  ptr pi (create(size,senf::noinit));
71  pi->init();
72  return pi;
73 }
74 
75 template <class PacketType>
76 prefix_ typename senf::PacketInterpreter<PacketType>::ptr
77 senf::PacketInterpreter<PacketType>::create(size_type size, senf::NoInit_t)
78 {
79  detail::PacketImpl::Guard p (new detail::PacketImpl(size,0));
80  return create(p.p,p.p->begin(),p.p->end(),Append);
81 }
82 
83 template <class PacketType>
84 prefix_ typename senf::PacketInterpreter<PacketType>::ptr
85 senf::PacketInterpreter<PacketType>::create(byte * data, size_type size, size_type chunkSize,
86  size_type offset)
87 {
88  detail::PacketImpl::Guard p (new detail::PacketImpl(data, size, chunkSize, offset));
89  return create(p.p,p.p->begin(),p.p->end(),Append);
90 }
91 
92 // Create packet as new packet after a given packet
93 
94 template <class PacketType>
95 prefix_ typename senf::PacketInterpreter<PacketType>::ptr
96 senf::PacketInterpreter<PacketType>::createAfter(PacketInterpreterBase::ptr const & packet,
97  size_type size)
98 {
99  if (size < initSize())
100  throw TruncatedPacketException();
101  ptr pi (createAfter(packet,size,senf::noinit));
102  std::fill(pi->data().begin(), pi->data().end(),0);
103  pi->init();
104  return pi;
105 }
106 
107 template <class PacketType>
108 prefix_ typename senf::PacketInterpreter<PacketType>::ptr
109 senf::PacketInterpreter<PacketType>::createAfter(PacketInterpreterBase::ptr const & packet,
110  size_type size, senf::NoInit_t)
111 {
112  optional_range r (packet->nextPacketRange());
113  if (!r)
114  throw InvalidPacketChainException();
115 
116  if (packet->next())
117  packet->impl().truncateInterpreters(packet->nextP());
118 
119  ptr pi (create(&packet->impl(),r->begin(),r->end(),Append));
120  pi->data().resize(size);
121  return pi;
122 }
123 
124 template <class PacketType>
125 template <class ForwardReadableRange>
126 prefix_ typename senf::PacketInterpreter<PacketType>::ptr
127 senf::PacketInterpreter<PacketType>::createAfter(PacketInterpreterBase::ptr const & packet,
128  ForwardReadableRange const & range)
129 {
130  optional_range r (packet->nextPacketRange());
131  if (!r)
132  throw InvalidPacketChainException();
133 
134  if (packet->next())
135  packet->impl().truncateInterpreters(packet->nextP());
136 
137  ptr pi (create(&packet->impl(),r->begin(),r->end(),Append));
138  pi->data().resize(boost::size(range));
139  std::copy(boost::begin(range), boost::end(range), pi->data().begin());
140  return pi;
141 }
142 
143 // Create packet as new packet (header) before a given packet
144 
145 template <class PacketType>
146 prefix_ typename senf::PacketInterpreter<PacketType>::ptr
147 senf::PacketInterpreter<PacketType>::createBeforeNoZero(PacketInterpreterBase::ptr const & packet)
148 {
149  ptr pi (createBefore(packet, senf::noinit, initHeadSize(), initSize() - initHeadSize()));
150  pi->init();
151  return pi;
152 }
153 
154 template <class PacketType>
155 prefix_ typename senf::PacketInterpreter<PacketType>::ptr
156 senf::PacketInterpreter<PacketType>::createBefore(PacketInterpreterBase::ptr const & packet)
157 {
158  ptr pi (createBefore(packet, senf::noinit, initHeadSize(), initSize() - initHeadSize()));
159  pi->data().zero(pi->data().begin(), packet->data().begin());
160  pi->data().zero(packet->data().end(), pi->data().end());
161  pi->init();
162  return pi;
163 }
164 
165 template <class PacketType>
166 prefix_ typename senf::PacketInterpreter<PacketType>::ptr
167 senf::PacketInterpreter<PacketType>::createBefore(PacketInterpreterBase::ptr const & packet,
168  senf::NoInit_t, size_type space,
169  size_type tailSpace)
170 {
171  if (packet->prev())
172  packet->impl().truncateInterpretersBackwards(packet->prevP());
173  size_type room (std::distance(packet->impl().begin(), packet->data().begin()));
174  ptr pi (create(&packet->impl(), packet->impl().begin(), packet->data().end(), Prepend));
175  if (room > space)
176  packet->impl().truncateDataBackwards(& pi->data(), packet->data().begin() - space);
177  else if (room < space)
178  pi->data().insert(pi->data().begin(), space - room, byte(0x00u));
179  // For the tail-space it's much simpler: since we have pruned the interpreter chain with the
180  // current packet, pi must be the most-outside packet interpreter. This means, there can be no
181  // packet which has data after pi. We can thus change the underlying data container without
182  // updating any other packet interpreter (that is the data offsets therein).
183  packet->impl().truncateRawDataForward(pi->data().end());
184  pi->data().insert(pi->data().end(), tailSpace, byte(0x00u));
185  return pi;
186 }
187 
188 template <class PacketType>
189 prefix_ typename senf::PacketInterpreter<PacketType>::ptr
190 senf::PacketInterpreter<PacketType>::createInsertBefore(PacketInterpreterBase::ptr const & packet)
191 {
192  ptr pi (createInsertBefore(packet, senf::noinit));
193  pi->data().insert(pi->data().begin(),initHeadSize(),byte(0x00u));
194  pi->data().insert(pi->data().end(),initSize()-initHeadSize(),byte(0x00u));
195  pi->init();
196  return pi;
197 }
198 
199 template <class PacketType>
200 prefix_ typename senf::PacketInterpreter<PacketType>::ptr
201 senf::PacketInterpreter<PacketType>::createInsertBefore(PacketInterpreterBase::ptr const & packet,
202  senf::NoInit_t)
203 {
204  return create(&packet->impl(),packet->data().begin(),packet->data().end(),packet);
205 }
206 
207 //-/////////////////////////////////////////////////////////////////////////////////////////////////
208 // private members
209 
210 // virtual interface
211 
212 template <class PacketType>
213 prefix_ senf::PacketInterpreterBase::optional_range
214 senf::PacketInterpreter<PacketType>::v_nextPacketRange()
215 {
216  return type::nextPacketRange(ConcretePacket<PacketType>(ptr(this)));
217 }
218 
219 template <class PacketType>
220 prefix_ senf::PacketInterpreterBase::ptr
221 senf::PacketInterpreter<PacketType>::v_appendClone(detail::PacketImpl * impl, iterator base,
222  iterator new_base)
223 {
224  return create(impl,
225  boost::next(new_base,std::distance(base,begin())),
226  boost::next(new_base,std::distance(base,end())),
227  Append);
228 }
229 
230 template <class PacketType>
231 prefix_ senf::PacketInterpreterBase::ptr
232 senf::PacketInterpreter<PacketType>::v_appendClone(detail::PacketImpl * impl, range r)
233 {
234  return create(impl, r.begin(), r.end(), Append);
235 }
236 
237 template <class PacketType>
238 prefix_ void senf::PacketInterpreter<PacketType>::v_finalize()
239 {
240  type::finalize(ConcretePacket<PacketType>(ptr(this)));
241 }
242 
243 template <class PacketType>
244 prefix_ void senf::PacketInterpreter<PacketType>::v_dump(std::ostream & os)
245 {
246  type::dump(ConcretePacket<PacketType>(ptr(this)),os);
247 }
248 
249 template <class PacketType>
250 prefix_ senf::TypeIdValue senf::PacketInterpreter<PacketType>::v_type()
251 {
252  return typeIdValue< ConcretePacket<PacketType> >();
253 }
254 
255 template <class PacketType>
256 prefix_ senf::PacketInterpreterBase::factory_t
257 senf::PacketInterpreter<PacketType>::v_factory()
258 {
259  return factory();
260 }
261 
262 template <class PacketType>
263 prefix_ senf::PacketInterpreterBase::factory_t
264 senf::PacketInterpreter<PacketType>::v_nextPacketType()
265 {
266  return type::nextPacketType(ConcretePacket<PacketType>(ptr(this)));
267 }
268 
269 
270 //-/////////////////////////////////////////////////////////////////////////////////////////////////
271 // senf::PacketInterpreterBase::Factory
272 
273 template <class ForwardReadableRange>
274 prefix_ senf::PacketInterpreterBase::ptr
275 senf::PacketInterpreterBase::Factory::create(ForwardReadableRange const & range)
276  const
277 {
278  ptr pi (create(boost::size(range),senf::noinit));
279  std::copy(boost::begin(range), boost::end(range), pi->data().begin());
280  return pi;
281 }
282 
283 template <class ForwardReadableRange>
284 prefix_ senf::PacketInterpreterBase::ptr
285 senf::PacketInterpreterBase::Factory::createAfter(PacketInterpreterBase::ptr const & packet,
286  ForwardReadableRange const & range)
287  const
288 {
289  ptr pi (createAfter(packet,boost::size(range),senf::noinit));
290  std::copy(boost::begin(range), boost::end(range), pi->data().begin());
291  return pi;
292 }
293 
294 //-/////////////////////////////////////////////////////////////////////////////////////////////////
295 // senf::PacketInterpreter<PacketType>::FactoryImpl
296 
297 // Create completely new packet
298 
299 template <class PacketType>
300 prefix_ typename senf::PacketInterpreterBase::ptr
301 senf::PacketInterpreter<PacketType>::FactoryImpl::create()
302  const
303 {
304  return senf::PacketInterpreter<PacketType>::create();
305 }
306 
307 template <class PacketType>
308 prefix_ typename senf::PacketInterpreterBase::ptr
309 senf::PacketInterpreter<PacketType>::FactoryImpl::create(senf::NoInit_t)
310  const
311 {
312  return senf::PacketInterpreter<PacketType>::create(senf::noinit);
313 }
314 
315 template <class PacketType>
316 prefix_ typename senf::PacketInterpreterBase::ptr
317 senf::PacketInterpreter<PacketType>::FactoryImpl::create(size_type size)
318  const
319 {
320  return senf::PacketInterpreter<PacketType>::create(size);
321 }
322 
323 template <class PacketType>
324 prefix_ typename senf::PacketInterpreterBase::ptr
325 senf::PacketInterpreter<PacketType>::FactoryImpl::create(size_type size, senf::NoInit_t)
326  const
327 {
328  return senf::PacketInterpreter<PacketType>::create(size, senf::noinit);
329 }
330 
331 template <class PacketType>
332 prefix_ typename senf::PacketInterpreterBase::ptr
333 senf::PacketInterpreter<PacketType>::FactoryImpl::create(byte * data, size_type size,
334  size_type chunkSize, size_type offset)
335 {
336  return senf::PacketInterpreter<PacketType>::create(data, size, chunkSize, offset);
337 }
338 
339 // Create packet as new packet after a given packet
340 
341 template <class PacketType>
342 prefix_ typename senf::PacketInterpreterBase::ptr
343 senf::PacketInterpreter<PacketType>::FactoryImpl::createAfter(PacketInterpreterBase::ptr const & packet)
344  const
345 {
346  return senf::PacketInterpreter<PacketType>::createAfter(packet);
347 }
348 
349 template <class PacketType>
350 prefix_ typename senf::PacketInterpreterBase::ptr
351 senf::PacketInterpreter<PacketType>::FactoryImpl::createAfter(PacketInterpreterBase::ptr const & packet,
352  senf::NoInit_t)
353  const
354 {
355  return senf::PacketInterpreter<PacketType>::createAfter(packet,senf::noinit);
356 }
357 
358 template <class PacketType>
359 prefix_ typename senf::PacketInterpreterBase::ptr
360 senf::PacketInterpreter<PacketType>::FactoryImpl::createAfter(PacketInterpreterBase::ptr const & packet,
361  size_type size)
362  const
363 {
364  return senf::PacketInterpreter<PacketType>::createAfter(packet,size);
365 }
366 
367 template <class PacketType>
368 prefix_ typename senf::PacketInterpreterBase::ptr
369 senf::PacketInterpreter<PacketType>::FactoryImpl::createAfter(PacketInterpreterBase::ptr const & packet,
370  size_type size, senf::NoInit_t)
371  const
372 {
373  return senf::PacketInterpreter<PacketType>::createAfter(packet,size,senf::noinit);
374 }
375 
376 // Create packet as new packet (header) before a given packet
377 
378 template <class PacketType>
379 prefix_ typename senf::PacketInterpreterBase::ptr
380 senf::PacketInterpreter<PacketType>::FactoryImpl::
381 createBefore(PacketInterpreterBase::ptr const & packet)
382  const
383 {
384  return senf::PacketInterpreter<PacketType>::createBefore(packet);
385 }
386 
387 template <class PacketType>
388 prefix_ senf::PacketInterpreterBase::ptr
389 senf::PacketInterpreter<PacketType>::FactoryImpl::
390 createBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t)
391  const
392 {
393  return senf::PacketInterpreter<PacketType>::createBefore(packet,senf::noinit);
394 }
395 
396 template <class PacketType>
397 prefix_ senf::PacketInterpreterBase::ptr
398 senf::PacketInterpreter<PacketType>::FactoryImpl::
399 createInsertBefore(PacketInterpreterBase::ptr const & packet)
400  const
401 {
402  return senf::PacketInterpreter<PacketType>::createInsertBefore(packet);
403 }
404 
405 template <class PacketType>
406 prefix_ senf::PacketInterpreterBase::ptr
407 senf::PacketInterpreter<PacketType>::FactoryImpl::
408 createInsertBefore(PacketInterpreterBase::ptr const & packet, senf::NoInit_t)
409  const
410 {
411  return senf::PacketInterpreter<PacketType>::createInsertBefore(packet,senf::noinit);
412 }
413 
414 // Parse next packet in chain
415 
416 template <class PacketType>
417 prefix_ typename senf::PacketInterpreterBase::ptr
418 senf::PacketInterpreter<PacketType>::FactoryImpl::parseNext(PacketInterpreterBase::ptr const & packet, PacketInterpreterBase::optional_range const & range)
419  const
420 {
421  if (!range)
422  throw InvalidPacketChainException();
423 
424  if (packet->next())
425  packet->impl().truncateInterpreters(packet->nextP());
426 
427  return senf::PacketInterpreter<PacketType>::create(&packet->impl(),range->begin(),range->end(),Append);
428 }
429 
430 //-/////////////////////////////////////////////////////////////////////////////////////////////////
431 #undef prefix_
432 
433 
434 // Local Variables:
435 // mode: c++
436 // fill-column: 100
437 // c-file-style: "senf"
438 // indent-tabs-mode: nil
439 // ispell-local-dictionary: "american"
440 // compile-command: "scons -u test"
441 // comment-column: 40
442 // End: