Main Packet class. More...

#include <senf/Packets/Packet.hh>

Inheritance diagram for senf::Packet:

Public Types

typedef void type
 Type of the packet. More...
 
typedef senf::detail::packet::byte byte
 
typedef senf::detail::packet::size_type size_type
 
typedef senf::detail::packet::difference_type difference_type
 Unsigned type to represent packet size. More...
 
typedef PacketInterpreterBase::factory_t factory_t
 Packet factory type (see below) More...
 

Protected Member Functions

 Packet (PacketInterpreterBase::ptr const &packet)
 
PacketInterpreterBase::ptr const & ptr () const
 
PacketInterpreterBase::ptr parseNextAs (factory_t factory, PacketInterpreterBase::optional_range const &range) const
 
PacketInterpreterBase::ptr getNext (PacketInterpreterBase::optional_range const &range) const
 
Packet getLast () const
 
- Protected Member Functions inherited from senf::comparable_safe_bool< class >
 ~comparable_safe_bool ()
 
- Protected Member Functions inherited from senf::safe_bool_base
void this_type_does_not_support_comparisons () const
 
 safe_bool_base ()
 
 safe_bool_base (const safe_bool_base &)
 
safe_bool_baseoperator= (const safe_bool_base &)
 
 ~safe_bool_base ()
 

Structors and default members

 Packet ()
 Create uninitialized packet handle. More...
 
Packet clone () const
 Create copy packet. More...
 
template<class PacketType >
 Packet (ConcretePacket< PacketType > const &packet)
 Copy-construct Packet from ConcretePacket. More...
 
Packetoperator= (Packet const &)
 
 Packet (Packet const &other)
 
 Packet (Packet &&other) noexcept
 
 ~Packet ()
 
static std::int32_t const & pktCount ()
 

Interpreter chain access

Packet next () const
 Get next packet in chain. More...
 
Packet next (NoThrow_t) const
 Get next packet in chain. More...
 
template<class OtherPacket >
OtherPacket next () const
 Get next packet in chain and cast to OtherPacket. More...
 
template<class OtherPacket >
OtherPacket next (NoThrow_t) const
 Get next packet in chain and cast to OtherPacket. More...
 
template<class OtherPacket >
OtherPacket find () const
 Search chain forward for packet of type OtherPacket. More...
 
template<class OtherPacket >
OtherPacket find (NoThrow_t) const
 Search chain forward for packet of type OtherPacket. More...
 
Packet prev () const
 Get previous packet in chain. More...
 
Packet prev (NoThrow_t) const
 Get previous packet in chain. More...
 
template<class OtherPacket >
OtherPacket prev () const
 Get previous packet in chain and cast to OtherPacket. More...
 
template<class OtherPacket >
OtherPacket prev (NoThrow_t) const
 Get previous packet in chain and cast to OtherPacket. More...
 
template<class OtherPacket >
OtherPacket rfind () const
 Search chain backwards for packet of type OtherPacket. More...
 
template<class OtherPacket >
OtherPacket rfind (NoThrow_t) const
 Search chain backwards for packet of type OtherPacket. More...
 
Packet first () const
 Return first packet in chain. More...
 
template<class OtherPacket >
OtherPacket first () const
 Return first packet in chain and cast. More...
 
Packet last () const
 Return last packet in chain. More...
 
template<class OtherPacket >
OtherPacket last () const
 Return last packet in chain and cast. More...
 
template<class OtherPacket >
OtherPacket parseNextAs () const
 Interpret payload of this as OtherPacket. More...
 
Packet parseNextAs (factory_t factory) const
 Interpret payload of this as factory type packet. More...
 
template<class OtherPacket >
bool is () const
 Check, whether this packet is of the given type. More...
 
template<class OtherPacket >
OtherPacket const & as () const
 Cast current packet to the given type. More...
 
template<class OtherPacket >
OtherPacket & as ()
 
template<class OtherPacket >
OtherPacket const & as (NoThrow_t) const
 Cast current packet to the given type. More...
 
template<class OtherPacket >
OtherPacket & as (NoThrow_t)
 
Packet append (Packet const &packet) const
 Append the given packet to this packet. More...
 
void reparse () const
 Reparse the payload the packet. More...
 
template<class OtherPacket >
OtherPacket replaceAs (difference_type offset=0, difference_type tailOffset=0)
 Replace the complete packet chain with a new chain. More...
 

Data access

PacketDatadata () const
 Access the packets raw data container. More...
 
size_type size () const
 Return size of packet in bytes. More...
 

Annotations

template<class Annotation >
Annotation & annotation ()
 Get packet annotation. More...
 
template<class Annotation >
Annotation const & annotation () const
 Get packet annotation. More...
 
void clearAnnotations ()
 Clear all packet annotations. More...
 

Other methods

bool operator== (Packet const &other) const
 Check for packet identity. More...
 
bool boolean_test () const
 Check, whether the packet is valid() (not null) More...
 
void finalizeThis ()
 Update calculated fields. More...
 
template<class Other >
void finalizeTo ()
 Update calculated fields. More...
 
void finalizeTo (Packet const &other)
 Update calculated fields. More...
 
void finalizeAll ()
 Update calculated fields. More...
 
void dump (std::ostream &os, DumpPacketAnnotations_t dumpAnnotationsSwitch=dumpAnnotations) const
 Write out a printable packet representation. More...
 
TypeIdValue typeId () const
 Get type of this packet. More...
 
factory_t factory () const
 Return factory instance of this packet. More...
 
unsigned long id () const
 Unique packet id. More...
 
bool is_shared () const
 check if this packet shares data with any another packet handle. More...
 
void memDebug (std::ostream &os) const
 

Additional Inherited Members

- Public Member Functions inherited from senf::comparable_safe_bool< class >
 operator bool_type () const
 
bool operator! () const
 
- Protected Types inherited from senf::safe_bool_base
typedef void(safe_bool_base::* bool_type) () const
 

Detailed Description

Main Packet class.

Packet is the main externally visible class of the packet library. Packet is a handle into the internal packet representation. From Packet you may access the data of that specific sub-packet/header/interpreter and navigate to the neighboring sub-packets/headers/interpreters.

Packet is protocol agnostic. This class only provides non-protocol dependent members. To access the protocol specific features of a packet (like header fields) the ConcretePacket class extending Packet is provided.

Semantics

All operations accessing the data of this packet in some way will ignore any preceding packets/headers/interpreters in the chain. It does not matter, whether a given packet is taken from the middle or the beginning of the chain, all operations (except those explicitly accessing the chain of course) should work the same.

This especially includes members like clone() or append(): clone() will clone only from this packet until the end of the chain, append() will append the given packet ignoring any possibly preceding packets/headers/interpreters.

In the same way, the data() member provides an STL-sequence compatible view of the packet data. This only includes the data which is part of this packet including header, trailer and payload but not the headers or trailers of packets before this packet in the packet/header/interpreter chain (nonetheless, this data overlaps with the data of other packets).

Several members are member templates taking an OtherPacket template parameter. This parameter must be the ConcretePacket instantiation associated with some concrete packet type (protocol). For each implemented protocol, typedefs should be provided for these instantiations (Example: EthernetPacket is a typedef for ConcretePacket < EthernetPacketType >).

See also
ConcretePacket for the type specific interface
PacketData for the sequence interface
The PacketParser facility for a specification of the parser interface

Definition at line 131 of file Packet.hh.

Member Typedef Documentation

◆ byte

Definition at line 140 of file Packet.hh.

◆ difference_type

Unsigned type to represent packet size.

Definition at line 142 of file Packet.hh.

◆ factory_t

Packet factory type (see below)

Definition at line 144 of file Packet.hh.

◆ size_type

◆ type

typedef void senf::Packet::type

Type of the packet.

Definition at line 139 of file Packet.hh.

Constructor & Destructor Documentation

◆ Packet() [1/5]

senf::Packet::Packet ( )

Create uninitialized packet handle.

An uninitialized handle is in - valid(). It does not allow any operation except assignment and checking for validity.

◆ Packet() [2/5]

template<class PacketType >
senf::Packet::Packet ( ConcretePacket< PacketType > const &  packet)

Copy-construct Packet from ConcretePacket.

This constructor allows to convert an arbitrary ConcretePacket into a general Packet, losing the protocol specific interface.

◆ Packet() [3/5]

senf::Packet::Packet ( Packet const &  other)

◆ Packet() [4/5]

senf::Packet::Packet ( Packet &&  other)
noexcept

◆ ~Packet()

senf::Packet::~Packet ( )

◆ Packet() [5/5]

senf::Packet::Packet ( PacketInterpreterBase::ptr const &  packet)
explicitprotected

Member Function Documentation

◆ annotation() [1/2]

template<class Annotation >
Annotation& senf::Packet::annotation ( )

Get packet annotation.

This member will retrieve an arbitrary packet annotation. Every annotation is identified by a unique Annotation type. This type should always be a struct.

struct MyAnnotation {
int value;
};
senf::Packet p (...);
p.annotation<MyAnnotation>().value = 1;
                                         Annotations are shared by all headers / interpreters
                                         within a single packet chain.

                                         If an annotation is \e not a POD type (more
                                         specifically, if it's constructor or destructor is not
                                         trivial including base classes and members), the \a
                                         Annotation type \e must inherit from
                                         senf::ComplexAnnotation. Failing to follow this rule
                                         will result in undefined behavior and will probably
                                         lead to a program crash.
struct MyStringAnnotation : senf::ComplexAnnotation {
std::string value;
};

(This type is not POD since std::string is not POD)

See also
Annotations
Implementation note:
The annotation system is implemented quite efficiently since annotations are stored within a packet embedded vector of fixed size (the size is determined automatically at runtime by the number of different annotations used). Additionally, non-complex small annotations require no additional memory management (new / delete).
Idea:
Pool the annotation vectors: In the destructor swap the vector into a vector graveyard (swapping two vectors is an O(1) no allocation operation). In the constructor, if there is a vector in the graveyard, swap it in from there. Of course, it would be better to do away with the vector and just allocate the space together with the packet but that looks quite complicated to do ... especially considering that the packetimpl itself uses a pool.

◆ annotation() [2/2]

template<class Annotation >
Annotation const& senf::Packet::annotation ( ) const

Get packet annotation.

See also
annotation()

◆ append()

Packet senf::Packet::append ( Packet const &  packet) const

Append the given packet to this packet.

This operation will replace the payload section of this packet with packet. This operation will replace the packet chain after this packet with a clone of packet and will replace the raw data of the payload of this with the raw data of packet. this packet will not share any data with packet.

Returns
Packet handle to the cloned packet, placed after this in the packet/header/interpreter chain.

◆ as() [1/4]

template<class OtherPacket >
OtherPacket const& senf::Packet::as ( ) const

Cast current packet to the given type.

This operations returns a handle to the same packet header/interpreter however upcast to the given ConcretePacket type which have been instantiated before.

Exceptions
std::bad_castif the current packet is not of type OtherPacket

◆ as() [2/4]

template<class OtherPacket >
OtherPacket& senf::Packet::as ( )

◆ as() [3/4]

template<class OtherPacket >
OtherPacket const& senf::Packet::as ( NoThrow_t  ) const

Cast current packet to the given type.

This operations returns a handle to the same packet header/interpreter however upcast to the given ConcretePacket type which have been instantiated before.

Warning
You must make absolutely sure that the packet is of the given type. If not, calling this member crashes your program in a unkindly way.

◆ as() [4/4]

template<class OtherPacket >
OtherPacket& senf::Packet::as ( NoThrow_t  )

◆ boolean_test()

bool senf::Packet::boolean_test ( ) const

Check, whether the packet is valid() (not null)

◆ clearAnnotations()

void senf::Packet::clearAnnotations ( )

Clear all packet annotations.

All packet annotations will be cleared. Afterwards the annotations equates to a new created packet.

Warning
all references to existing complex annotations become invalid.

◆ clone()

Packet senf::Packet::clone ( ) const

Create copy packet.

clone() will create a complete copy of this packet. The returned packet will have the same data, annotations and packet chain. It does however not share any data with the original packet.

◆ data()

PacketData& senf::Packet::data ( ) const

Access the packets raw data container.

◆ dump()

void senf::Packet::dump ( std::ostream &  os,
DumpPacketAnnotations_t  dumpAnnotationsSwitch = dumpAnnotations 
) const

Write out a printable packet representation.

This method is provided mostly to help debugging packet problems. Each concrete packet should implement a dump method writing out all fields of the packet in a readable representation. dump() will call this member for each packet/header/interpreter in the chain from this packet up to the end of the chain.

Definition at line 59 of file Packet.cc.

◆ factory()

factory_t senf::Packet::factory ( ) const

Return factory instance of this packet.

The returned factory instance can be used to create new packets of the given type without knowing the concrete type of the packet. The value may be stored away for later use if needed.

◆ finalizeAll()

void senf::Packet::finalizeAll ( )

Update calculated fields.

The finalize() family of members will update calculated packet fields: checksums, size fields and so on. This includes any field, which can be set from other information in the packet. Each concrete packet type should document, which fields are set by finalize().

finalizeAll() will automatically process all packets/headers/interpreters from the end of the chain (the most inner packet) backwards up to this.

This call is equivalent to

p.finalizeTo(p.last())
                                         Beware, that finalizeAll() will \e not finalize any
                                         headers before \c this, it will \e only process inner
                                         headers.  

◆ finalizeThis()

void senf::Packet::finalizeThis ( )

Update calculated fields.

The finalize() family of members will update calculated packet fields: checksums, size fields and so on. This includes any field, which can be set from other information in the packet. Each concrete packet type should document, which fields are set by finalize().

finalizeThis() will only process the current header. Even if only changing fields in this protocol, depending on the protocol it may not be enough to finalize this header only. See the packet type documentation.

◆ finalizeTo() [1/2]

template<class Other >
void senf::Packet::finalizeTo ( )

Update calculated fields.

The finalize() family of members will update calculated packet fields: checksums, size fields and so on. This includes any field, which can be set from other information in the packet. Each concrete packet type should document, which fields are set by finalize().

finalizeTo() will automatically process all packets/headers/interpreters from the first occurrence of packet type Other (beginning at this packet searching forward towards deeper nested packets) backwards up to this.

This call is equivalent to

p.finalizeTo(p.next<Other>())

◆ finalizeTo() [2/2]

void senf::Packet::finalizeTo ( Packet const &  other)

Update calculated fields.

The finalize() family of members will update calculated packet fields: checksums, size fields and so on. This includes any field, which can be set from other information in the packet. Each concrete packet type should document, which fields are set by finalize().

finalizeTo(other) will automatically process all packets/headers/interpreters beginning at other backwards towards outer packets up to this.

◆ find() [1/2]

template<class OtherPacket >
OtherPacket senf::Packet::find ( ) const

Search chain forward for packet of type OtherPacket.

The search will start with the current packet.

Exceptions
InvalidPacketChainExceptionif no packet of type OtherPacket can be found.

◆ find() [2/2]

template<class OtherPacket >
OtherPacket senf::Packet::find ( NoThrow_t  ) const

Search chain forward for packet of type OtherPacket.

The search will start with the current packet.

Returns
in - valid() packet if no packet of type OtherPacket can be found.

◆ first() [1/2]

Packet senf::Packet::first ( ) const

Return first packet in chain.

◆ first() [2/2]

template<class OtherPacket >
OtherPacket senf::Packet::first ( ) const

Return first packet in chain and cast.

Exceptions
std::bad_castif the first() packet is not of type OtherPacket

◆ getLast()

senf::Packet senf::Packet::getLast ( ) const
protected

Definition at line 47 of file Packet.cc.

◆ getNext()

senf::PacketInterpreterBase::ptr senf::Packet::getNext ( PacketInterpreterBase::optional_range const &  range) const
protected

Definition at line 40 of file Packet.cc.

◆ id()

unsigned long senf::Packet::id ( ) const

Unique packet id.

Get a unique packet id. If two packets have the same id, they share the internal data representation.

◆ is()

template<class OtherPacket >
bool senf::Packet::is ( ) const

Check, whether this packet is of the given type.

◆ is_shared()

bool senf::Packet::is_shared ( ) const

check if this packet shares data with any another packet handle.

This method returns true if there is any other packet handle pointing to any header in the packet chain.

◆ last() [1/2]

Packet senf::Packet::last ( ) const

Return last packet in chain.

◆ last() [2/2]

template<class OtherPacket >
OtherPacket senf::Packet::last ( ) const

Return last packet in chain and cast.

Exceptions
std::bad_castif the last() packet is not of type OtherPacket

◆ memDebug()

void senf::Packet::memDebug ( std::ostream &  os) const

Definition at line 66 of file Packet.cc.

◆ next() [1/4]

Packet senf::Packet::next ( ) const

Get next packet in chain.

Exceptions
InvalidPacketChainExceptionif no next packet exists

◆ next() [2/4]

Packet senf::Packet::next ( NoThrow_t  ) const

Get next packet in chain.

Returns
in - valid() packet if no next packet exists

◆ next() [3/4]

template<class OtherPacket >
OtherPacket senf::Packet::next ( ) const

Get next packet in chain and cast to OtherPacket.

Exceptions
std::bad_castif the next() packet is not of type OtherPacket
InvalidPacketChainExceptionif no next packet exists

◆ next() [4/4]

template<class OtherPacket >
OtherPacket senf::Packet::next ( NoThrow_t  ) const

Get next packet in chain and cast to OtherPacket.

Returns
in - valid() packet if no next packet exists or if next() packet is not of type OtherPacket

◆ operator=()

Packet& senf::Packet::operator= ( Packet const &  )

◆ operator==()

bool senf::Packet::operator== ( Packet const &  other) const

Check for packet identity.

Two packet handles compare equal if they really are the same packet header in the same packet chain.

◆ parseNextAs() [1/3]

template<class OtherPacket >
OtherPacket senf::Packet::parseNextAs ( ) const

Interpret payload of this as OtherPacket.

parseNextAs() will throw away the packet chain after the current packet if necessary. It will then parse the payload section of this packet as given by OtherPacket. The new packet is added to the chain after this.

Returns
new packet instance sharing the same data and placed after this packet in the chain.
Exceptions
InvalidPacketChainExceptionif no next packet header is allowed (viz. nextPacketRange() of the the current PacketType returns no_range() )

◆ parseNextAs() [2/3]

Packet senf::Packet::parseNextAs ( factory_t  factory) const

Interpret payload of this as factory type packet.

parseNextAs() will throw away the packet chain after the current packet if necessary. It will then parse the payload section of this packet as given by factory. The new packet is added to the chain after this.

Returns
new packet instance sharing the same data and placed after this packet in the chain.
Exceptions
InvalidPacketChainExceptionif no next packet header is allowed (viz. nextPacketRange() of the the current PacketType returns no_range() )

◆ parseNextAs() [3/3]

PacketInterpreterBase::ptr senf::Packet::parseNextAs ( factory_t  factory,
PacketInterpreterBase::optional_range const &  range 
) const
protected

◆ pktCount()

std::int32_t const & senf::Packet::pktCount ( )
static

Definition at line 30 of file Packet.cc.

◆ prev() [1/4]

Packet senf::Packet::prev ( ) const

Get previous packet in chain.

Exceptions
InvalidPacketChainExceptionif no previous packet exists

◆ prev() [2/4]

Packet senf::Packet::prev ( NoThrow_t  ) const

Get previous packet in chain.

Returns
in - valid() packet if no previous packet exists

◆ prev() [3/4]

template<class OtherPacket >
OtherPacket senf::Packet::prev ( ) const

Get previous packet in chain and cast to OtherPacket.

Exceptions
std::bad_cast,ifthe previous packet is not of type OtherPacket
InvalidPacketChainExceptionif no previous packet exists

◆ prev() [4/4]

template<class OtherPacket >
OtherPacket senf::Packet::prev ( NoThrow_t  ) const

Get previous packet in chain and cast to OtherPacket.

Returns
in - valid() packet if no previous packet exists or if the previous packet is not of type OtherPacket

◆ ptr()

PacketInterpreterBase::ptr const& senf::Packet::ptr ( ) const
protected

◆ reparse()

void senf::Packet::reparse ( ) const

Reparse the payload the packet.

This member will throw away the packet chain after the current packet. The payload will be reparsed automatically when calling next()

◆ replaceAs()

template<class OtherPacket >
OtherPacket senf::Packet::replaceAs ( difference_type  offset = 0,
difference_type  tailOffset = 0 
)

Replace the complete packet chain with a new chain.

This will invalidate the all the current packets and replace them with a new packet of the given type. If an offset is given, the new packet will be created at that offset from the start of the current packet. The new packet will not be explicitly initialized since it is expected that the data already present is to be interpreted in a different manner.

◆ rfind() [1/2]

template<class OtherPacket >
OtherPacket senf::Packet::rfind ( ) const

Search chain backwards for packet of type OtherPacket.

The search will start with the current packet.

Exceptions
InvalidPacketChainExceptionif no packet of type OtherPacket can be found.

◆ rfind() [2/2]

template<class OtherPacket >
OtherPacket senf::Packet::rfind ( NoThrow_t  ) const

Search chain backwards for packet of type OtherPacket.

The search will start with the current packet.

Returns
in - valid() packet if no packet of type OtherPacket can be found.

◆ size()

size_type senf::Packet::size ( ) const

Return size of packet in bytes.

This size does not include the size of any preceding headers/packets/interpreters. It does however include this packets payload.

◆ typeId()

TypeIdValue senf::Packet::typeId ( ) const

Get type of this packet.

This value is used e.g. in the packet registry to associate packet types with other information.

Returns
A type holding the same information as a type_info object, albeit assignable

The documentation for this class was generated from the following files: