Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | 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 Thu Oct 28 03:02:10 2004 for Crypto++ by  doxygen 1.3.9.1