// factory.h - originally written and placed in the public domain by Wei Dai /// \file factory.h /// \brief Classes and functions for registering and locating library objects #ifndef CRYPTOPP_OBJFACT_H #define CRYPTOPP_OBJFACT_H #include "cryptlib.h" #include "misc.h" #include "stdcpp.h" NAMESPACE_BEGIN(CryptoPP) /// \brief Object factory interface for registering objects /// \tparam AbstractClass Base class interface of the object template class ObjectFactory { public: virtual ~ObjectFactory () {} virtual AbstractClass * CreateObject() const =0; }; /// \brief Object factory for registering objects /// \tparam AbstractClass Base class interface of the object /// \tparam ConcreteClass Class object template class DefaultObjectFactory : public ObjectFactory { public: AbstractClass * CreateObject() const { return new ConcreteClass; } }; /// \brief Object factory registry /// \tparam AbstractClass Base class interface of the object /// \tparam instance unique identifier template class ObjectFactoryRegistry { public: class FactoryNotFound : public Exception { public: FactoryNotFound(const char *name) : Exception(OTHER_ERROR, std::string("ObjectFactoryRegistry: could not find factory for algorithm ") + name) {} }; ~ObjectFactoryRegistry() { for (typename Map::iterator i = m_map.begin(); i != m_map.end(); ++i) { delete (ObjectFactory *)i->second; i->second = NULLPTR; } } void RegisterFactory(const std::string &name, ObjectFactory *factory) { m_map[name] = factory; } const ObjectFactory * GetFactory(const char *name) const { typename Map::const_iterator i = m_map.find(name); return i == m_map.end() ? NULLPTR : (ObjectFactory *)i->second; } AbstractClass *CreateObject(const char *name) const { const ObjectFactory *factory = GetFactory(name); if (!factory) throw FactoryNotFound(name); return factory->CreateObject(); } // Return a vector containing the factory names. This is easier than returning an iterator. // from Andrew Pitonyak std::vector GetFactoryNames() const { std::vector names; typename Map::const_iterator iter; for (iter = m_map.begin(); iter != m_map.end(); ++iter) names.push_back(iter->first); return names; } CRYPTOPP_NOINLINE static ObjectFactoryRegistry & Registry(CRYPTOPP_NOINLINE_DOTDOTDOT); private: // use void * instead of ObjectFactory * to save code size typedef std::map Map; Map m_map; }; template ObjectFactoryRegistry & ObjectFactoryRegistry::Registry(CRYPTOPP_NOINLINE_DOTDOTDOT) { static ObjectFactoryRegistry s_registry; return s_registry; } /// \brief Object factory registry helper /// \tparam AbstractClass Base class interface of the object /// \tparam ConcreteClass Class object /// \tparam instance unique identifier template struct RegisterDefaultFactoryFor { RegisterDefaultFactoryFor(const char *name=NULLPTR) { // BCB2006 workaround std::string n = name ? std::string(name) : std::string(ConcreteClass::StaticAlgorithmName()); ObjectFactoryRegistry::Registry(). RegisterFactory(n, new DefaultObjectFactory); } }; /// \fn RegisterAsymmetricCipherDefaultFactories /// \brief Register asymmetric ciphers /// \tparam SchemeClass interface of the object under a scheme /// \details Schemes include asymmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), /// signature schemes (registers SchemeClass::Signer and SchemeClass::Verifier), /// symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), /// authenticated symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), etc. template void RegisterAsymmetricCipherDefaultFactories(const char *name=NULLPTR) { RegisterDefaultFactoryFor((const char *)name); RegisterDefaultFactoryFor((const char *)name); } /// \fn RegisterSignatureSchemeDefaultFactories /// \brief Register signature schemes /// \tparam SchemeClass interface of the object under a scheme /// \details Schemes include asymmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), /// signature schemes (registers SchemeClass::Signer and SchemeClass::Verifier), /// symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), /// authenticated symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), etc. template void RegisterSignatureSchemeDefaultFactories(const char *name=NULLPTR) { RegisterDefaultFactoryFor((const char *)name); RegisterDefaultFactoryFor((const char *)name); } /// \fn RegisterSymmetricCipherDefaultFactories /// \brief Register symmetric ciphers /// \tparam SchemeClass interface of the object under a scheme /// \details Schemes include asymmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), /// signature schemes (registers SchemeClass::Signer and SchemeClass::Verifier), /// symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), /// authenticated symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), etc. template void RegisterSymmetricCipherDefaultFactories(const char *name=NULLPTR) { RegisterDefaultFactoryFor((const char *)name); RegisterDefaultFactoryFor((const char *)name); } /// \fn RegisterAuthenticatedSymmetricCipherDefaultFactories /// \brief Register authenticated symmetric ciphers /// \tparam SchemeClass interface of the object under a scheme /// \details Schemes include asymmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), /// signature schemes (registers SchemeClass::Signer and SchemeClass::Verifier), /// symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), /// authenticated symmetric ciphers (registers SchemeClass::Encryptor and SchemeClass::Decryptor), etc. template void RegisterAuthenticatedSymmetricCipherDefaultFactories(const char *name=NULLPTR) { RegisterDefaultFactoryFor((const char *)name); RegisterDefaultFactoryFor((const char *)name); } NAMESPACE_END #endif