4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 // Stefan Bund <stefan.bund@fokus.fraunhofer.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief PacketRegistry public header */
26 #ifndef HH_PacketRegistryImpl_
27 #define HH_PacketRegistryImpl_ 1
31 #include <boost/utility.hpp> // for boost::noncopyable
32 #include <boost/optional.hpp>
33 #include "../Utils/Exception.hh"
36 //#include "PacketRegistry.mpp"
37 ///////////////////////////////hh.p////////////////////////////////////////
41 /** \brief Registry entry
43 Value returned by a registry lookup
46 : public intrusive_refcount
48 virtual ~PkReg_Entry();
49 virtual Packet::factory_t factory() const = 0;
50 ///< Get factory of the registered packet type
53 namespace detail { template <class Key> class PacketRegistryImpl; }
55 /** \brief Packet registration facility
57 The PacketRegistry provides a generic facility to associate an arbitrary key with
58 Packets. Example keys are Ethertype or IP protocols.
60 Every PacketRegistry is identified by a type tag:
63 typedef some_key_type key_t;
66 The key type can be an arbitrary value type. The PacketRegistry for this Tag can then be
67 accessed using <code>senf::PacketRegistry<SomeTag>::</code>.
69 The PacketRegistry class has only static members and provides access to the packet
70 registry. It allows two-way lookup either by key or by packet type.
73 senf::Packet::factory_t factory (senf::PacketRegistry<SomeTag>::lookup(some_key).factory());
74 SomeTag::key_t key = PacketRegistry<SomeTag>::key<SomePacket>();
77 Packets can be registered either dynamically or statically. Dynamic:
79 // dynamic registration
80 senf::PacketRegistry<SomeTag>::registerPacket<SomePacket>(key_of_somePacket);
82 // static registration. 'registerSomePacket' is an arbitrary symbol name
83 senf::PacketRegistry<SomeTag>::RegistrationProxy<SomePacket>
84 registerSomePacket (key_of_somePacket);
87 This global variable declaration will register \a SomePacket with the \a SomeTag registry
88 under the key \a key_of_somePacket. The variable \a registerSomePacket is a dummy. It's only
89 function is to force the call of it's constructor during global construction time. This
90 static registration only works when the symbol is included into the final binary. To force
91 this inclusion, you should not put packet registrations into a library but into an object
94 \ingroup packet_module
100 /** \brief Statically register a packet type in a PacketRegistry
102 To use this class, define a global symbol in the following way:
105 senf::PacketRegistry<Tag>::RegistrationProxy<PacketType>
106 registerPacketType (key);
108 \endcode Here \a Tag is the type tag of the registry to register the packet in, \a
109 PacketType is the packet to register (this is the ConcretePacket of that packet) and \a
110 key is the key of type \c Tag::key_t under which the packet is to be registered. \a
111 registerPacketType is an arbitrary name for the global symbol.
113 template <class PacketType>
114 struct RegistrationProxy
116 RegistrationProxy(typename Tag::key_t key);
119 /** \brief Register new packet type
121 Register \a PacketType in the packet registry \a Tag under the given \a key.
123 \par Preconditions: The given \a key must be unique and not be assigned to any other
124 packet class in this registry. The Packet must not already be registered in the
127 \param PacketType ConcretePacket instantiation of packet to register
128 \param key The key of the packet
130 template <class PacketType>
131 static void registerPacket(typename Tag::key_t key);
133 /** \brief Find key of a packet type
135 Return the key of \a PacketType as registered in the \a Tag registry
137 \param PacketType packet of which the key is requested
138 \returns key of the packet
139 \throws PacketTypeNotRegistered if the packet type is not found in the registry.
141 template <class PacketType>
142 static typename Tag::key_t key();
144 /** \brief Find key of a packet type
146 Return the key of \a PacketType as registered in the \a Tag registry
148 \param PacketType packet of which the key is requested
149 \returns key of the packet wrapped in a <a
150 href="http://www.boost.org/libs/optional/doc/optional.html">boost::optional</a> or
151 an unbound optional, if the key is not found.
153 template <class PacketType>
154 static typename boost::optional<typename Tag::key_t> key(NoThrow_t);
156 /** \brief Find key of a packet
158 Return the key of \a packet, an arbitrary packet, as registered in the \a Tag registry.
160 \param packet The packet of which the key is requested
161 \returns key of the packet
162 \throws PacketTypeNotRegistered if the packet type is not found in the registry.
164 static typename Tag::key_t key(Packet packet);
166 /** \brief Find key of a packet
168 Return the key of \a packet, an arbitrary packet, as registered in the \a Tag registry.
171 packet of which the key is requested
172 \returns key of the packet wrapped in a <a
173 href="http://www.boost.org/libs/optional/doc/optional.html">boost::optional</a> or
174 an unbound optional, if the key is not found.
176 static typename boost::optional<typename Tag::key_t> key(Packet packet, NoThrow_t);
178 /** \brief Lookup a packet by it's key
180 \throws PacketTypeNotRegistered if the \a key is not found in the registry
181 \return Packet entry for given \a key
183 static PkReg_Entry const & lookup(typename Tag::key_t key);
185 /** \brief Lookup a packet by it's key
186 \return Pointer to packet entry for given \a key or 0, if the key is not found in the
189 static PkReg_Entry const * lookup(typename Tag::key_t key, NoThrow_t);
192 typedef detail::PacketRegistryImpl<typename Tag::key_t> Registry;
193 static Registry & registry();
196 /** \brief Entry not found in registry
198 This exception is signaled whenever a throwing lookup operation fails.
200 struct PacketTypeNotRegisteredException : public std::exception
201 { virtual char const * what() const throw() { return "packet type not registered"; } };
205 ///////////////////////////////hh.e////////////////////////////////////////
207 #if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketRegistryImpl_i_)
208 #define HH_PacketRegistryImpl_i_
209 //#include "PacketRegistry.cci"
210 #include "PacketRegistry.ct"
211 #include "PacketRegistry.cti"
218 // c-file-style: "senf"
219 // indent-tabs-mode: nil
220 // ispell-local-dictionary: "american"
221 // compile-command: "scons -u test"
222 // comment-column: 40