Crypto++

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

factory.h

    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     // Return a vector containing the factory names. This is easier than returning an iterator.
    00070     // from Andrew Pitonyak
    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     // use void * instead of ObjectFactory<AbstractClass> * to save code size
    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     // BCB2006 workaround
    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 template <class SchemeClass>
    00127 void RegisterAuthenticatedSymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL)
    00128 {
    00129     RegisterDefaultFactoryFor<AuthenticatedSymmetricCipher, CPP_TYPENAME SchemeClass::Encryption, ENCRYPTION>((const char *)name);
    00130     RegisterDefaultFactoryFor<AuthenticatedSymmetricCipher, CPP_TYPENAME SchemeClass::Decryption, DECRYPTION>((const char *)name);
    00131 }
    00132
    00133 NAMESPACE_END
    00134
    00135 #endif