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