/** \file
\brief PacketRegistry public header */
-#ifndef HH_PacketRegistryImpl_
-#define HH_PacketRegistryImpl_ 1
+#ifndef HH_SENF_Packets_PacketRegistry_
+#define HH_SENF_Packets_PacketRegistry_ 1
// Custom includes
#include <map>
#include <boost/utility.hpp> // for boost::noncopyable
#include <boost/optional.hpp>
+#include <boost/preprocessor/cat.hpp>
#include "../Utils/Exception.hh"
#include "Packet.hh"
+#include "PacketRegistry.ih"
//#include "PacketRegistry.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
- /** \brief Registry entry
+ /** \brief %Packet registration facility
- Value returned by a registry lookup
- */
- struct PkReg_Entry
- : public intrusive_refcount
- {
- virtual ~PkReg_Entry();
- virtual Packet::factory_t factory() const = 0;
- ///< Get factory of the registered packet type
- };
-
- namespace detail { template <class Key> class PacketRegistryImpl; }
-
- /** \brief Packet registration facility
-
- The PacketRegistry provides a generic facility to associate an arbitrary key with
+ 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:
+ 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 value type. The PacketRegistry for this Tag can then be
+ The key type can be an arbitrary value type. The %PacketRegistry for this Tag can then be
accessed using <code>senf::PacketRegistry<SomeTag>::</code>.
- The PacketRegistry class has only static members and provides access to the packet
- registry. It allows two-way lookup either by key or by packet type.
+ The %PacketRegistry class has only static members and provides access to the packet
+ registry. It allows two-way lookup either by key or by packet type.
\code
senf::Packet::factory_t factory (senf::PacketRegistry<SomeTag>::lookup(some_key).factory());
static registration only works when the symbol is included into the final binary. To force
this inclusion, you should not put packet registrations into a library but into an object
file.
-
+
\ingroup packet_module
*/
template <class Tag>
class PacketRegistry
{
public:
+ typedef typename detail::PacketRegistryImpl<typename Tag::key_t>::iterator iterator;
+
/** \brief Statically register a packet type in a PacketRegistry
To use this class, define a global symbol in the following way:
Register \a PacketType in the packet registry \a Tag under the given \a key.
- \par Preconditions: The given \a key must be unique and not be assigned to any other
- packet class in this registry. The Packet must not already be registered in the
+ \par Preconditions:
+ The given \a key must be unique and not be assigned to any other
+ packet class in this registry. The %Packet must not already be registered in the
registry.
- \param PacketType ConcretePacket instantiation of packet to register
+ \tparam PacketType ConcretePacket instantiation of packet to register
\param key The key of the packet
*/
template <class PacketType>
Return the key of \a PacketType as registered in the \a Tag registry
- \param PacketType packet of which the key is requested
+ \tparam 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.
*/
Return the key of \a PacketType as registered in the \a Tag registry
- \param PacketType packet of which the key is requested
+ \tparam PacketType packet of which the key is requested
\returns key of the packet wrapped in a <a
href="http://www.boost.org/libs/optional/doc/optional.html">boost::optional</a> or
an unbound optional, if the key is not found.
\param packet The packet of which the key is requested
\returns key of the packet
\throws PacketTypeNotRegistered if the packet type is not found in the registry.
- */
- static typename Tag::key_t key(Packet packet);
+ */
+ static typename Tag::key_t key(Packet const & packet);
/** \brief Find key of a packet
Return the key of \a packet, an arbitrary packet, as registered in the \a Tag registry.
- \param packet The
-packet of which the key is requested
+ \param packet The packet of which the key is requested
\returns key of the packet wrapped in a <a
href="http://www.boost.org/libs/optional/doc/optional.html">boost::optional</a> or
an unbound optional, if the key is not found.
*/
- static typename boost::optional<typename Tag::key_t> key(Packet packet, NoThrow_t);
+ static typename boost::optional<typename Tag::key_t> key(Packet const & packet, NoThrow_t);
/** \brief Lookup a packet by it's key
-
+
\throws PacketTypeNotRegistered if the \a key is not found in the registry
- \return Packet entry for given \a key
+ \return %Packet entry for given \a key
*/
static PkReg_Entry const & lookup(typename Tag::key_t key);
*/
static PkReg_Entry const * lookup(typename Tag::key_t key, NoThrow_t);
+ /** \brief Beginning iterator to list of registered keys
+ */
+ static iterator begin();
+
+ /** \brief End iterator to list of registered keys
+ */
+ static iterator end();
+
private:
typedef detail::PacketRegistryImpl<typename Tag::key_t> Registry;
static Registry & registry();
\hideinitializer
*/
-# define SENF_PACKET_REGISTRY_REGISTER( registry, value, type ) \
- namespace { \
- senf::PacketRegistry< registry >::RegistrationProxy< type > \
- packetRegistration_ ## __LINE__ ( value ); \
+# define SENF_PACKET_REGISTRY_REGISTER( registry, value, type ) \
+ namespace { \
+ senf::PacketRegistry< registry >::RegistrationProxy< type > \
+ BOOST_PP_CAT(packetRegistration_, __LINE__) ( value ); \
}
+ /** \brief Dump all packet registries
+
+ This command will dump all packet registries to the given stream. This is to help debugging
+ registration problems.
+ */
+ void dumpPacketRegistries(std::ostream & os);
+
/** \brief Entry not found in registry
This exception is signaled whenever a throwing lookup operation fails.
*/
- struct PacketTypeNotRegisteredException : public std::exception
- { virtual char const * what() const throw() { return "packet type not registered"; } };
+ struct PacketTypeNotRegisteredException : public senf::Exception
+ { PacketTypeNotRegisteredException() : senf::Exception("packet type not registered"){} };
}
///////////////////////////////hh.e////////////////////////////////////////
#endif
-#if !defined(HH_Packets__decls_) && !defined(HH_PacketRegistryImpl_i_)
-#define HH_PacketRegistryImpl_i_
-//#include "PacketRegistry.cci"
+#if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketRegistry_i_)
+#define HH_SENF_Packets_PacketRegistry_i_
+#include "PacketRegistry.cci"
#include "PacketRegistry.ct"
#include "PacketRegistry.cti"
#endif
-\f
+
// Local Variables:
// mode: c++
// fill-column: 100