• 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

Generated on Mon Aug 9 2010 15:56:34 for Crypto++ by  doxygen 1.7.1