1 // factory.h - written and placed in the public domain by Wei Dai
2
3 //! \file factory.h
4 //! \brief Classes and functions for registering and locating library objects
5
6 #ifndef CRYPTOPP_OBJFACT_H
7 #define CRYPTOPP_OBJFACT_H
8
9 #include "cryptlib.h"
10 #include "misc.h"
11 #include "stdcpp.h"
12
NAMESPACE_BEGIN(CryptoPP)13 NAMESPACE_BEGIN(CryptoPP)
14
15 //! \class ObjectFactory
16 //! \brief Object factory interface for registering objects
17 //! \tparam AbstractClass Base class interface of the object
18 template <class AbstractClass>
19 class ObjectFactory
20 {
21 public:
22 virtual ~ObjectFactory () {}
23 virtual AbstractClass * CreateObject() const =0;
24 };
25
26 //! \class DefaultObjectFactory
27 //! \brief Object factory for registering objects
28 //! \tparam AbstractClass Base class interface of the object
29 //! \tparam ConcreteClass Class object
30 template <class AbstractClass, class ConcreteClass>
31 class DefaultObjectFactory : public ObjectFactory<AbstractClass>
32 {
33 public:
CreateObject()34 AbstractClass * CreateObject() const
35 {
36 return new ConcreteClass;
37 }
38 };
39
40 //! \class ObjectFactoryRegistry
41 //! \brief Object factory registry
42 //! \tparam AbstractClass Base class interface of the object
43 //! \tparam instance unique identifier
44 template <class AbstractClass, int instance=0>
45 class ObjectFactoryRegistry
46 {
47 public:
48 class FactoryNotFound : public Exception
49 {
50 public:
FactoryNotFound(const char * name)51 FactoryNotFound(const char *name) : Exception(OTHER_ERROR, std::string("ObjectFactoryRegistry: could not find factory for algorithm ") + name) {}
52 };
53
~ObjectFactoryRegistry()54 ~ObjectFactoryRegistry()
55 {
56 for (typename Map::iterator i = m_map.begin(); i != m_map.end(); ++i)
57 {
58 delete (ObjectFactory<AbstractClass> *)i->second;
59 i->second = NULL;
60 }
61 }
62
RegisterFactory(const std::string & name,ObjectFactory<AbstractClass> * factory)63 void RegisterFactory(const std::string &name, ObjectFactory<AbstractClass> *factory)
64 {
65 m_map[name] = factory;
66 }
67
GetFactory(const char * name)68 const ObjectFactory<AbstractClass> * GetFactory(const char *name) const
69 {
70 typename Map::const_iterator i = m_map.find(name);
71 return i == m_map.end() ? NULL : (ObjectFactory<AbstractClass> *)i->second;
72 }
73
CreateObject(const char * name)74 AbstractClass *CreateObject(const char *name) const
75 {
76 const ObjectFactory<AbstractClass> *factory = GetFactory(name);
77 if (!factory)
78 throw FactoryNotFound(name);
79 return factory->CreateObject();
80 }
81
82 // Return a vector containing the factory names. This is easier than returning an iterator.
83 // from Andrew Pitonyak
GetFactoryNames()84 std::vector<std::string> GetFactoryNames() const
85 {
86 std::vector<std::string> names;
87 typename Map::const_iterator iter;
88 for (iter = m_map.begin(); iter != m_map.end(); ++iter)
89 names.push_back(iter->first);
90 return names;
91 }
92
93 CRYPTOPP_NOINLINE static ObjectFactoryRegistry<AbstractClass, instance> & Registry(CRYPTOPP_NOINLINE_DOTDOTDOT);
94
95 private:
96 // use void * instead of ObjectFactory<AbstractClass> * to save code size
97 typedef std::map<std::string, void *> Map;
98 Map m_map;
99 };
100
101 template <class AbstractClass, int instance>
Registry(CRYPTOPP_NOINLINE_DOTDOTDOT)102 ObjectFactoryRegistry<AbstractClass, instance> & ObjectFactoryRegistry<AbstractClass, instance>::Registry(CRYPTOPP_NOINLINE_DOTDOTDOT)
103 {
104 static ObjectFactoryRegistry<AbstractClass, instance> s_registry;
105 return s_registry;
106 }
107
108 //! \class RegisterDefaultFactoryFor
109 //! \brief Object factory registry helper
110 //! \tparam AbstractClass Base class interface of the object
111 //! \tparam ConcreteClass Class object
112 //! \tparam instance unique identifier
113 template <class AbstractClass, class ConcreteClass, int instance = 0>
114 struct RegisterDefaultFactoryFor
115 {
116 RegisterDefaultFactoryFor(const char *name=NULL)
117 {
118 // BCB2006 workaround
119 std::string n = name ? std::string(name) : std::string(ConcreteClass::StaticAlgorithmName());
120 ObjectFactoryRegistry<AbstractClass, instance>::Registry().
121 RegisterFactory(n, new DefaultObjectFactory<AbstractClass, ConcreteClass>);
122 }
123 };
124
125 //! \fn RegisterAsymmetricCipherDefaultFactories
126 //! \brief Register asymmetric ciphers
127 //! \tparam SchemeClass interface of the object under a scheme
128 //! \details Schemes include asymmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
129 //! signature schemes (registers <tt>SchemeClass::Signer</tt> and <tt>SchemeClass::Verifier</tt>),
130 //! symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
131 //! authenticated symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>), etc.
132 template <class SchemeClass>
133 void RegisterAsymmetricCipherDefaultFactories(const char *name=NULL)
134 {
135 RegisterDefaultFactoryFor<PK_Encryptor, typename SchemeClass::Encryptor>((const char *)name);
136 RegisterDefaultFactoryFor<PK_Decryptor, typename SchemeClass::Decryptor>((const char *)name);
137 }
138
139 //! \fn RegisterSignatureSchemeDefaultFactories
140 //! \brief Register signature schemes
141 //! \tparam SchemeClass interface of the object under a scheme
142 //! \details Schemes include asymmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
143 //! signature schemes (registers <tt>SchemeClass::Signer</tt> and <tt>SchemeClass::Verifier</tt>),
144 //! symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
145 //! authenticated symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>), etc.
146 template <class SchemeClass>
147 void RegisterSignatureSchemeDefaultFactories(const char *name=NULL)
148 {
149 RegisterDefaultFactoryFor<PK_Signer, typename SchemeClass::Signer>((const char *)name);
150 RegisterDefaultFactoryFor<PK_Verifier, typename SchemeClass::Verifier>((const char *)name);
151 }
152
153 //! \fn RegisterSymmetricCipherDefaultFactories
154 //! \brief Register symmetric ciphers
155 //! \tparam SchemeClass interface of the object under a scheme
156 //! \details Schemes include asymmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
157 //! signature schemes (registers <tt>SchemeClass::Signer</tt> and <tt>SchemeClass::Verifier</tt>),
158 //! symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
159 //! authenticated symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>), etc.
160 template <class SchemeClass>
161 void RegisterSymmetricCipherDefaultFactories(const char *name=NULL)
162 {
163 RegisterDefaultFactoryFor<SymmetricCipher, typename SchemeClass::Encryption, ENCRYPTION>((const char *)name);
164 RegisterDefaultFactoryFor<SymmetricCipher, typename SchemeClass::Decryption, DECRYPTION>((const char *)name);
165 }
166
167 //! \fn RegisterAuthenticatedSymmetricCipherDefaultFactories
168 //! \brief Register authenticated symmetric ciphers
169 //! \tparam SchemeClass interface of the object under a scheme
170 //! \details Schemes include asymmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
171 //! signature schemes (registers <tt>SchemeClass::Signer</tt> and <tt>SchemeClass::Verifier</tt>),
172 //! symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
173 //! authenticated symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>), etc.
174 template <class SchemeClass>
175 void RegisterAuthenticatedSymmetricCipherDefaultFactories(const char *name=NULL)
176 {
177 RegisterDefaultFactoryFor<AuthenticatedSymmetricCipher, typename SchemeClass::Encryption, ENCRYPTION>((const char *)name);
178 RegisterDefaultFactoryFor<AuthenticatedSymmetricCipher, typename SchemeClass::Decryption, DECRYPTION>((const char *)name);
179 }
180
181 NAMESPACE_END
182
183 #endif
184