X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FPacketType.hh;h=931ef4bf1452f0ff5824780a0524951acb765361;hb=c45c112ae88196ea8da9c5a9efb0e167196744d2;hp=88ea3bd39b3876502bc8f60660e0e81fdfc2381d;hpb=47368f306a577d1e46df69a7f729bd3893cbe5e7;p=senf.git diff --git a/Packets/PacketType.hh b/Packets/PacketType.hh index 88ea3bd..931ef4b 100644 --- a/Packets/PacketType.hh +++ b/Packets/PacketType.hh @@ -1,6 +1,8 @@ -// Copyright (C) 2007 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// $Id$ +// +// Copyright (C) 2007 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // This program is free software; you can redistribute it and/or modify @@ -21,8 +23,8 @@ /** \file \brief PacketType public header */ -#ifndef HH_PacketType_ -#define HH_PacketType_ 1 +#ifndef HH_SENF_Packets_PacketType_ +#define HH_SENF_Packets_PacketType_ 1 // Custom includes #include @@ -36,7 +38,7 @@ namespace senf { - /** \brief Helper baseclass implementing the PacketType interface + /** \brief Helper base-class implementing the PacketType interface This helper class maybe used when building a new PacketType. It provides a complete default implementations of this interface. To define a new PacketType, derive from this class and @@ -88,7 +90,7 @@ namespace senf { static void finalize(packet p) { - // optionally complete the packet by generating autogenerated information + // optionally complete the packet by generating auto-generated information // (like checksums) } @@ -100,7 +102,9 @@ namespace senf { \endcode You may leave out any one of the members (you should however always define the \c - interpreter typedef member) + packet typedef member) + + \ingroup packet_module */ struct PacketTypeBase { @@ -124,7 +128,7 @@ namespace senf { ///< Parser to parser packet fields /**< This typedef has to be set to the parser of the packet - The default is a VoidPacketParser which does not parser + The default is a VoidPacketParser which does not parse any field. */ static size_type initSize(); @@ -136,7 +140,7 @@ namespace senf { static size_type initHeadSize(); ///< Get size of new (empty) packet header /**< This function gives the index within a newly created, - empty packet where a subpacket is to be placed. + empty packet where a sub-packet is to be placed. The default implementation returns initSize(). @@ -152,7 +156,7 @@ namespace senf { packet. The new packet will have a size of at least initSize() but the size may well be larger. It is also possible for the packet to already have further - subpackets. + sub-packets. The default implementation does nothing. */ @@ -203,8 +207,8 @@ namespace senf { static void dump(packet p, std::ostream & os); ///< Dump packet data in readable form /**< The dump() function writes out a complete - representation of the packet. This is used formost for - debugging purposes. + representation of the packet. This is used for most for + debugging purposes. The default implementation does nothing. */ }; @@ -212,68 +216,152 @@ namespace senf { /** \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() and - nextPacketType() members: + 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 - pyblic senf:PacketTypeMixin + : public senf::PacketTypeBase, + public senf::PacketTypeMixin { - static interpreter::size_type initSize() - { - // This member is optional. If it is not defined, 'senf::init_size::value' - // will be returned. + typedef senf::PacketTypeMixin mixin; + typedef senf::ConcretePacket packet; + typedef SomePacketParser parser; - // 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; + using mixin::nextPacketRange; + using mixin::nextPacketType; // Only if the optional 'Registry' argument is provided + using mixin::initSize; + using mixin::init; + + 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 + // passed to the PacketTypeMixin template. + return p->typeField(); } - + + static void finalize(packet p) + { + // 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(senf::nothrow)); + + // optionally complete the packet by generating auto-generated information + // (like checksums) + } + + static void dump(packet p, std::ostream & os) + { + // Write out a readable representation of the packet for debug purposes + } + static interpreter::size_type initHeadSize() { - // This member is optional. It returns the header size if the packet has a + // This member is optional. It returns the \e fixed header size if the packet has a // trailer. return header_size; } - static registry_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 - // passed to the PacketTypeMixin template. - return i.fields().typeField(); + }; + \endcode + + Most of the members are optional, which reduces the minimal implementation of a packet to: + + \code + struct SimplePacketType + : public senf::PacketTypeBase, + public senf::PacketTypeMixin + { + typedef senf::PacketTypeMixin mixin; + typedef senf::ConcretePacket packet; + typedef SomePacketParser parser; + + using mixin::nextPacketRange; + using mixin::nextPacketType; + using mixin::initSize; + 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 void dump(packet p) { + // should always be implemented although optional } }; \endcode + + \ingroup packet_module */ template class PacketTypeMixin { public: - typedef typename Registry::key_t registry_key_t; + typedef typename Registry::key_t key_t; + typedef boost::optional optional_key_t; + + static optional_key_t key (Packet const & 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 + next packet from information stored in the current + packets header, the key() member will look up the type + of packet \a p in the registry and return it's + key. + + If either \a p is an in - valid() packet or the packet + 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. */ - static PacketInterpreterBase::optional_range nextPacketRange (Packet p); - static PacketInterpreterBase::factory_t nextPacketType (Packet p); + ///\name PacketType interface implementation + ///@{ + + static PacketInterpreterBase::optional_range nextPacketRange (Packet const & p); + static PacketInterpreterBase::factory_t nextPacketType (Packet const & p); static PacketInterpreterBase::size_type initSize (); - static void init (Packet p); + static void init (Packet const & p); + + ///@} }; +# ifndef DOXYGEN + template class PacketTypeMixin { public: - static PacketInterpreterBase::optional_range nextPacketRange (Packet p); + static PacketInterpreterBase::optional_range nextPacketRange (Packet const & p); static PacketInterpreterBase::size_type initSize (); - static void init (Packet p); + static void init (Packet const & p); }; +# endif + } ///////////////////////////////hh.e//////////////////////////////////////// +#endif +#if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketType_i_) +#define HH_SENF_Packets_PacketType_i_ #include "PacketType.cci" -//#include "PacketType.ct" +#include "PacketType.ct" #include "PacketType.cti" #endif @@ -284,4 +372,7 @@ namespace senf { // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// comment-column: 40 // End: +