Packet.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_Packet_
18 #define HH_SENF_Packets_Packet_ 1
19 
20 // Custom includes
21 #include <boost/operators.hpp>
22 #include <boost/utility/enable_if.hpp>
23 #include <boost/type_traits/is_integral.hpp>
24 #include <senf/Utils/Tags.hh>
25 #include <senf/Utils/safe_bool.hh>
26 #include "PacketInterpreter.hh"
27 
28 //#include "Packet.mpp"
29 //-/////////////////////////////////////////////////////////////////////////////////////////////////
30 
31 namespace senf {
32 
87  template <class PackeType> class ConcretePacket;
88 
90  //\{
91 
131  class Packet
132  : public safe_bool<Packet>,
133  public boost::equality_comparable<Packet>
134  {
135  public:
136  //-////////////////////////////////////////////////////////////////////////
137  // Types
138 
139  typedef void type;
145 
146  //-////////////////////////////////////////////////////////////////////////
148  //\{
149 
150  // default copy constructor
151  // default copy assignment
152  // default destructor
153 
154  Packet();
155 
158  Packet clone() const;
159 
164  // conversion constructors
165 
166  template <class PacketType>
167  Packet(ConcretePacket<PacketType> const & packet);
169 
173  // the below is needed to implement an 'active' Packet Handle Counter
174  Packet & operator=(Packet const &);
175  Packet(Packet const & other);
176  Packet(Packet && other) noexcept;
177  ~Packet();
178 
179 
180  static std::int32_t const & pktCount();
181 
182  //\}
183  //-////////////////////////////////////////////////////////////////////////
184 
186  //\{
187 
188  Packet next() const;
189 
191  Packet next(NoThrow_t) const;
192 
194  template <class OtherPacket> OtherPacket next() const;
196 
200  template <class OtherPacket> OtherPacket next(NoThrow_t) const;
202 
205  template <class OtherPacket> OtherPacket find() const;
207 
210  template <class OtherPacket> OtherPacket find(NoThrow_t) const;
212 
216  Packet prev() const;
217 
219  Packet prev(NoThrow_t) const;
220 
222  template <class OtherPacket> OtherPacket prev() const;
224 
228  template <class OtherPacket> OtherPacket prev(NoThrow_t) const;
230 
233  template <class OtherPacket> OtherPacket rfind() const;
235 
238  template <class OtherPacket> OtherPacket rfind(NoThrow_t) const;
240 
245  Packet first() const;
246  template <class OtherPacket> OtherPacket first() const;
248 
251  Packet last() const;
252  template <class OtherPacket> OtherPacket last() const;
254 
258  template <class OtherPacket> OtherPacket parseNextAs() const;
260 
270  Packet parseNextAs(factory_t factory) const;
272 
283  template <class OtherPacket> bool is() const;
285  template <class OtherPacket> OtherPacket const & as() const;
287 
293  template <class OtherPacket> OtherPacket & as();
294  template <class OtherPacket> OtherPacket const & as(NoThrow_t) const;
296 
303  template <class OtherPacket> OtherPacket & as(NoThrow_t);
304 
305  Packet append(Packet const & packet) const;
306 
316  void reparse() const;
317 
321  template <class OtherPacket>
322  OtherPacket replaceAs(difference_type offset=0, difference_type tailOffset=0);
324 
332  //\}
333 
335  //\{
336 
337  PacketData & data() const;
338  size_type size() const;
339 
342  //\}
343 
345  //\{
346 
347  template <class Annotation>
348  Annotation & annotation();
349 
404  template <class Annotation>
405  Annotation const & annotation() const;
406 
408  void clearAnnotations();
409 
413  //\}
414 
416  //\{
417 
418  bool operator==(Packet const & other) const;
419 
421  bool boolean_test() const;
422 
423  void finalizeThis();
424 
437  template <class Other>
438  void finalizeTo();
439 
457  void finalizeTo(Packet const & other);
458 
469  void finalizeAll();
470 
490  void dump(std::ostream & os, DumpPacketAnnotations_t dumpAnnotationsSwitch = dumpAnnotations) const;
492 
499  TypeIdValue typeId() const;
500 
504  factory_t factory() const;
505 
510  unsigned long id() const;
511 
514  bool is_shared() const;
515 
518  void memDebug(std::ostream & os) const;
519 
520  //\}
521 
522  protected:
523  explicit Packet(PacketInterpreterBase::ptr const & packet);
524 
525  PacketInterpreterBase::ptr const & ptr() const;
526 
529  Packet getLast() const;
530 
531  private:
533 
534 #ifdef SENF_DEBUG
535  static std::int32_t pktCount_;
536 #endif
537  template <class PacketType>
538  friend class ConcretePacket;
539  friend class PacketParserBase;
540  };
541 
542  std::ostream & operator<<(std::ostream & os, Packet const & packet);
543 
581  template <class PacketType>
582  class ConcretePacket
583  : public Packet
584  {
585  public:
586  //-////////////////////////////////////////////////////////////////////////
587  // Types
588 
589  typedef PacketType type;
590  typedef typename PacketType::parser Parser;
591 
592  //-////////////////////////////////////////////////////////////////////////
594  //\{
595 
596  // default copy constructor
597  // default copy assignment
598  // default destructor
599  // no conversion constructors
600 
601  ConcretePacket();
602 
606  static factory_t factory();
607 
610  // Create completely new packet
611 
612  static ConcretePacket create();
613 
615  static ConcretePacket create(senf::NoInit_t);
616 
620  static ConcretePacket create(size_type size);
621 
631 
637 #ifndef DOXYGEN
638  template <class ForwardReadableRange>
639  static ConcretePacket create(
640  ForwardReadableRange const & range,
641  typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type * = 0);
642 #else
643  template <class ForwardReadableRange>
644  static ConcretePacket create(ForwardReadableRange const & range);
646 
653 #endif
654 
655  static ConcretePacket create(byte * data, size_type size, size_type totalSize = 0u,
656  size_type offset = 0u);
658 
680  // Create packet as new packet after a given packet
681 
682  static ConcretePacket createAfter(Packet const & packet);
684 
688  static ConcretePacket createAfter(Packet const & packet, senf::NoInit_t);
690 
697  static ConcretePacket createAfter(Packet const & packet, size_type size);
699 
710  static ConcretePacket createAfter(Packet const & packet, size_type size, senf::NoInit_t);
712 
720 #ifndef DOXYGEN
721  template <class ForwardReadableRange>
722  static ConcretePacket createAfter(
723  Packet const & packet,
724  ForwardReadableRange const & range,
725  typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type * = 0);
726 #else
727  template <class ForwardReadableRange>
728  static ConcretePacket createAfter(Packet const & packet,
729  ForwardReadableRange const & range);
731 
740 #endif
741 
742  // Create packet as new packet (header) before a given packet
743 
744  static ConcretePacket createBefore(Packet const & packet);
746 
754  static ConcretePacket createBeforeNoZero(Packet const & packet);
756 
763  static ConcretePacket createBefore(Packet const & packet, senf::NoInit_t, size_type space=0,
764  size_type tailSpace=0);
766 
774  static ConcretePacket createInsertBefore(Packet const & packet);
776 
781  static ConcretePacket createInsertBefore(Packet const & packet, senf::NoInit_t);
783 
788  // Create a clone of the current packet
789 
790  ConcretePacket clone() const;
791 
792  //\}
793  //-////////////////////////////////////////////////////////////////////////
794 
795  // Field access
796 
797  struct ParserProxy
798  {
799  ParserProxy(Parser const & p) : p_ (p) {}
800  Parser * operator->() { return &p_; }
801  Parser p_;
802  };
803 
804  ParserProxy operator->() const;
805 
816  Parser parser() const;
817 
823 #ifndef DOXYGEN
824  using Packet::next;
825 
826  Packet next(NoThrow_t) const;
827  template <class OtherPacket>
828  OtherPacket next(NoThrow_t) const;
829 #endif
830 
831  private:
833 
834  ConcretePacket(typename interpreter::ptr const & packet_);
835 
836  interpreter * ptr() const;
837 
838  friend class Packet;
839  friend class PacketInterpreter<PacketType>;
840  template<class PType> friend class ConcretePacket;
841  };
842 
849  template <class PacketType, class Parser>
850  Parser operator<<(Parser target, ConcretePacket<PacketType> const & packet);
851 
852  //\}
853 
854 #ifdef SENF_CXX11_ENABLED
855 # define SENF_PACKET_PREVENT_TEMPLATE_INSTANTIATION(Packet) \
856  extern template class senf::ConcretePacket<Packet##Type>; \
857  extern template class senf::PacketInterpreter<Packet##Type>;
858 # define SENF_PACKET_INSTANTIATE_TEMPLATE(Packet) \
859  template class senf::ConcretePacket<Packet##Type>; \
860  template class senf::PacketInterpreter<Packet##Type>;
861 #else
862 # define SENF_PACKET_PREVENT_TEMPLATE_INSTANTIATION(Packet)
863 # define SENF_PACKET_INSTANTIATE_TEMPLATE(Packet)
864 #endif
865 
866 }
867 
868 //-/////////////////////////////////////////////////////////////////////////////////////////////////
869 #endif
870 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_Packet_i_)
871 #define HH_SENF_Packets_Packet_i_
872 #include "Packet.cci"
873 #include "Packet.ct"
874 #include "Packet.cti"
875 #endif
876 
877 
878 // Local Variables:
879 // mode: c++
880 // fill-column: 100
881 // c-file-style: "senf"
882 // indent-tabs-mode: nil
883 // ispell-local-dictionary: "american"
884 // compile-command: "scons -u test"
885 // comment-column: 40
886 // End:
OtherPacket replaceAs(difference_type offset=0, difference_type tailOffset=0)
Replace the complete packet chain with a new chain.
DumpPacketAnnotations_t
Packet append(Packet const &packet) const
Append the given packet to this packet.
bool operator==(Packet const &other) const
Check for packet identity.
senf::detail::packet::smart_pointer< PacketInterpreter >::ptr_t ptr
bool is_shared() const
check if this packet shares data with any another packet handle.
static std::int32_t const & pktCount()
Definition: Packet.cc:30
OtherPacket rfind() const
Search chain backwards for packet of type OtherPacket.
unspecified_keyword_type parser
std::ostream & operator<<(std::ostream &os, Packet const &packet)
Definition: Packet.cc:75
Internal: Concrete packet interpreter.
Definition: PacketImpl.hh:99
OtherPacket find() const
Search chain forward for packet of type OtherPacket.
NoInit_t
PacketData & data() const
Access the packets raw data container.
Packet last() const
Return last packet in chain.
void type
Type of the packet.
Definition: Packet.hh:139
senf::detail::packet::byte byte
Definition: Packet.hh:140
senf::detail::packet::difference_type difference_type
Unsigned type to represent packet size.
Definition: Packet.hh:142
Main Packet class.
Definition: Packet.hh:131
Protocol specific packet handle.
Definition: Packet.hh:87
Packet data STL-sequence view.
Definition: PacketData.hh:61
OtherPacket const & as() const
Cast current packet to the given type.
raw_container::size_type size_type
Definition: PacketTypes.hh:66
PacketInterpreter public header.
void clearAnnotations()
Clear all packet annotations.
Packet next() const
Get next packet in chain.
PacketType type
Definition: Packet.hh:589
void memDebug(std::ostream &os) const
Definition: Packet.cc:66
senf::detail::packet::size_type size_type
Definition: Packet.hh:141
Packet & operator=(Packet const &)
OtherPacket parseNextAs() const
Interpret payload of this as OtherPacket.
PacketType::parser Parser
Definition: Packet.hh:590
senf::detail::packet::smart_pointer< PacketInterpreterBase >::ptr_t ptr
Annotation & annotation()
Get packet annotation.
void reparse() const
Reparse the payload the packet.
PacketInterpreterBase::ptr getNext(PacketInterpreterBase::optional_range const &range) const
Definition: Packet.cc:40
NoThrow_t
void dump(std::ostream &os, DumpPacketAnnotations_t dumpAnnotationsSwitch=dumpAnnotations) const
Write out a printable packet representation.
Definition: Packet.cc:59
Packet clone() const
Create copy packet.
unsigned long id() const
Unique packet id.
PacketInterpreterBase::ptr const & ptr() const
ParserProxy(Parser const &p)
Definition: Packet.hh:799
void finalizeTo()
Update calculated fields.
Packet first() const
Return first packet in chain.
raw_container::difference_type difference_type
Definition: PacketTypes.hh:67
boost::optional< range > optional_range
size_type size() const
Return size of packet in bytes.
Parser Base class.
boost::uint8_t byte
Definition: PacketTypes.hh:60
friend class ConcretePacket
Definition: Packet.hh:538
TypeIdValue typeId() const
Get type of this packet.
void finalizeThis()
Update calculated fields.
PacketInterpreterBase::factory_t factory_t
Packet factory type (see below)
Definition: Packet.hh:144
Packet getLast() const
Definition: Packet.cc:47
void finalizeAll()
Update calculated fields.
Packet prev() const
Get previous packet in chain.
factory_t factory() const
Return factory instance of this packet.
Packet()
Create uninitialized packet handle.
bool is() const
Check, whether this packet is of the given type.
bool boolean_test() const
Check, whether the packet is valid() (not null)