+// $Id$
+//
// Copyright (C) 2007
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// 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
/** \brief Mixin to provide standard implementations for nextPacketRange and nextPacketType
- This mixin class simplifies the definition of simple packets with fixed-size (!) headers
- and/or trailers. For this type of Packet, this mixin provides the nextPacketRange()
- member. If you additionally provide the optional \a Registry argument, PacketTypeMixin
- provides a simple implementation of nextPacketType. When using the PacketTypeMixin, the
- implementation of a packet is simplified to:
+ This mixin class simplifies the definition of simple packets:
+
+ \li The packets consist of three sections: The header, the payload and an optional trailer.
+ \li If the packet has a trailer, both the header and the trailer must have a fixed size.
+
+ This mixin provides the nextPacketRange() member as well as initSize() and init(). If you
+ additionally provide the optional \a Registry argument, PacketTypeMixin provides a simple
+ implementation of nextPacketType().
+
+ When using the PacketTypeMixin, the implementation of a packet is simplified to:
\code
// Here 'SomeRegistryTag' is optional
struct SimplePacketType
- : public senf::PacketTypeBase
- public senf:PacketTypeMixin<SimplePacketType, SomeRegistryTag>
+ : public senf::PacketTypeBase,
+ public senf::PacketTypeMixin<SimplePacketType, SomeRegistryTag>
{
typedef senf::PacketTypeMixin<SimplePacketType, SomeRegistryTag> mixin;
typedef senf::ConcretePacket<SimplePacketType> packet;
typedef SomePacketParser parser;
using mixin::nextPacketRange;
- // Only if the optional 'Registry' argument is provided
- using mixin::nextPacketType;
- // Only if using the default implementation
+ using mixin::nextPacketType; // Only if the optional 'Registry' argument is provided
using mixin::initSize;
- // Only if using the default implementation
- using mixin::init;
-
- static interpreter::size_type initSize()
- {
- // This member is optional. If it is not defined, 'senf::init_size<parser>::value'
- // will be returned.
-
- // The value returned is the length of the header if initHeadSize() is not defined.
- // If initHeadSize is defined, this value is the combined size of the header
- // and trailer while initHeadSize() will return the size of the header only.
- return packet_size;
- }
-
- static interpreter::size_type initHeadSize()
- {
- // This member is optional. It returns the header size if the packet has a
- // trailer.
- return header_size;
- }
+ using mixin::init;
- static void init(packet p)
- {
- // This member is optional. The default implementation calls the parsers init()
- // member.
- }
-
- static registry_key_t nextPacketKey(packet p)
+ static key_t nextPacketKey(packet p)
{
// Return the key in the registry under which the next packet
// header is to be found. This member must be given if a Registry argument is
// Set the type field by querying the type of the next packet. This is an
// optional assignment: If the key is not found, the value returned by 'key'
// is an empty optional and the assignment will be skipped.
- p->typeField << key(p.next());
+ p->typeField << key(p.next(senf::nothrow));
// optionally complete the packet by generating auto-generated information
// (like checksums)
{
// Write out a readable representation of the packet for debug purposes
}
+
+ static interpreter::size_type initHeadSize()
+ {
+ // This member is optional. It returns the \e fixed header size if the packet has a
+ // trailer.
+ return header_size;
+ }
+
};
\endcode
- Most of the members are optional, which reduces the implementation of a fixed-sized header
- packet with no trailer and a simple next-packet header to
+ Most of the members are optional, which reduces the minimal implementation of a packet to:
\code
struct SimplePacketType
- : public senf::PacketTypeBase
- public senf:PacketTypeMixin<SimplePacketType, SomeRegistryTag>
+ : public senf::PacketTypeBase,
+ public senf::PacketTypeMixin<SimplePacketType, SomeRegistryTag>
{
typedef senf::PacketTypeMixin<SimplePacketType, SomeRegistryTag> mixin;
typedef senf::ConcretePacket<SimplePacketType> packet;
using mixin::nextPacketRange;
using mixin::nextPacketType;
using mixin::initSize;
- using mixin::init;
+ using mixin::init;
+
+ // 'typeField()' is one of the fields defined in the parser which holds
+ // the next-header information
+
+ static key_t nextPacketKey(packet p) { return p->typeField(); }
+ static void finalize(packet p) { p->typeField() << key(p.next(senf::nothrow)); }
- static registry_key_t nextPacketKey(packet p)
- { return p->typeField(); }
+ static void dump(packet p) {
+ // should always be implemented although optional
+ }
};
\endcode
- If needed, you may additionally add a \c finalize() member. You also should add a \c dump()
- member to help debugging but both members are optional.
-
\ingroup packet_module
*/
template <class Self, class Registry=void>
class PacketTypeMixin
{
public:
- typedef typename Registry::key_t registry_key_t;
- typedef boost::optional<registry_key_t> optional_registry_key_t;
+ typedef typename Registry::key_t key_t;
+ typedef boost::optional<key_t> optional_key_t;
- static optional_registry_key_t key (Packet p); ///< Find key of packet from registry
+ static optional_key_t key (Packet p); ///< Find key of packet from registry
/**< key() will query the registry to find the key of the
given packet. Whereas \c nextPacketKey() as implemented
by the mixin user will provide the registry key of the
type is not found in the registry, the returned
optional value will be empty. */
+ static PacketTypeBase::factory_t lookup (key_t key); ///< Lookup the key in the registry
+ /**< lookup() will query the registry and find the factory
+ for the given key. If the key cannot be found,
+ no_factory() will be returned. */
+
///\name PacketType interface implementation
///@{
#if !defined(HH_Packets__decls_) && !defined(HH_PacketType_i_)
#define HH_PacketType_i_
#include "PacketType.cci"
-//#include "PacketType.ct"
+#include "PacketType.ct"
#include "PacketType.cti"
#endif