- Main Page
- Namespaces
- Classes
- Files

# 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