aboutsummaryrefslogtreecommitdiffstats
path: root/src/algo_factory
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-11-12 21:23:56 +0000
committerlloyd <[email protected]>2008-11-12 21:23:56 +0000
commitd226f7f054ad22352b1e99826218712bdd63a508 (patch)
tree38dcf834345b1cb880ef63053d93a540d9acbb3d /src/algo_factory
parent1c7f4ac5cade236cf53598abf5c043945cbc9a8f (diff)
Implement the guts of Algorithm_Factory::prototoype_X using a function
template to share the search and cache management logic across all types
Diffstat (limited to 'src/algo_factory')
-rw-r--r--src/algo_factory/algo_factory.cpp145
1 files changed, 80 insertions, 65 deletions
diff --git a/src/algo_factory/algo_factory.cpp b/src/algo_factory/algo_factory.cpp
index 8cd7d70ff..043e21459 100644
--- a/src/algo_factory/algo_factory.cpp
+++ b/src/algo_factory/algo_factory.cpp
@@ -17,10 +17,66 @@ Algorithm Factory
namespace Botan {
+namespace {
+
+/**
+* Template functions for the factory prototype/search algorithm
+*/
+template<typename T>
+T* engine_get_algo(Engine* engine, const SCAN_Name& request,
+ Algorithm_Factory& af)
+ { return 0; }
+
+template<>
+BlockCipher* engine_get_algo(Engine* engine, const SCAN_Name& request,
+ Algorithm_Factory& af)
+ { return engine->find_block_cipher(request, af); }
+
+template<>
+StreamCipher* engine_get_algo(Engine* engine, const SCAN_Name& request,
+ Algorithm_Factory& af)
+ { return engine->find_stream_cipher(request, af); }
+
+template<>
+HashFunction* engine_get_algo(Engine* engine, const SCAN_Name& request,
+ Algorithm_Factory& af)
+ { return engine->find_hash(request, af); }
+
+template<>
+MessageAuthenticationCode* engine_get_algo(Engine* engine,
+ const SCAN_Name& request,
+ Algorithm_Factory& af)
+ { return engine->find_mac(request, af); }
+
+template<typename T>
+const T* factory_prototype(const std::string& algo_spec,
+ const std::string& provider,
+ const std::vector<Engine*>& engines,
+ Algorithm_Factory& af,
+ Algorithm_Cache<T>& cache)
+ {
+ if(const T* cache_hit = cache.get(algo_spec, provider))
+ return cache_hit;
+
+ SCAN_Name scan_name(algo_spec);
+ for(u32bit i = 0; i != engines.size(); ++i)
+ {
+ T* impl = engine_get_algo<T>(engines[i], scan_name, af);
+ if(impl)
+ cache.add(impl, algo_spec, engines[i]->provider_name());
+ }
+
+ return cache.get(algo_spec, provider);
+ }
+
+}
+
/**
* Setup caches
*/
-Algorithm_Factory::Algorithm_Factory(Mutex_Factory& mf) :
+Algorithm_Factory::Algorithm_Factory(const std::vector<Engine*>& engines_in,
+ Mutex_Factory& mf) :
+ engines(engines_in),
block_cipher_cache(mf.make()),
stream_cipher_cache(mf.make()),
hash_cache(mf.make()),
@@ -38,14 +94,6 @@ Algorithm_Factory::~Algorithm_Factory()
}
/**
-* Add a new engine to the search list
-*/
-void Algorithm_Factory::add_engine(Engine* engine)
- {
- engines.insert(engines.begin(), engine);
- }
-
-/**
* Set the preferred provider for an algorithm
*/
void Algorithm_Factory::set_preferred_provider(const std::string& algo_spec,
@@ -97,17 +145,8 @@ const BlockCipher*
Algorithm_Factory::prototype_block_cipher(const std::string& algo_spec,
const std::string& provider)
{
- if(const BlockCipher* hit = block_cipher_cache.get(algo_spec, provider))
- return hit;
-
- SCAN_Name scan_name(algo_spec);
- for(u32bit i = 0; i != engines.size(); ++i)
- {
- if(BlockCipher* impl = engines[i]->find_block_cipher(scan_name, *this))
- block_cipher_cache.add(impl, algo_spec, engines[i]->provider_name());
- }
-
- return block_cipher_cache.get(algo_spec, provider);
+ return factory_prototype<BlockCipher>(algo_spec, provider, engines,
+ *this, block_cipher_cache);
}
/**
@@ -117,17 +156,8 @@ const StreamCipher*
Algorithm_Factory::prototype_stream_cipher(const std::string& algo_spec,
const std::string& provider)
{
- if(const StreamCipher* hit = stream_cipher_cache.get(algo_spec, provider))
- return hit;
-
- SCAN_Name scan_name(algo_spec);
- for(u32bit i = 0; i != engines.size(); ++i)
- {
- if(StreamCipher* impl = engines[i]->find_stream_cipher(scan_name, *this))
- stream_cipher_cache.add(impl, algo_spec, engines[i]->provider_name());
- }
-
- return stream_cipher_cache.get(algo_spec, provider);
+ return factory_prototype<StreamCipher>(algo_spec, provider, engines,
+ *this, stream_cipher_cache);
}
/**
@@ -137,17 +167,8 @@ const HashFunction*
Algorithm_Factory::prototype_hash_function(const std::string& algo_spec,
const std::string& provider)
{
- if(const HashFunction* hit = hash_cache.get(algo_spec, provider))
- return hit;
-
- SCAN_Name scan_name(algo_spec);
- for(u32bit i = 0; i != engines.size(); ++i)
- {
- if(HashFunction* impl = engines[i]->find_hash(scan_name, *this))
- hash_cache.add(impl, algo_spec, engines[i]->provider_name());
- }
-
- return hash_cache.get(algo_spec, provider);
+ return factory_prototype<HashFunction>(algo_spec, provider, engines,
+ *this, hash_cache);
}
/**
@@ -157,24 +178,16 @@ const MessageAuthenticationCode*
Algorithm_Factory::prototype_mac(const std::string& algo_spec,
const std::string& provider)
{
- if(const MessageAuthenticationCode* hit = mac_cache.get(algo_spec, provider))
- return hit;
-
- SCAN_Name scan_name(algo_spec);
- for(u32bit i = 0; i != engines.size(); ++i)
- {
- if(MessageAuthenticationCode* impl = engines[i]->find_mac(scan_name, *this))
- mac_cache.add(impl, algo_spec, engines[i]->provider_name());
- }
-
- return mac_cache.get(algo_spec, provider);
+ return factory_prototype<MessageAuthenticationCode>(algo_spec, provider, engines,
+ *this, mac_cache);
}
/**
* Return a new block cipher cooresponding to this request
*/
-BlockCipher* Algorithm_Factory::make_block_cipher(const std::string& algo_spec,
- const std::string& provider)
+BlockCipher*
+Algorithm_Factory::make_block_cipher(const std::string& algo_spec,
+ const std::string& provider)
{
if(const BlockCipher* proto = prototype_block_cipher(algo_spec, provider))
return proto->clone();
@@ -184,22 +197,24 @@ BlockCipher* Algorithm_Factory::make_block_cipher(const std::string& algo_spec,
/**
* Return a new stream cipher cooresponding to this request
*/
-StreamCipher* Algorithm_Factory::make_stream_cipher(const std::string& algo_spec,
- const std::string& provider)
+StreamCipher*
+Algorithm_Factory::make_stream_cipher(const std::string& algo_spec,
+ const std::string& provider)
{
- if(const StreamCipher* prototype = prototype_stream_cipher(algo_spec, provider))
- return prototype->clone();
+ if(const StreamCipher* proto = prototype_stream_cipher(algo_spec, provider))
+ return proto->clone();
throw Algorithm_Not_Found(algo_spec);
}
/**
* Return a new object cooresponding to this request
*/
-HashFunction* Algorithm_Factory::make_hash_function(const std::string& algo_spec,
- const std::string& provider)
+HashFunction*
+Algorithm_Factory::make_hash_function(const std::string& algo_spec,
+ const std::string& provider)
{
- if(const HashFunction* prototype = prototype_hash_function(algo_spec, provider))
- return prototype->clone();
+ if(const HashFunction* proto = prototype_hash_function(algo_spec, provider))
+ return proto->clone();
throw Algorithm_Not_Found(algo_spec);
}
@@ -210,8 +225,8 @@ MessageAuthenticationCode*
Algorithm_Factory::make_mac(const std::string& algo_spec,
const std::string& provider)
{
- if(const MessageAuthenticationCode* prototype = prototype_mac(algo_spec, provider))
- return prototype->clone();
+ if(const MessageAuthenticationCode* proto = prototype_mac(algo_spec, provider))
+ return proto->clone();
throw Algorithm_Not_Found(algo_spec);
}