From: g0dil Date: Mon, 11 Feb 2008 11:32:31 +0000 (+0000) Subject: Packets: Add PacketRegistry::begin()/end() and senf::dumpPacketRegistries() utility X-Git-Url: http://g0dil.de/git?p=senf.git;a=commitdiff_plain;h=f90ccec9262e178534bb86c0061ecf83e3df91b3 Packets: Add PacketRegistry::begin()/end() and senf::dumpPacketRegistries() utility Examples/Sniffer: Dump all packet registries before starting the packet capture git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@682 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Examples/Sniffer/SConscript b/Examples/Sniffer/SConscript index e30f7c9..250abc6 100644 --- a/Examples/Sniffer/SConscript +++ b/Examples/Sniffer/SConscript @@ -5,6 +5,7 @@ import SENFSCons SENFSCons.Binary(env, 'sniffer', SENFSCons.GlobSources(), LIBS = [ 'Scheduler', 'Packets', 'Socket', 'Utils' ], - OBJECTS = [ '#/Packets/DefaultBundle/DefaultBundle.o' ]); + OBJECTS = [ '#/Packets/DefaultBundle/DefaultBundle.o', + '#/Packets/MPEGDVBBundle/MPEGDVBBundle.o' ]) SENFSCons.Doxygen(env) diff --git a/Examples/Sniffer/Sniffer.cc b/Examples/Sniffer/Sniffer.cc index 0c53e5f..fbeeab4 100644 --- a/Examples/Sniffer/Sniffer.cc +++ b/Examples/Sniffer/Sniffer.cc @@ -110,6 +110,9 @@ int scheduler_main(int argc, char const * argv[]) int main(int argc, char const * argv[]) { + std::cout << "Registered packets:\n\n"; + senf::dumpPacketRegistries(std::cout); + if (argc >= 3) if (std::string(argv[1]) == "loop") return loop_main(argc,argv); diff --git a/Packets/PacketRegistry.cc b/Packets/PacketRegistry.cc index 48b76bb..366c129 100644 --- a/Packets/PacketRegistry.cc +++ b/Packets/PacketRegistry.cc @@ -34,6 +34,27 @@ prefix_ senf::PkReg_Entry::~PkReg_Entry() {} +prefix_ senf::detail::PacketRegistryImplBase::~PacketRegistryImplBase() +{} + +prefix_ void senf::detail::PacketRegistryImplBase::dump(std::ostream & os) +{ + RegistryMap::const_iterator i (registries().begin()); + RegistryMap::const_iterator const i_end (registries().end()); + for (; i!=i_end; ++i) { + os << i->first << ":\n"; + i->second->v_dump(os); + os << "\n"; + } +} + +prefix_ senf::detail::PacketRegistryImplBase::RegistryMap & +senf::detail::PacketRegistryImplBase::registries() +{ + static RegistryMap map; + return map; +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "PacketRegistry.mpp" diff --git a/Packets/PacketRegistry.cci b/Packets/PacketRegistry.cci new file mode 100644 index 0000000..2e0c48f --- /dev/null +++ b/Packets/PacketRegistry.cci @@ -0,0 +1,50 @@ +// $Id$ +// +// Copyright (C) 2008 +// 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 +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief PacketRegistry inline non-template implementation */ + +#include "PacketRegistry.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cci.p/////////////////////////////////////// + +prefix_ void senf::dumpPacketRegistries(std::ostream & os) +{ + senf::detail::PacketRegistryImplBase::dump(os); +} + +///////////////////////////////cci.e/////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/Packets/PacketRegistry.ct b/Packets/PacketRegistry.ct index 2cd02f8..f274efa 100644 --- a/Packets/PacketRegistry.ct +++ b/Packets/PacketRegistry.ct @@ -33,6 +33,9 @@ #define prefix_ ///////////////////////////////ct.p//////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +// senf::detail::PkReg_EntryImpl + template prefix_ senf::PacketInterpreterBase::factory_t senf::detail::PkReg_EntryImpl::factory() const @@ -47,6 +50,20 @@ prefix_ std::string senf::detail::PkReg_EntryImpl::name() return prettyName(typeid(PacketType)); } +/////////////////////////////////////////////////////////////////////////// +// senf::PacketRegistry + +template +prefix_ typename senf::PacketRegistry::Registry & +senf::PacketRegistry::registry() +{ + static Registry registry (prettyName(typeid(Tag))); + return registry; +} + +/////////////////////////////////////////////////////////////////////////// +// senf::detail::PacketRegistryImpl: + template template prefix_ void senf::detail::PacketRegistryImpl::registerPacket(key_t key) @@ -108,12 +125,13 @@ senf::detail::PacketRegistryImpl::lookup(key_t key, bool) return i->second.get(); } -template -prefix_ typename senf::PacketRegistry::Registry & -senf::PacketRegistry::registry() +template +prefix_ void senf::detail::PacketRegistryImpl::v_dump(std::ostream & os) { - static Registry registry; - return registry; + typename PacketMap::const_iterator i (registry_.begin()); + typename PacketMap::const_iterator const i_end (registry_.end()); + for (; i != i_end; ++i) + os << i->first << " " << i->second->name() << "\n"; } ///////////////////////////////ct.e//////////////////////////////////////// diff --git a/Packets/PacketRegistry.cti b/Packets/PacketRegistry.cti index 2f7ffd1..6de3a0c 100644 --- a/Packets/PacketRegistry.cti +++ b/Packets/PacketRegistry.cti @@ -30,6 +30,9 @@ #define prefix_ inline ///////////////////////////////PacketRegistry..p/////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +// senf::PacketRegistry::RegistrationProxy + template template prefix_ senf::PacketRegistry::RegistrationProxy:: @@ -38,6 +41,9 @@ RegistrationProxy(typename Tag::key_t key) PacketRegistry::template registerPacket(key); } +/////////////////////////////////////////////////////////////////////////// +// senf::PacketRegistry + template template prefix_ void senf::PacketRegistry::registerPacket(typename Tag::key_t key) @@ -85,6 +91,45 @@ prefix_ senf::PkReg_Entry const * senf::PacketRegistry::lookup(typename Tag return registry().lookup(key,true); } +template +prefix_ typename senf::PacketRegistry::iterator senf::PacketRegistry::begin() +{ + return registry().begin(); +} + +template +prefix_ typename senf::PacketRegistry::iterator senf::PacketRegistry::end() +{ + return registry().end(); +} + +/////////////////////////////////////////////////////////////////////////// +// senf::detail::PacketRegistryImpl + +template +prefix_ senf::detail::PacketRegistryImpl::PacketRegistryImpl(std::string const & name) +{ + registries()[name] = this; +} + +template +prefix_ typename senf::detail::PacketRegistryImpl::iterator +senf::detail::PacketRegistryImpl::begin() + const +{ + return boost::make_transform_iterator( + registry_.begin(), __gnu_cxx::select1st()); +} + +template +prefix_ typename senf::detail::PacketRegistryImpl::iterator +senf::detail::PacketRegistryImpl::end() + const +{ + return boost::make_transform_iterator( + registry_.end(), __gnu_cxx::select1st()); +} + ///////////////////////////////PacketRegistry..e/////////////////////////////////////// #undef prefix_ diff --git a/Packets/PacketRegistry.hh b/Packets/PacketRegistry.hh index 2ae1fa3..bb0d4c2 100644 --- a/Packets/PacketRegistry.hh +++ b/Packets/PacketRegistry.hh @@ -33,26 +33,12 @@ #include "../Utils/Exception.hh" #include "Packet.hh" +#include "PacketRegistry.ih" //#include "PacketRegistry.mpp" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { - /** \brief Registry entry - - 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 - virtual std::string name() const = 0; - }; - - namespace detail { template class PacketRegistryImpl; } - /** \brief Packet registration facility The PacketRegistry provides a generic facility to associate an arbitrary key with @@ -98,6 +84,8 @@ namespace senf { class PacketRegistry { public: + typedef typename detail::PacketRegistryImpl::iterator iterator; + /** \brief Statically register a packet type in a PacketRegistry To use this class, define a global symbol in the following way: @@ -189,6 +177,14 @@ packet of which the key is requested */ 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 Registry; static Registry & registry(); @@ -201,12 +197,19 @@ packet of which the key is requested \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 > \ + 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. @@ -220,7 +223,7 @@ packet of which the key is requested #endif #if !defined(HH_Packets__decls_) && !defined(HH_PacketRegistryImpl_i_) #define HH_PacketRegistryImpl_i_ -//#include "PacketRegistry.cci" +#include "PacketRegistry.cci" #include "PacketRegistry.ct" #include "PacketRegistry.cti" #endif diff --git a/Packets/PacketRegistry.ih b/Packets/PacketRegistry.ih index 7d23bfd..44198ce 100644 --- a/Packets/PacketRegistry.ih +++ b/Packets/PacketRegistry.ih @@ -27,12 +27,28 @@ #define IH_PacketRegistryImpl_ 1 // Custom includes +#include #include +#include #include "../Utils/TypeIdValue.hh" ///////////////////////////////ih.p//////////////////////////////////////// namespace senf { + + /** \brief Registry entry + + 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 + virtual std::string name() const = 0; + }; + namespace detail { /** \brief Internal: Registry entry implementation for a specific packet type @@ -47,13 +63,33 @@ namespace detail { virtual std::string name() const; }; + /** \brief Internal: Registry implementation base-class and registry of registries + + \internal + */ + class PacketRegistryImplBase + : private boost::noncopyable + { + public: + virtual ~PacketRegistryImplBase(); + + static void dump(std::ostream & os); + + protected: + typedef std::map RegistryMap; + static RegistryMap & registries(); + + private: + virtual void v_dump(std::ostream & os) = 0; + }; + /** \brief Internal: Singleton class implementing the packet registry. \internal */ template class PacketRegistryImpl - : private boost::noncopyable + : public PacketRegistryImplBase { public: typedef KeyType key_t; @@ -68,15 +104,14 @@ namespace detail { /////////////////////////////////////////////////////////////////////////// // Types + typedef boost::transform_iterator< __gnu_cxx::select1st, + typename PacketMap::const_iterator > iterator; + /////////////////////////////////////////////////////////////////////////// ///\name Structors and default members ///@{ - - // default default constructor - // no copy constructor - // no copy assignment - // default destructor - // no conversion constructors + + PacketRegistryImpl(std::string const & name); ///@} /////////////////////////////////////////////////////////////////////////// @@ -90,9 +125,14 @@ namespace detail { Entry const & lookup(key_t key); Entry const * lookup(key_t key, bool); + iterator begin() const; + iterator end() const; + protected: private: + virtual void v_dump(std::ostream & os); + PacketMap registry_; ReversePacketMap reverseRegistry_; }; diff --git a/Packets/PacketRegistry.test.cc b/Packets/PacketRegistry.test.cc index d43afb7..6f2e96f 100644 --- a/Packets/PacketRegistry.test.cc +++ b/Packets/PacketRegistry.test.cc @@ -27,6 +27,7 @@ // Custom includes #include +#include #include "Packets.hh" #include "../Utils/auto_unit_test.hh" @@ -74,6 +75,31 @@ BOOST_AUTO_UNIT_TEST(packetRegistry_test) BOOST_CHECK_EQUAL( PacketRegistry::key(), "foo" ); BOOST_CHECK( ! PacketRegistry::lookup("blub", senf::nothrow) ); BOOST_CHECK( PacketRegistry::lookup(1u, senf::nothrow) ); + + unsigned elts1[] = { 1u, 2u }; + BOOST_CHECK_EQUAL_COLLECTIONS( PacketRegistry::begin(), PacketRegistry::end(), + elts1+0, elts1+sizeof(elts1)/sizeof(elts1[0]) ); + + std::string elts2[] = { "bar", "foo" }; + BOOST_CHECK_EQUAL_COLLECTIONS( PacketRegistry::begin(), PacketRegistry::end(), + elts2+0, elts2+sizeof(elts2)/sizeof(elts2[0]) ); + + std::stringstream s; + senf::dumpPacketRegistries(s); + BOOST_CHECK_EQUAL( s.str(), + "(anonymous namespace)::BaseTag:\n" + "1 senf::ConcretePacket<(anonymous namespace)::FooPacketType>\n" + "2 senf::ConcretePacket<(anonymous namespace)::BarPacketType>\n" + "\n" + "(anonymous namespace)::RegTag:\n" + "1 senf::ConcretePacket<(anonymous namespace)::FooPacketType>\n" + "2 senf::ConcretePacket<(anonymous namespace)::BarPacketType>\n" + "\n" + "(anonymous namespace)::StringTag:\n" + "bar senf::ConcretePacket<(anonymous namespace)::BarPacketType>\n" + "foo senf::ConcretePacket<(anonymous namespace)::FooPacketType>\n" + "\n" ); + } ///////////////////////////////cc.e////////////////////////////////////////