// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// TODO: Add parameterless create() method
#ifndef HH_PacketRegistryImpl_
#define HH_PacketRegistryImpl_ 1
// Custom includes
#include <map>
#include <boost/utility.hpp> // for boost::noncopyable
-#include <boost/shared_ptr.hpp>
+#include <boost/optional.hpp>
+#include "Utils/Exception.hh"
+#include "PacketInterpreter.hh"
#include "Packet.hh"
//#include "PacketRegistry.mpp"
///////////////////////////////hh.p////////////////////////////////////////
-namespace satcom {
-namespace pkf {
+namespace senf {
- namespace impl { template <class key> class PacketRegistryImpl; }
+ struct PkReg_Entry
+ : public intrusive_refcount
+ {
+ virtual ~PkReg_Entry();
+ virtual PacketInterpreterBase::factory_t factory() const = 0;
+ };
+
+ namespace detail { template <class Key> class PacketRegistryImpl; }
/** \brief Packet registration facility
The PacketRegistry provides a generic facility to associate an
arbitrary key with Packets. Example keys are Ethertype or IP
protocols.
-
+
Every PacketRegistry is identified by a type tag:
\code
struct SomeTag {
typedef some_key_type key_t;
};
\endcode
- The key type can be an arbitrary valuetype. The PacketRegistry
+ The key type can be an arbitrary value type. The PacketRegistry
for this Tag can then be accessed using
<code>PacketRegistry<SomeTag>::</code>.
Normally, packet classes are registered statically and not
procedurally. To this end, the RegistrationProxy is provided:
\code
- PacketRegistry<SomeTag>::RegistrationProxy<SomePacket>
+ PacketRegistry<SomeTag>::RegistrationProxy<SomePacket>
registerSomePacket (key_of_somePacket);
\endcode
This global variable declaration will register \c SomePacket
constructor during global construction time.
The PacketRegistry's purpose is mostly to assist in
- implementing the \v v_nextInterpreter() member of packet
+ implementing the v_nextInterpreter() member of packet
facades. This is further supported by the PacketRegistryMixin
class.
+
+ \todo Add parameterless create() method
*/
template <class Tag>
class PacketRegistry
{
public:
- // TODO: This fails to work within a library since the linker will
- // remove all unused object files ...
/** \brief Statically register a packet type in a PacketRegistry
*/
- template <class OtherPacket>
+ template <class PacketType>
struct RegistrationProxy
{
RegistrationProxy(typename Tag::key_t key);
};
-
+
/** \brief Register new packet type
-
- Register \c OtherPacket in the packet registry \c Tag
+
+ Register \c PacketType in the packet registry \c Tag
under the given \c key.
\par Preconditions:
any other packet class in this registry.
The Packet must not already be registered in the registry.
- \param OtherPacket packet to regiser
+ \param PacketType packet to register
\param key key of the packet
*/
- template <class OtherPacket>
+ template <class PacketType>
static void registerPacket(typename Tag::key_t key);
/** \brief Find key of a packet
-
- Return the key of \c OtherPacket as registered in the \c
+
+ Return the key of \c PacketType as registered in the \c
Tag registry
- \param OtherPacket packet of which the key is requested
+ \param PacketType packet of which the key is requested
\returns key of the packet
\throws PacketTypeNotRegistered if the packet type is not
found in the registry.
*/
- template <class OtherPacket>
+ template <class PacketType>
static typename Tag::key_t key();
- /** \brief Create new Packet
-
- \param key Key of packet type to create instance of
- \param b begin iterator argument to Packet::create()
- \param e end iterator argment to Packet::create()
- \returns new Instance of the packet type registered under
- key or DataPacket, if the key is not registered.
- */
- template <class InputIterator>
- static Packet::ptr create(typename Tag::key_t key, InputIterator b, InputIterator e);
-
- private:
- typedef impl::PacketRegistryImpl<typename Tag::key_t> Registry;
- static Registry & registry();
-
- template <class T, class D> friend class PacketRegistryMixin;
- };
+ template <class PacketType>
+ static typename boost::optional<typename Tag::key_t> key(NoThrow_t);
- /** \brief Helper class for v_nextInterpreter implementations
+ static typename Tag::key_t key(Packet packet);
+ static typename Tag::key_t key(Packet packet, NoThrow_t);
- This class is a helper class which is to be inherited from in
- a packet facade which wants to register a new interpreter with
- the packet framework depending on a packet registry.
+ /** \brief Lookup a packet by it's key
- This mixin class provides a new registerInterpreter
- implementation which can be used besides the methods provided
- bei satcom::pkf::Packet to add a new interpreter to the
- interpreter chain.
+ Returns the packet registration registered under \a key in the \a Tag registry
- \code
- class SomePacket
- : public Packet,
- private PacketRegistryMixin<SomeTag,SomePacket>
- {
- using Packet::retgisterInterpreter;
- using PacketRegistryMixin<SomeTag,SomePacket>::registerInterpreter;
-
- virtual void v_nextInterpreter()
- {
- registerInterpreter(some_key_value, subpacket_begin, subpacket_end);
- }
- };
- \endcode
- This example is not complete, it only contains the parts
- concerned with PacketRegistryMixin.
- */
- template <class Tag, class Derived>
- class PacketRegistryMixin
- {
- protected:
- /** \brief add interpreter to interpreter chain
-
- This method is used by v_nextInterpreter() to add a new
- interpreter to the interpreter chain (see the Packet
- reference for more). Instead of specifying the type of
- packet to use as a template argument it is specified using
- the \c key value from the \c Tag registry
+ \param key Key of the packet registered
+ \returns Registration entry of the packet
+ \throws PacketTypeNotRegistered if the packet type is not found in the registry
*/
- void registerInterpreter(typename Tag::key_t key,
- Packet::iterator b, Packet::iterator e) const;
+ static PkReg_Entry const & lookup(typename Tag::key_t key);
+
+ static PkReg_Entry const * lookup(typename Tag::key_t key, NoThrow_t);
+
+ private:
+ typedef detail::PacketRegistryImpl<typename Tag::key_t> Registry;
+ static Registry & registry();
};
- struct PacketTypeNotRegistered : public std::exception
+ struct PacketTypeNotRegisteredException : public std::exception
{ virtual char const * what() const throw() { return "packet type not registered"; } };
-}}
+}
///////////////////////////////hh.e////////////////////////////////////////
//#include "PacketRegistry.cci"
\f
// Local Variables:
// mode: c++
-// c-file-style: "satcom"
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
// End: