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
00070
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
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
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 NAMESPACE_END
00127
00128 #endif