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)
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);
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"
--- /dev/null
+// $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:
#define prefix_
///////////////////////////////ct.p////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::PkReg_EntryImpl<PacketType>
+
template <class PacketType>
prefix_ senf::PacketInterpreterBase::factory_t senf::detail::PkReg_EntryImpl<PacketType>::factory()
const
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)
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////////////////////////////////////////
#define prefix_ inline
///////////////////////////////PacketRegistry..p///////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+// senf::PacketRegistry<Tag>::RegistrationProxy<PacketType>
+
template <class Tag>
template <class PacketType>
prefix_ senf::PacketRegistry<Tag>::RegistrationProxy<PacketType>::
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)
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_
#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
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:
*/
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 > \
+ 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.
#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
#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
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;
///////////////////////////////////////////////////////////////////////////
// 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);
///@}
///////////////////////////////////////////////////////////////////////////
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_;
};
// Custom includes
#include <string>
+#include <sstream>
#include "Packets.hh"
#include "../Utils/auto_unit_test.hh"
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////////////////////////////////////////