From d226f7f054ad22352b1e99826218712bdd63a508 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 12 Nov 2008 21:23:56 +0000 Subject: Implement the guts of Algorithm_Factory::prototoype_X using a function template to share the search and cache management logic across all types --- src/algo_factory/algo_factory.cpp | 145 +++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 65 deletions(-) (limited to 'src/algo_factory') 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 +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 +const T* factory_prototype(const std::string& algo_spec, + const std::string& provider, + const std::vector& engines, + Algorithm_Factory& af, + Algorithm_Cache& 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(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& engines_in, + Mutex_Factory& mf) : + engines(engines_in), block_cipher_cache(mf.make()), stream_cipher_cache(mf.make()), hash_cache(mf.make()), @@ -37,14 +93,6 @@ Algorithm_Factory::~Algorithm_Factory() engines.clear(); } -/** -* 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 */ @@ -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(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(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(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(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); } -- cgit v1.2.3