Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

factory.h

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

Generated on Wed Jul 21 19:15:23 2004 for Crypto++ by doxygen 1.3.7-20040704