Packets: Add PacketRegistry::begin()/end() and senf::dumpPacketRegistries() utility
g0dil [Mon, 11 Feb 2008 11:32:31 +0000 (11:32 +0000)]
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

Examples/Sniffer/SConscript
Examples/Sniffer/Sniffer.cc
Packets/PacketRegistry.cc
Packets/PacketRegistry.cci [new file with mode: 0644]
Packets/PacketRegistry.ct
Packets/PacketRegistry.cti
Packets/PacketRegistry.hh
Packets/PacketRegistry.ih
Packets/PacketRegistry.test.cc

index e30f7c9..250abc6 100644 (file)
@@ -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)
index 0c53e5f..fbeeab4 100644 (file)
@@ -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);
index 48b76bb..366c129 100644 (file)
 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 (file)
index 0000000..2e0c48f
--- /dev/null
@@ -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 <g0dil@berlios.de>
+//
+// 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_
+
+\f
+// 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:
index 2cd02f8..f274efa 100644 (file)
@@ -33,6 +33,9 @@
 #define prefix_
 ///////////////////////////////ct.p////////////////////////////////////////
 
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::PkReg_EntryImpl<PacketType>
+
 template <class PacketType>
 prefix_ senf::PacketInterpreterBase::factory_t senf::detail::PkReg_EntryImpl<PacketType>::factory()
     const
@@ -47,6 +50,20 @@ prefix_ std::string senf::detail::PkReg_EntryImpl<PacketType>::name()
     return prettyName(typeid(PacketType));
 }
 
+///////////////////////////////////////////////////////////////////////////
+// senf::PacketRegistry<Tag>
+
+template <class Tag>
+prefix_ typename senf::PacketRegistry<Tag>::Registry &
+senf::PacketRegistry<Tag>::registry()
+{
+    static Registry registry (prettyName(typeid(Tag)));
+    return registry;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::PacketRegistryImpl<KeyType>:
+
 template <class KeyType>
 template <class PacketType>
 prefix_ void senf::detail::PacketRegistryImpl<KeyType>::registerPacket(key_t key)
@@ -108,12 +125,13 @@ senf::detail::PacketRegistryImpl<KeyType>::lookup(key_t key, bool)
     return i->second.get();
 }
 
-template <class Tag>
-prefix_ typename senf::PacketRegistry<Tag>::Registry &
-senf::PacketRegistry<Tag>::registry()
+template <class KeyType>
+prefix_ void senf::detail::PacketRegistryImpl<KeyType>::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////////////////////////////////////////
index 2f7ffd1..6de3a0c 100644 (file)
@@ -30,6 +30,9 @@
 #define prefix_ inline
 ///////////////////////////////PacketRegistry..p///////////////////////////////////////
 
+///////////////////////////////////////////////////////////////////////////
+// senf::PacketRegistry<Tag>::RegistrationProxy<PacketType>
+
 template <class Tag>
 template <class PacketType>
 prefix_ senf::PacketRegistry<Tag>::RegistrationProxy<PacketType>::
@@ -38,6 +41,9 @@ RegistrationProxy(typename Tag::key_t key)
     PacketRegistry<Tag>::template registerPacket<PacketType>(key);
 }
 
+///////////////////////////////////////////////////////////////////////////
+// senf::PacketRegistry<Tag>
+
 template <class Tag>
 template <class PacketType>
 prefix_ void senf::PacketRegistry<Tag>::registerPacket(typename Tag::key_t key)
@@ -85,6 +91,45 @@ prefix_ senf::PkReg_Entry const * senf::PacketRegistry<Tag>::lookup(typename Tag
     return registry().lookup(key,true);
 }
 
+template <class Tag>
+prefix_ typename senf::PacketRegistry<Tag>::iterator senf::PacketRegistry<Tag>::begin()
+{
+    return registry().begin();
+}
+
+template <class Tag>
+prefix_ typename senf::PacketRegistry<Tag>::iterator senf::PacketRegistry<Tag>::end()
+{
+    return registry().end();
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::PacketRegistryImpl<KeyType>
+
+template <class KeyType>
+prefix_ senf::detail::PacketRegistryImpl<KeyType>::PacketRegistryImpl(std::string const & name)
+{
+    registries()[name] = this;
+}
+
+template <class KeyType>
+prefix_ typename senf::detail::PacketRegistryImpl<KeyType>::iterator
+senf::detail::PacketRegistryImpl<KeyType>::begin()
+    const
+{
+    return boost::make_transform_iterator(
+        registry_.begin(), __gnu_cxx::select1st<typename PacketMap::value_type>());
+}
+
+template <class KeyType>
+prefix_ typename senf::detail::PacketRegistryImpl<KeyType>::iterator
+senf::detail::PacketRegistryImpl<KeyType>::end()
+    const
+{
+    return boost::make_transform_iterator(
+        registry_.end(), __gnu_cxx::select1st<typename PacketMap::value_type>());
+}
+
 ///////////////////////////////PacketRegistry..e///////////////////////////////////////
 #undef prefix_
 
index 2ae1fa3..bb0d4c2 100644 (file)
 #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 Key> 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<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:
@@ -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<typename Tag::key_t> 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
index 7d23bfd..44198ce 100644 (file)
 #define IH_PacketRegistryImpl_ 1
 
 // Custom includes
+#include <ext/functional>
 #include <boost/intrusive_ptr.hpp>
+#include <boost/iterator/transform_iterator.hpp>
 #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<std::string, PacketRegistryImplBase*>  RegistryMap;
+        static RegistryMap & registries();
+
+    private:
+        virtual void v_dump(std::ostream & os) = 0;
+    };
+
     /** \brief Internal: Singleton class implementing the packet registry.
 
         \internal
      */
     template <class KeyType>
     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::value_type>,
+                                           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_;
     };
index d43afb7..6f2e96f 100644 (file)
@@ -27,6 +27,7 @@
 
 // Custom includes
 #include <string>
+#include <sstream>
 #include "Packets.hh"
 
 #include "../Utils/auto_unit_test.hh"
@@ -74,6 +75,31 @@ BOOST_AUTO_UNIT_TEST(packetRegistry_test)
     BOOST_CHECK_EQUAL( PacketRegistry<StringTag>::key<FooPacket>(), "foo" );
     BOOST_CHECK( ! PacketRegistry<StringTag>::lookup("blub", senf::nothrow) );
     BOOST_CHECK( PacketRegistry<BaseTag>::lookup(1u, senf::nothrow) );
+
+    unsigned elts1[] = { 1u, 2u };
+    BOOST_CHECK_EQUAL_COLLECTIONS( PacketRegistry<BaseTag>::begin(), PacketRegistry<BaseTag>::end(),
+                                   elts1+0, elts1+sizeof(elts1)/sizeof(elts1[0]) );
+
+    std::string elts2[] = { "bar", "foo" };
+    BOOST_CHECK_EQUAL_COLLECTIONS( PacketRegistry<StringTag>::begin(), PacketRegistry<StringTag>::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////////////////////////////////////////