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