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     CRYPTOPP_NOINLINE static ObjectFactoryRegistry<AbstractClass, instance> & Registry(CRYPTOPP_NOINLINE_DOTDOTDOT);
00069 
00070 private:
00071     // use void * instead of ObjectFactory<AbstractClass> * to save code size
00072     typedef std::map<std::string, void *> Map;
00073     Map m_map;
00074 };
00075 
00076 template <class AbstractClass, int instance>
00077 ObjectFactoryRegistry<AbstractClass, instance> & ObjectFactoryRegistry<AbstractClass, instance>::Registry(CRYPTOPP_NOINLINE_DOTDOTDOT)
00078 {
00079     static ObjectFactoryRegistry<AbstractClass, instance> s_registry;
00080     return s_registry;
00081 }
00082 
00083 template <class AbstractClass, class ConcreteClass, int instance = 0>
00084 struct RegisterDefaultFactoryFor {
00085 RegisterDefaultFactoryFor(const char *name=NULL)
00086 {
00087     // BCB2006 workaround
00088     std::string n = name ? std::string(name) : std::string(ConcreteClass::StaticAlgorithmName());
00089     ObjectFactoryRegistry<AbstractClass, instance>::Registry().
00090         RegisterFactory(n, new DefaultObjectFactory<AbstractClass, ConcreteClass>);
00091 }};
00092 
00093 template <class SchemeClass>
00094 void RegisterAsymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL)
00095 {
00096     RegisterDefaultFactoryFor<PK_Encryptor, CPP_TYPENAME SchemeClass::Encryptor>((const char *)name);
00097     RegisterDefaultFactoryFor<PK_Decryptor, CPP_TYPENAME SchemeClass::Decryptor>((const char *)name);
00098 }
00099 
00100 template <class SchemeClass>
00101 void RegisterSignatureSchemeDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL)
00102 {
00103     RegisterDefaultFactoryFor<PK_Signer, CPP_TYPENAME SchemeClass::Signer>((const char *)name);
00104     RegisterDefaultFactoryFor<PK_Verifier, CPP_TYPENAME SchemeClass::Verifier>((const char *)name);
00105 }
00106 
00107 template <class SchemeClass>
00108 void RegisterSymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL)
00109 {
00110     RegisterDefaultFactoryFor<SymmetricCipher, CPP_TYPENAME SchemeClass::Encryption, ENCRYPTION>((const char *)name);
00111     RegisterDefaultFactoryFor<SymmetricCipher, CPP_TYPENAME SchemeClass::Decryption, DECRYPTION>((const char *)name);
00112 }
00113 
00114 NAMESPACE_END
00115 
00116 #endif

Generated on Thu Jul 5 22:21:37 2007 for Crypto++ by  doxygen 1.5.2