Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

PacketImpl.ih

Go to the documentation of this file.
00001 // $Id: PacketImpl.ih 1742 2010-11-04 14:51:56Z g0dil $
00002 //
00003 // Copyright (C) 2010
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00026 #ifndef IH_SENF_senf_Packets_PacketImpl_
00027 #define IH_SENF_senf_Packets_PacketImpl_ 1
00028 
00029 // Custom includes
00030 #include <iostream>
00031 #include <map>
00032 #include <string>
00033 #include <ext/functional>
00034 #include <boost/iterator/transform_iterator.hpp>
00035 #include <boost/type_traits/is_convertible.hpp>
00036 #include <boost/mpl/sizeof.hpp>
00037 #include <boost/mpl/int.hpp>
00038 #include <boost/mpl/or.hpp>
00039 #include <boost/mpl/greater.hpp>
00040 #include <boost/ptr_container/ptr_map.hpp>
00041 #include <senf/Utils/TypeInfo.hh>
00042 #include <senf/Utils/singleton.hh>
00043 #include <senf/config.hh>
00044 #include <senf/Utils/IgnoreValue.hh>
00045 
00046 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00047 
00048 namespace senf {
00049 
00050     struct ComplexAnnotation;
00051 
00052 namespace detail {
00053 
00054     template <class Annotation>
00055     struct IsComplexAnnotation
00056         : public boost::mpl::or_< boost::is_convertible<Annotation*, ComplexAnnotation*>,
00057                                   boost::mpl::greater<
00058                                       boost::mpl::sizeof_<Annotation>,
00059                                       boost::mpl::int_<SENF_PACKET_ANNOTATION_SLOTSIZE> > >
00060     {};
00061 
00062     class AnnotationRegistry
00063         : public senf::singleton<AnnotationRegistry>
00064     {
00065     public:
00066         typedef int key_type;
00067 
00068     private:
00069         struct RegistrationBase
00070         {
00071             virtual ~RegistrationBase () {};
00072             key_type key;
00073             virtual void v_dump(std::ostream & os, void * annotation) const = 0;
00074             virtual std::string v_name() const = 0;
00075             virtual bool v_isComplex() const = 0;
00076             virtual unsigned v_size() const = 0;
00077         };
00078 
00079         template <class Annotation>
00080         struct Registration
00081             : public RegistrationBase
00082         {
00083             void v_dump(std::ostream & os, void * annotation) const
00084                 { os << * static_cast<Annotation*>(annotation); }
00085             std::string v_name() const
00086                 { return prettyName(typeid(Annotation)); }
00087             bool v_isComplex() const
00088                 { return boost::is_convertible<Annotation*, ComplexAnnotation*>::value; }
00089             unsigned v_size() const
00090                 { return sizeof(Annotation); }
00091         };
00092 
00093         typedef boost::ptr_map<key_type, RegistrationBase> Registry;
00094         // Index must be a multi-map since two identically named classes
00095         // both in the anonymous namespace both have the same demangled name.
00096         // we could sort on the mangled name instead ...
00097         typedef std::multimap<std::string, key_type> Index;
00098 
00099     public:
00100         typedef boost::transform_iterator< ::__gnu_cxx::select2nd<Index::value_type>,
00101                                            Index::const_iterator > iterator;
00102 
00103         using senf::singleton<AnnotationRegistry>::instance;
00104 
00105         template <class Annotation> class RegistrationProxy;
00106 
00107         class EntryBase;
00108         template <class Annotation> class Entry;
00109 
00110         template <class Annotation>
00111         key_type registerAnnotation();
00112 
00113         void dump(key_type key, std::ostream & os, void * annotation) const;
00114         std::string name(key_type key) const;
00115         bool isComplex(key_type key) const;
00116         unsigned size(key_type key) const;
00117 
00118         template <class Annotation>
00119         static key_type lookup();
00120 
00121         iterator begin() const;
00122         iterator end() const;
00123 
00124         void dumpRegistrations(std::ostream & os);
00125 
00126     private:
00127         AnnotationRegistry();
00128 
00129         key_type simpleAnnotationCount_;
00130         key_type complexAnnotationCount_;
00131 
00132         Registry registry_;
00133         // The index is needed to ensure a persistent and reproducible
00134         // ordering of the annotations when dumping
00135         Index index_;
00136 
00137         friend class senf::singleton<AnnotationRegistry>;
00138     };
00139 
00140     template <class Annotation>
00141     class AnnotationRegistry::RegistrationProxy
00142     {
00143     public:
00144         RegistrationProxy()
00145             {
00146                 AnnotationRegistry::Entry<Annotation>::key_ =
00147                     AnnotationRegistry::instance().registerAnnotation<Annotation>();
00148             }
00149     };
00150 
00151     class AnnotationRegistry::EntryBase
00152     {
00153     public:
00154         virtual ~EntryBase() {}
00155 
00156         virtual void * get() = 0;
00157 
00158         typedef EntryBase * ptr;
00159         virtual ptr clone() const = 0;
00160     };
00161 
00162     inline AnnotationRegistry::EntryBase::ptr new_clone( AnnotationRegistry::EntryBase const & entry)
00163     {
00164         return entry.clone();
00165     }
00166 
00167     template <class Annotation>
00168     class AnnotationRegistry::Entry
00169         : public AnnotationRegistry::EntryBase
00170     {
00171         static RegistrationProxy<Annotation> proxy_;
00172         static AnnotationRegistry::key_type key_;
00173     public:
00174         // We use this member to force instantiation of proxy_ ...
00175         static AnnotationRegistry::key_type key()
00176             { senf::IGNORE(&proxy_); return key_; }
00177 
00178         virtual void * get() { return & annotation_; }
00179         virtual EntryBase::ptr clone() const { return new Entry<Annotation>( *this); }
00180 
00181     private:
00182         Annotation annotation_;
00183 
00184         friend class AnnotationRegistry::RegistrationProxy<Annotation>;
00185     };
00186 
00187 }}
00188 
00189 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00190 #endif
00191 
00192 
00193 // Local Variables:
00194 // mode: c++
00195 // fill-column: 100
00196 // comment-column: 40
00197 // c-file-style: "senf"
00198 // indent-tabs-mode: nil
00199 // ispell-local-dictionary: "american"
00200 // compile-command: "scons -u test"
00201 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research