// $Id$
//
-// Copyright (C) 2007
-// Fraunhofer Institute for Open Communication Systems (FOKUS)
-// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// Custom includes
#include <boost/operators.hpp>
-
+#include <boost/utility.hpp>
+#include <boost/type_traits/is_integral.hpp>
#include "../Utils/Exception.hh"
+#include "../Utils/Tags.hh"
#include "../Utils/safe_bool.hh"
#include "PacketInterpreter.hh"
/** \defgroup packet_module Packet Handling
- The basic groundwork of the Packet library is the packet handling:
+ The basic groundwork of the %Packet library is the packet handling:
\li The packet classes provide access to a chain of packet headers (more generically called
interpreters).
///\addtogroup packet_module
///@{
- /** \brief Main Packet class
+ /** \brief 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
+ %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
+ %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.
+ class extending %Packet is provided.
\section packet_semantics Semantics
\ref ConcretePacket < \ref EthernetPacketType >).
\see
- \ref ConcretePacket for the type specific interface\n
+ \ref ConcretePacket for the %type specific interface\n
\ref PacketData for the sequence interface\n
\ref packetparser for a specification of the parser interface
*/
///< Unsigned type to represent packet size
typedef PacketInterpreterBase::factory_t factory_t; ///< Packet factory type (see below)
- enum NoInit_t { noinit }; ///< Special argument flag
- /**< Used in some ConcretePacket constructors */
-
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///@{
Packet next() const;
///< Get next packet in chain
- /**< \returns in - valid() packet, if no next packet
+ /**< \throws InvalidPacketChainException if no next packet
+ exists */
+ Packet next(NoThrow_t) const;
+ ///< Get next packet in chain
+ /**< \returns in - valid() packet if no next packet
exists */
template <class OtherPacket> OtherPacket next() const;
///< Get next packet in chain and cast to \a OtherPacket
/**< \throws std::bad_cast if the next() packet is not of
type \a OtherPacket
- \returns in - valid() packet, if no next packet
+ \throws InvalidPacketChainException if no next packet
+ exists */
+ template <class OtherPacket> OtherPacket next(NoThrow_t) const;
+ ///< Get next packet in chain and cast to \a OtherPacket
+ /**< \throws std::bad_cast if the next() packet is not of
+ type \a OtherPacket
+ \returns in - valid() packet if no next packet
exists */
template <class OtherPacket> OtherPacket find() const;
///< Search chain forward for packet of type \a OtherPacket
/**< The search will start with the current packet.
- \returns in - valid() packet, if no packet of type \a
+ \throws InvalidPacketChainException if no packet of
+ type \a OtherPacket can be found. */
+ template <class OtherPacket> OtherPacket find(NoThrow_t) const;
+ ///< Search chain forward for packet of type \a OtherPacket
+ /**< The search will start with the current packet.
+ \returns in - valid() packet if no packet of type \a
OtherPacket can be found. */
Packet prev() const;
///< Get previous packet in chain
- /**< \returns in - valid() packet, if no previous packet
+ /**< \throws InvalidPacketChainException if no previous
+ packet exists */
+ Packet prev(NoThrow_t) const;
+ ///< Get previous packet in chain
+ /**< \returns in - valid() packet if no previous packet
exists */
template <class OtherPacket> OtherPacket prev() const;
///< Get previous packet in chain and cast to \a OtherPacket
/**< \throws std::bad_cast, if the previous packet is not of
type \a OtherPacket
- \returns in - valid() packet, if no previous packet
+ \throws InvalidPacketChainException if no previous
+ packet exists */
+ template <class OtherPacket> OtherPacket prev(NoThrow_t) const;
+ ///< Get previous packet in chain and cast to \a OtherPacket
+ /**< \throws std::bad_cast, if the previous packet is not of
+ type \a OtherPacket
+ \returns in - valid() packet if no previous packet
exists */
template <class OtherPacket> OtherPacket rfind() const;
///< Search chain backwards for packet of type \a OtherPacket
/**< The search will start with the current packet.
- \returns in - valid() packet, if no packet of type \a
+ \throws InvalidPacketChainException if no packet of
+ type \a OtherPacket can be found. */
+ template <class OtherPacket> OtherPacket rfind(NoThrow_t) const;
+ ///< Search chain backwards for packet of type \a OtherPacket
+ /**< The search will start with the current packet.
+ \returns in - valid() packet if no packet of type \a
OtherPacket can be found. */
static ConcretePacket create(); ///< Create default initialized packet
/**< The packet will be initialized to it's default empty
state. */
- static ConcretePacket create(NoInit_t); ///< Create uninitialized empty packet
+ static ConcretePacket create(senf::NoInit_t); ///< Create uninitialized empty packet
/**< This will create a completely empty and uninitialized
packet with <tt>size() == 0</tt>.
- \param[in] noinit This parameter must always have the
+ \param[in] senf::noinit This parameter must always have the
value \c senf::noinit. */
static ConcretePacket create(size_type size); ///< Create default initialized packet
/**< This member will create a default initialized packet
\throws TruncatedPacketException if \a size is smaller
than the smallest permissible size for this type of
packet. */
- static ConcretePacket create(size_type size, NoInit_t); ///< Create uninitialized packet
+ static ConcretePacket create(size_type size, senf::NoInit_t);
+ ///< Create uninitialized packet
/**< Creates an uninitialized (all-zero) packet of the exact
given size.
\param[in] size Size of the packet to create in bytes
- \param[in] noinit This parameter must always have the
+ \param[in] senf::noinit This parameter must always have the
value \c senf::noinit. */
+#ifndef DOXYGEN
+ template <class ForwardReadableRange>
+ static ConcretePacket create(
+ ForwardReadableRange const & range,
+ typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type * = 0);
+#else
template <class ForwardReadableRange>
static ConcretePacket create(ForwardReadableRange const & range);
///< Create packet from given data
\param[in] range <a
href="http://www.boost.org/libs/range/index.html">Boost.Range</a>
of data to construct packet from. */
+#endif
// Create packet as new packet after a given packet
state. It will be appended as next header/interpreter
after \a packet in that packets interpreter chain.
\param[in] packet Packet to append new packet to. */
- static ConcretePacket createAfter(Packet packet, NoInit_t);
+ static ConcretePacket createAfter(Packet packet, senf::NoInit_t);
///< Create uninitialized empty packet after\a packet
/**< This will create a completely empty and uninitialized
packet with <tt>size() == 0</tt>. It will be appended
as next header/interpreter after \a packet in that
packets interpreter chain.
\param[in] packet Packet to append new packet to.
- \param[in] noinit This parameter must always have the
+ \param[in] senf::noinit This parameter must always have the
value \c senf::noinit. */
static ConcretePacket createAfter(Packet packet, size_type size);
///< Create default initialized packet after \a packet
\throws TruncatedPacketException if \a size is smaller
than the smallest permissible size for this type of
packet. */
- static ConcretePacket createAfter(Packet packet, size_type size, NoInit_t);
+ static ConcretePacket createAfter(Packet packet, size_type size, senf::NoInit_t);
///< Create uninitialized packet after \a packet
/**< Creates an uninitialized (all-zero) packet of the exact
given size. It will be appended as next
interpreter chain.
\param[in] packet Packet to append new packet to.
\param[in] size Size of the packet to create in bytes
- \param[in] noinit This parameter must always have the
+ \param[in] senf::noinit This parameter must always have the
value \c senf::noinit. */
+#ifndef DOXYGEN
+ template <class ForwardReadableRange>
+ static ConcretePacket createAfter(
+ Packet packet,
+ ForwardReadableRange const & range,
+ typename boost::disable_if< boost::is_integral<ForwardReadableRange> >::type * = 0);
+#else
template <class ForwardReadableRange>
static ConcretePacket createAfter(Packet packet,
ForwardReadableRange const & range);
\param[in] range <a
href="http://www.boost.org/libs/range/index.html">Boost.Range</a>
of data to construct packet from. */
+#endif
// Create packet as new packet (header) before a given packet
header/interpreter before \a packet in that packets
interpreter chain.
\param[in] packet Packet to prepend new packet to. */
- static ConcretePacket createBefore(Packet packet, NoInit_t);
+ static ConcretePacket createBefore(Packet packet, senf::NoInit_t);
///< Create uninitialized empty packet before \a packet
/**< Creates a completely empty and uninitialized packet. It
will be prepended as previous header/interpreter before
/ recreation ...)
\see \ref packetparser for the parser interface. */
+ Parser parser() const; ///< Access packet field parser directly
+ /**< Access the parser of the packet. This is the same
+ object returned by the operator->() operator. The
+ operator however does not allow to access this object
+ itself, only it's members.
+ \see \ref packetparser for the parser interface */
+
protected:
private: