summaryrefslogtreecommitdiff
path: root/factory.h
blob: d3d36e3c3261cdcb4496ae5e67ba144bdb46a487 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// factory.h - originally written and placed in the public domain by Wei Dai

/// \file factory.h
/// \brief Classes and functions for registering and locating library objects

#ifndef CRYPTOPP_OBJFACT_H
#define CRYPTOPP_OBJFACT_H

#include "cryptlib.h"
#include "misc.h"
#include "stdcpp.h"

NAMESPACE_BEGIN(CryptoPP)

/// \brief Object factory interface for registering objects
/// \tparam AbstractClass Base class interface of the object
template <class AbstractClass>
class ObjectFactory
{
public:
	virtual ~ObjectFactory () {}
	virtual AbstractClass * CreateObject() const =0;
};

/// \brief Object factory for registering objects
/// \tparam AbstractClass Base class interface of the object
/// \tparam ConcreteClass Class object
template <class AbstractClass, class ConcreteClass>
class DefaultObjectFactory : public ObjectFactory<AbstractClass>
{
public:
	AbstractClass * CreateObject() const
	{
		return new ConcreteClass;
	}
};

/// \brief Object factory registry
/// \tparam AbstractClass Base class interface of the object
/// \tparam instance unique identifier
template <class AbstractClass, int instance=0>
class ObjectFactoryRegistry
{
public:
	class FactoryNotFound : public Exception
	{
	public:
		FactoryNotFound(const char *name) : Exception(OTHER_ERROR, std::string("ObjectFactoryRegistry: could not find factory for algorithm ") + name)  {}
	};

	~ObjectFactoryRegistry()
	{
		for (typename Map::iterator i = m_map.begin(); i != m_map.end(); ++i)
		{
			delete (ObjectFactory<AbstractClass> *)i->second;
			i->second = NULLPTR;
		}
	}

	void RegisterFactory(const std::string &name, ObjectFactory<AbstractClass> *factory)
	{
		m_map[name] = factory;
	}

	const ObjectFactory<AbstractClass> * GetFactory(const char *name) const
	{
		typename Map::const_iterator i = m_map.find(name);
		return i == m_map.end() ? NULLPTR : (ObjectFactory<AbstractClass> *)i->second;
	}

	AbstractClass *CreateObject(const char *name) const
	{
		const ObjectFactory<AbstractClass> *factory = GetFactory(name);
		if (!factory)
			throw FactoryNotFound(name);
		return factory->CreateObject();
	}

	// Return a vector containing the factory names. This is easier than returning an iterator.
	// from Andrew Pitonyak
	std::vector<std::string> GetFactoryNames() const
	{
		std::vector<std::string> names;
		typename Map::const_iterator iter;
		for (iter = m_map.begin(); iter != m_map.end(); ++iter)
			names.push_back(iter->first);
		return names;
	}

	CRYPTOPP_NOINLINE static ObjectFactoryRegistry<AbstractClass, instance> & Registry(CRYPTOPP_NOINLINE_DOTDOTDOT);

private:
	// use void * instead of ObjectFactory<AbstractClass> * to save code size
	typedef std::map<std::string, void *> Map;
	Map m_map;
};

template <class AbstractClass, int instance>
ObjectFactoryRegistry<AbstractClass, instance> & ObjectFactoryRegistry<AbstractClass, instance>::Registry(CRYPTOPP_NOINLINE_DOTDOTDOT)
{
	static ObjectFactoryRegistry<AbstractClass, instance> s_registry;
	return s_registry;
}

/// \brief Object factory registry helper
/// \tparam AbstractClass Base class interface of the object
/// \tparam ConcreteClass Class object
/// \tparam instance unique identifier
template <class AbstractClass, class ConcreteClass, int instance = 0>
struct RegisterDefaultFactoryFor
{
	RegisterDefaultFactoryFor(const char *name=NULLPTR)
	{
		// BCB2006 workaround
		std::string n = name ? std::string(name) : std::string(ConcreteClass::StaticAlgorithmName());
		ObjectFactoryRegistry<AbstractClass, instance>::Registry().
		RegisterFactory(n, new DefaultObjectFactory<AbstractClass, ConcreteClass>);
	}
};

/// \fn RegisterAsymmetricCipherDefaultFactories
/// \brief Register asymmetric ciphers
/// \tparam SchemeClass interface of the object under a scheme
/// \details Schemes include asymmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
///   signature schemes (registers <tt>SchemeClass::Signer</tt> and <tt>SchemeClass::Verifier</tt>),
///   symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
///   authenticated symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>), etc.
template <class SchemeClass>
void RegisterAsymmetricCipherDefaultFactories(const char *name=NULLPTR)
{
	RegisterDefaultFactoryFor<PK_Encryptor, typename SchemeClass::Encryptor>((const char *)name);
	RegisterDefaultFactoryFor<PK_Decryptor, typename SchemeClass::Decryptor>((const char *)name);
}

/// \fn RegisterSignatureSchemeDefaultFactories
/// \brief Register signature schemes
/// \tparam SchemeClass interface of the object under a scheme
/// \details Schemes include asymmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
///   signature schemes (registers <tt>SchemeClass::Signer</tt> and <tt>SchemeClass::Verifier</tt>),
///   symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
///   authenticated symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>), etc.
template <class SchemeClass>
void RegisterSignatureSchemeDefaultFactories(const char *name=NULLPTR)
{
	RegisterDefaultFactoryFor<PK_Signer, typename SchemeClass::Signer>((const char *)name);
	RegisterDefaultFactoryFor<PK_Verifier, typename SchemeClass::Verifier>((const char *)name);
}

/// \fn RegisterSymmetricCipherDefaultFactories
/// \brief Register symmetric ciphers
/// \tparam SchemeClass interface of the object under a scheme
/// \details Schemes include asymmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
///   signature schemes (registers <tt>SchemeClass::Signer</tt> and <tt>SchemeClass::Verifier</tt>),
///   symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
///   authenticated symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>), etc.
template <class SchemeClass>
void RegisterSymmetricCipherDefaultFactories(const char *name=NULLPTR)
{
	RegisterDefaultFactoryFor<SymmetricCipher, typename SchemeClass::Encryption, ENCRYPTION>((const char *)name);
	RegisterDefaultFactoryFor<SymmetricCipher, typename SchemeClass::Decryption, DECRYPTION>((const char *)name);
}

/// \fn RegisterAuthenticatedSymmetricCipherDefaultFactories
/// \brief Register authenticated symmetric ciphers
/// \tparam SchemeClass interface of the object under a scheme
/// \details Schemes include asymmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
///   signature schemes (registers <tt>SchemeClass::Signer</tt> and <tt>SchemeClass::Verifier</tt>),
///   symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
///   authenticated symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>), etc.
template <class SchemeClass>
void RegisterAuthenticatedSymmetricCipherDefaultFactories(const char *name=NULLPTR)
{
	RegisterDefaultFactoryFor<AuthenticatedSymmetricCipher, typename SchemeClass::Encryption, ENCRYPTION>((const char *)name);
	RegisterDefaultFactoryFor<AuthenticatedSymmetricCipher, typename SchemeClass::Decryption, DECRYPTION>((const char *)name);
}

NAMESPACE_END

#endif