///@}
+ ///\name Annotations
+ ///@{
+
+ template <class Annotation>
+ Annotation & annotation(); ///< Get packet annotation
+ /**< This member will retrieve an arbitrary packet
+ annotation. Every annotation is identified by a unique
+ \a Annotation type. This type should \e always be a \c
+ struct.
+
+ \code
+ struct MyAnnotation {
+ int value;
+ };
+
+ senf::Packet p (...);
+
+ p.annotation<MyAnnotation>().value = 1;
+ \endcode
+
+ 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), 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.
+
+ \code
+ struct MyStringAnnotation : senf::ComplexAnnotation {
+ std::string value;
+ };
+ \endcode
+
+ \implementation 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 (\c new /
+ \c 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.
+ */
+
+ ///@}
+
///\name Other methods
///@{
when using a packet in a boolean context. */
void finalizeThis(); ///< Update calculated fields
- /**< This call will update all calculated fields of the
- packet. This includes checksums, payload size fields or
- other fields, which can be set from other information
- in the packet. Each concrete packet type should
- document, which fields are set by finalize().
+ /**< The finalize() fammily 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 \e only process the current
header. Even if only changing fields in this protocol,
template <class Other>
void finalizeTo(); ///< Update calculated fields
- /**< This call will update all calculated fields of the
- packet. This includes checksums, payload size fields or
- other fields, which can be set from other information
- in the packet. Each concrete packet type should
- document, which fields are set by finalize().
+ /**< The finalize() fammily 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 \a Other backwards up to \c this. */
+ packets/headers/interpreters from the \e first
+ occurrence of packet type \a Other (beginning at \c
+ this packet searching forward towards deeper nested
+ packets) backwards up to \c this.
+
+ This call is equivalent to
+ \code
+ p.finalizeTo(p.next<Other>())
+ \endcode */
void finalizeTo(Packet other); ///< Update calculated fields
- /**< This call will update all calculated fields of the
- packet. This includes checksums, payload size fields or
- other fields, which can be set from other information
- in the packet. Each concrete packet type should
- document, which fields are set by finalize().
+ /**< The finalize() fammily 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(other) will automatically process all
- packets/headers/interpreters from \a other backwards up
- to \c this. */
+ finalizeTo(other) will automatically process all
+ packets/headers/interpreters beginning at \a other
+ backwards towards outer packets up to \c this. */
void finalizeAll(); ///< Update calculated fields
- /**< This call will update all calculated fields of the
- packet. This includes checksums, payload size fields or
- other fields, which can be set from other information
- in the packet. Each concrete packet type should
- document, which fields are set by finalize().
+ /**< The finalize() fammily 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
- backwards up to \c this. */
+ (the most inner packet) backwards up to \c this.
+
+ This call is equivalent to
+ \code
+ p.finalizeTo(p.last())
+ \endcode
+
+ Beware, that finalizeAll() will \e not finalize any
+ headers before \c this, it will \e only process inner
+ headers. */
void dump(std::ostream & os) const; ///< Write out a printable packet representation
/**< This method is provided mostly to help debugging packet