Crypto++
|
00001 #ifndef CRYPTOPP_OBJFACT_H 00002 #define CRYPTOPP_OBJFACT_H 00003 00004 #include "cryptlib.h" 00005 #include <map> 00006 #include <vector> 00007 00008 NAMESPACE_BEGIN(CryptoPP) 00009 00010 //! _ 00011 template <class AbstractClass> 00012 class ObjectFactory 00013 { 00014 public: 00015 virtual AbstractClass * CreateObject() const =0; 00016 }; 00017 00018 //! _ 00019 template <class AbstractClass, class ConcreteClass> 00020 class DefaultObjectFactory : public ObjectFactory<AbstractClass> 00021 { 00022 public: 00023 AbstractClass * CreateObject() const 00024 { 00025 return new ConcreteClass; 00026 } 00027 00028 }; 00029 00030 //! _ 00031 template <class AbstractClass, int instance=0> 00032 class ObjectFactoryRegistry 00033 { 00034 public: 00035 class FactoryNotFound : public Exception 00036 { 00037 public: 00038 FactoryNotFound(const char *name) : Exception(OTHER_ERROR, std::string("ObjectFactoryRegistry: could not find factory for algorithm ") + name) {} 00039 }; 00040 00041 ~ObjectFactoryRegistry() 00042 { 00043 for (CPP_TYPENAME Map::iterator i = m_map.begin(); i != m_map.end(); ++i) 00044 { 00045 delete (ObjectFactory<AbstractClass> *)i->second; 00046 i->second = NULL; 00047 } 00048 } 00049 00050 void RegisterFactory(const std::string &name, ObjectFactory<AbstractClass> *factory) 00051 { 00052 m_map[name] = factory; 00053 } 00054 00055 const ObjectFactory<AbstractClass> * GetFactory(const char *name) const 00056 { 00057 CPP_TYPENAME Map::const_iterator i = m_map.find(name); 00058 return i == m_map.end() ? NULL : (ObjectFactory<AbstractClass> *)i->second; 00059 } 00060 00061 AbstractClass *CreateObject(const char *name) const 00062 { 00063 const ObjectFactory<AbstractClass> *factory = GetFactory(name); 00064 if (!factory) 00065 throw FactoryNotFound(name); 00066 return factory->CreateObject(); 00067 } 00068 00069 // Return a vector containing the factory names. This is easier than returning an iterator. 00070 // from Andrew Pitonyak 00071 std::vector<std::string> GetFactoryNames() const 00072 { 00073 std::vector<std::string> names; 00074 CPP_TYPENAME Map::const_iterator iter; 00075 for (iter = m_map.begin(); iter != m_map.end(); ++iter) 00076 names.push_back(iter->first); 00077 return names; 00078 } 00079 00080 CRYPTOPP_NOINLINE static ObjectFactoryRegistry<AbstractClass, instance> & Registry(CRYPTOPP_NOINLINE_DOTDOTDOT); 00081 00082 private: 00083 // use void * instead of ObjectFactory<AbstractClass> * to save code size 00084 typedef std::map<std::string, void *> Map; 00085 Map m_map; 00086 }; 00087 00088 template <class AbstractClass, int instance> 00089 ObjectFactoryRegistry<AbstractClass, instance> & ObjectFactoryRegistry<AbstractClass, instance>::Registry(CRYPTOPP_NOINLINE_DOTDOTDOT) 00090 { 00091 static ObjectFactoryRegistry<AbstractClass, instance> s_registry; 00092 return s_registry; 00093 } 00094 00095 template <class AbstractClass, class ConcreteClass, int instance = 0> 00096 struct RegisterDefaultFactoryFor { 00097 RegisterDefaultFactoryFor(const char *name=NULL) 00098 { 00099 // BCB2006 workaround 00100 std::string n = name ? std::string(name) : std::string(ConcreteClass::StaticAlgorithmName()); 00101 ObjectFactoryRegistry<AbstractClass, instance>::Registry(). 00102 RegisterFactory(n, new DefaultObjectFactory<AbstractClass, ConcreteClass>); 00103 }}; 00104 00105 template <class SchemeClass> 00106 void RegisterAsymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL) 00107 { 00108 RegisterDefaultFactoryFor<PK_Encryptor, CPP_TYPENAME SchemeClass::Encryptor>((const char *)name); 00109 RegisterDefaultFactoryFor<PK_Decryptor, CPP_TYPENAME SchemeClass::Decryptor>((const char *)name); 00110 } 00111 00112 template <class SchemeClass> 00113 void RegisterSignatureSchemeDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL) 00114 { 00115 RegisterDefaultFactoryFor<PK_Signer, CPP_TYPENAME SchemeClass::Signer>((const char *)name); 00116 RegisterDefaultFactoryFor<PK_Verifier, CPP_TYPENAME SchemeClass::Verifier>((const char *)name); 00117 } 00118 00119 template <class SchemeClass> 00120 void RegisterSymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL) 00121 { 00122 RegisterDefaultFactoryFor<SymmetricCipher, CPP_TYPENAME SchemeClass::Encryption, ENCRYPTION>((const char *)name); 00123 RegisterDefaultFactoryFor<SymmetricCipher, CPP_TYPENAME SchemeClass::Decryption, DECRYPTION>((const char *)name); 00124 } 00125 00126 template <class SchemeClass> 00127 void RegisterAuthenticatedSymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL) 00128 { 00129 RegisterDefaultFactoryFor<AuthenticatedSymmetricCipher, CPP_TYPENAME SchemeClass::Encryption, ENCRYPTION>((const char *)name); 00130 RegisterDefaultFactoryFor<AuthenticatedSymmetricCipher, CPP_TYPENAME SchemeClass::Decryption, DECRYPTION>((const char *)name); 00131 } 00132 00133 NAMESPACE_END 00134 00135 #endif