4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.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_SENF_Packets_PacketRegistry_
27 #define HH_SENF_Packets_PacketRegistry_ 1
31 #include <boost/utility.hpp> // for boost::noncopyable
32 #include <boost/optional.hpp>
33 #include <boost/preprocessor/cat.hpp>
34 #include <senf/Utils/Exception.hh>
37 #include "PacketRegistry.ih"
38 //#include "PacketRegistry.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
43 /** \brief %Packet registration facility
45 The %PacketRegistry provides a generic facility to associate an arbitrary key with
46 Packets. Example keys are Ethertype or IP protocols.
48 Every %PacketRegistry is identified by a type tag:
51 typedef some_key_type key_t;
54 The key type can be an arbitrary value type. The %PacketRegistry for this Tag can then be
55 accessed using <code>senf::PacketRegistry<SomeTag>::</code>.
57 The %PacketRegistry class has only static members and provides access to the packet
58 registry. It allows two-way lookup either by key or by packet type.
61 senf::Packet::factory_t factory (senf::PacketRegistry<SomeTag>::lookup(some_key).factory());
62 SomeTag::key_t key = PacketRegistry<SomeTag>::key<SomePacket>();
65 Packets can be registered either dynamically or statically. Dynamic:
67 // dynamic registration
68 senf::PacketRegistry<SomeTag>::registerPacket<SomePacket>(key_of_somePacket);
70 // static registration. 'registerSomePacket' is an arbitrary symbol name
71 senf::PacketRegistry<SomeTag>::RegistrationProxy<SomePacket>
72 registerSomePacket (key_of_somePacket);
75 This global variable declaration will register \a SomePacket with the \a SomeTag registry
76 under the key \a key_of_somePacket. The variable \a registerSomePacket is a dummy. It's only
77 function is to force the call of it's constructor during global construction time. This
78 static registration only works when the symbol is included into the final binary. To force
79 this inclusion, you should not put packet registrations into a library but into an object
82 To simplify static registration the SENF_PACKET_REGISTRY_REGISTER macro can be used:
84 SENF_PACKET_REGISTRY_REGISTER(SomeTag, SomePacket, key_of_somePacket);
87 \ingroup packet_module
93 typedef typename detail::PacketRegistryImpl<typename Tag::key_t>::iterator iterator;
94 typedef typename detail::PacketRegistryImpl<typename Tag::key_t>::Entry Entry;
96 /** \brief Statically register a packet type in a PacketRegistry
98 To use this class, define a global symbol in the following way:
101 senf::PacketRegistry<Tag>::RegistrationProxy<PacketType>
102 registerPacketType (key);
104 \endcode Here \a Tag is the type tag of the registry to register the packet in, \a
105 PacketType is the packet to register (this is the ConcretePacket of that packet) and \a
106 key is the key of type \c Tag::key_t under which the packet is to be registered. \a
107 registerPacketType is an arbitrary name for the global symbol.
109 template <class PacketType>
110 struct RegistrationProxy
112 RegistrationProxy(typename Tag::key_t key);
113 ~RegistrationProxy();
116 /** \brief Register new packet type
118 Register \a PacketType in the packet registry \a Tag under the given \a key.
121 The given \a key must be unique and not be assigned to any other
122 packet class in this registry. The %Packet must not already be registered in the
125 \tparam PacketType ConcretePacket instantiation of packet to register
126 \param key The key of the packet
128 template <class PacketType>
129 static void registerPacket(typename Tag::key_t key);
131 template <class PacketType>
132 static void unregisterPacket();
133 static void unregisterPacket(typename Tag::key_t key);
135 /** \brief Find key of a packet type
137 Return the key of \a PacketType as registered in the \a Tag registry
139 \tparam PacketType packet of which the key is requested
140 \returns key of the packet
141 \throws PacketTypeNotRegistered if the packet type is not found in the registry.
143 template <class PacketType>
144 static typename Tag::key_t key();
146 /** \brief Find key of a packet type
148 Return the key of \a PacketType as registered in the \a Tag registry
150 \tparam PacketType packet of which the key is requested
151 \returns key of the packet wrapped in a <a
152 href="http://www.boost.org/libs/optional/doc/optional.html">boost::optional</a> or
153 an unbound optional, if the key is not found.
155 template <class PacketType>
156 static typename boost::optional<typename Tag::key_t> key(NoThrow_t);
158 /** \brief Find key of a packet
160 Return the key of \a packet, an arbitrary packet, as registered in the \a Tag registry.
162 \param packet The packet of which the key is requested
163 \returns key of the packet
164 \throws PacketTypeNotRegistered if the packet type is not found in the registry.
166 static typename Tag::key_t key(Packet const & packet);
168 /** \brief Find key of a packet
170 Return the key of \a packet, an arbitrary packet, as registered in the \a Tag registry.
172 \param packet The packet of which the key is requested
173 \returns key of the packet wrapped in a <a
174 href="http://www.boost.org/libs/optional/doc/optional.html">boost::optional</a> or
175 an unbound optional, if the key is not found.
177 static typename boost::optional<typename Tag::key_t> key(Packet const & packet, NoThrow_t);
179 /** \brief Lookup a packet by it's key
181 \throws PacketTypeNotRegistered if the \a key is not found in the registry
182 \return %Packet entry for given \a key
184 static Entry const & lookup(typename Tag::key_t key);
186 /** \brief Lookup a packet by it's key
187 \return Pointer to packet entry for given \a key or 0, if the key is not found in the
190 static Entry const * lookup(typename Tag::key_t key, NoThrow_t);
192 /** \brief Beginning iterator to list of registered keys
194 static iterator begin();
196 /** \brief End iterator to list of registered keys
198 static iterator end();
201 typedef detail::PacketRegistryImpl<typename Tag::key_t> Registry;
202 static Registry & registry();
205 /** \brief Statically add an entry to a packet registry
207 This macro will declare an anonymous global variable in such a way, that constructing this
208 variable will add a registration to the given packet registry.
210 \ingroup packet_module
213 # define SENF_PACKET_REGISTRY_REGISTER( registry, value, type ) \
215 senf::PacketRegistry< registry >::RegistrationProxy< type > \
216 BOOST_PP_CAT(packetRegistration_, __LINE__) ( value ); \
219 /** \brief Dump all packet registries
221 This command will dump all packet registries to the given stream. This is to help debugging
222 registration problems.
224 void dumpPacketRegistries(std::ostream & os);
226 /** \brief Entry not found in registry
228 This exception is signaled whenever a throwing lookup operation fails.
230 struct PacketTypeNotRegisteredException : public senf::Exception
231 { PacketTypeNotRegisteredException() : senf::Exception("packet type not registered") {} };
235 ///////////////////////////////hh.e////////////////////////////////////////
237 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketRegistry_i_)
238 #define HH_SENF_Packets_PacketRegistry_i_
239 #include "PacketRegistry.cci"
240 #include "PacketRegistry.ct"
241 #include "PacketRegistry.cti"
248 // c-file-style: "senf"
249 // indent-tabs-mode: nil
250 // ispell-local-dictionary: "american"
251 // compile-command: "scons -u test"
252 // comment-column: 40