00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #ifndef HH_SENF_Packets_GenericTLV_
00027 #define HH_SENF_Packets_GenericTLV_ 1
00028
00029
00030 #include <boost/ptr_container/ptr_map.hpp>
00031 #include <senf/Packets/Packets.hh>
00032 #include <senf/Utils/type_traits.hh>
00033 #include <senf/Utils/singleton.hh>
00034
00035
00036
00037
00038 namespace senf {
00039
00132 template <class Base>
00133 class GenericTLVParserBase : public Base
00134 {
00135 public:
00136 GenericTLVParserBase(senf::PacketParserBase::data_iterator i, senf::PacketParserBase::state_type s)
00137 : Base(i,s) {}
00138
00139 senf::PacketParserBase::size_type bytes() const;
00140 void init() const;
00141
00142 template <class Parser>
00143 Parser init();
00144
00145 template <class Parser>
00146 Parser as() const;
00147
00148 template <class Parser>
00149 bool is() const;
00150
00151 senf::PacketInterpreterBase::range value() const;
00152
00153 void dump(std::ostream & os) const;
00154
00155 #ifndef DOXYGEN
00156 template<class ForwardReadableRange>
00157 void value(ForwardReadableRange const & val,
00158 typename boost::disable_if<senf::is_pair<ForwardReadableRange> >::type * = 0);
00159
00160 template<class First, class Second>
00161 void value(std::pair<First, Second> const & val,
00162 typename boost::disable_if<boost::is_convertible<First, typename Base::type_t::value_type> >::type * = 0);
00163
00164 template <class Type, class ForwardReadableRange>
00165 void value(std::pair<Type, ForwardReadableRange> const & val,
00166 typename boost::enable_if<boost::is_convertible<Type, typename Base::type_t::value_type> >::type * = 0);
00167 #else
00168 template<class ForwardReadableRange>
00169 void value(ForwardReadableRange const & val);
00170
00171 template <class ForwardReadableRange>
00172 void value(std::pair<typename Base::type_t::value_type, ForwardReadableRange> const & val);
00173 #endif
00174
00175 private:
00176 template<class ForwardReadableRange>
00177 void value_(ForwardReadableRange const &range);
00178
00179 Base & self();
00180 Base const & self() const;
00181 };
00182
00183
00184 namespace detail {
00185 template <class BaseParser>
00186 struct GenericTLVParserRegistry_EntryBase {
00187 virtual ~GenericTLVParserRegistry_EntryBase() {}
00188 virtual void dump(GenericTLVParserBase<BaseParser> const & parser, std::ostream & os) const = 0;
00189 virtual PacketParserBase::size_type bytes(GenericTLVParserBase<BaseParser> const & parser) const = 0;
00190 };
00191
00192 template <class BaseParser, class Parser>
00193 struct GenericTLVParserRegistry_Entry
00194 : GenericTLVParserRegistry_EntryBase<BaseParser>
00195 {
00196 virtual void dump(GenericTLVParserBase<BaseParser> const & parser, std::ostream & os) const;
00197 virtual PacketParserBase::size_type bytes(GenericTLVParserBase<BaseParser> const & parser) const;
00198 };
00199
00200
00201 template <class BaseParser, class Parser>
00202 class Predicate
00203 {
00204 public:
00205 bool operator() (BaseParser const &p) const {
00206 return p.template is<Parser>();
00207 }
00208 };
00209 }
00210
00258 template <class BaseParser, class Keytype = typename BaseParser::type_t::value_type>
00259 class GenericTLVParserRegistry
00260 : public senf::singleton<GenericTLVParserRegistry<BaseParser,Keytype> >
00261 {
00262 typedef boost::ptr_map<Keytype,
00263 detail::GenericTLVParserRegistry_EntryBase<BaseParser> > Map;
00264 Map map_;
00265
00266 GenericTLVParserRegistry() {};
00267 public:
00268 using senf::singleton<GenericTLVParserRegistry<BaseParser,Keytype> >::instance;
00269 friend class senf::singleton<GenericTLVParserRegistry<BaseParser,Keytype> >;
00270
00271 template <class PacketParser>
00272 struct RegistrationProxy {
00273 RegistrationProxy();
00274 };
00275
00276 template <typename Parser>
00277 void registerParser();
00278
00279 typedef GenericTLVParserBase<BaseParser> GenericTLVParser;
00280
00281 bool isRegistered(GenericTLVParserBase<BaseParser> const & parser) const;
00282 bool isRegistered(Keytype const & key) const;
00283
00284 void dump(GenericTLVParser const & parser, std::ostream & os) const;
00285 void dump(GenericTLVParser const & parser, Keytype const & key, std::ostream & os) const;
00286
00287 PacketParserBase::size_type bytes(GenericTLVParser const & parser) const;
00288 PacketParserBase::size_type bytes(GenericTLVParser const & parser, Keytype const & key) const;
00289 };
00290
00291 struct TLVParserNotRegisteredException : public senf::Exception
00292 {
00293 TLVParserNotRegisteredException() : senf::Exception("tlv parser not registered") {}
00294 };
00295
00296
00305 # define SENF_PACKET_TLV_REGISTRY_REGISTER( ConreteTLVParser ) \
00306 namespace { \
00307 ConreteTLVParser::Registry::RegistrationProxy<ConreteTLVParser> \
00308 BOOST_PP_CAT(tlvparserRegistration_, __LINE__); \
00309 }
00310
00311 }
00312
00313
00314
00315 #include "GenericTLV.ct"
00316 #include "GenericTLV.cti"
00317 #endif
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328