aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/compression/compression.cpp39
-rw-r--r--src/lib/compression/compression.h32
-rw-r--r--src/tests/test_compression.cpp58
3 files changed, 129 insertions, 0 deletions
diff --git a/src/lib/compression/compression.cpp b/src/lib/compression/compression.cpp
index ded6b3b08..361bf7dd3 100644
--- a/src/lib/compression/compression.cpp
+++ b/src/lib/compression/compression.cpp
@@ -7,6 +7,7 @@
#include <botan/compression.h>
#include <botan/mem_ops.h>
+#include <botan/exceptn.h>
#include <cstdlib>
#if defined(BOTAN_HAS_ZLIB)
@@ -48,6 +49,25 @@ Compression_Algorithm* make_compressor(const std::string& name)
return nullptr;
}
+//static
+std::unique_ptr<Compression_Algorithm>
+Compression_Algorithm::create(const std::string& algo)
+ {
+ std::unique_ptr<Compression_Algorithm> compressor(make_compressor(algo));
+ return compressor;
+ }
+
+//static
+std::unique_ptr<Compression_Algorithm>
+Compression_Algorithm::create_or_throw(const std::string& algo)
+ {
+ if(auto compressor = Compression_Algorithm::create(algo))
+ {
+ return compressor;
+ }
+ throw Lookup_Error("Compression", algo, "");
+ }
+
Decompression_Algorithm* make_decompressor(const std::string& name)
{
#if defined(BOTAN_HAS_ZLIB)
@@ -73,5 +93,24 @@ Decompression_Algorithm* make_decompressor(const std::string& name)
return nullptr;
}
+//static
+std::unique_ptr<Decompression_Algorithm>
+Decompression_Algorithm::create(const std::string& algo)
+ {
+ std::unique_ptr<Decompression_Algorithm> decompressor(make_decompressor(algo));
+ return decompressor;
+ }
+
+//static
+std::unique_ptr<Decompression_Algorithm>
+Decompression_Algorithm::create_or_throw(const std::string& algo)
+ {
+ if(auto decompressor = Decompression_Algorithm::create(algo))
+ {
+ return decompressor;
+ }
+ throw Lookup_Error("Decompression", algo, "");
+ }
}
+
diff --git a/src/lib/compression/compression.h b/src/lib/compression/compression.h
index 2ebde3f2f..403b335e1 100644
--- a/src/lib/compression/compression.h
+++ b/src/lib/compression/compression.h
@@ -20,6 +20,22 @@ class BOTAN_PUBLIC_API(2,0) Compression_Algorithm
{
public:
/**
+ * Create an instance based on a name, or return null if the
+ * algo/provider combination cannot be found. If provider is
+ * empty then best available is chosen.
+ */
+ static std::unique_ptr<Compression_Algorithm>
+ create(const std::string& algo_spec);
+
+ /**
+ * Create an instance based on a name
+ * @param algo_spec algorithm name
+ * Throws Lookup_Error if not not found.
+ */
+ static std::unique_ptr<Compression_Algorithm>
+ create_or_throw(const std::string& algo_spec);
+
+ /**
* Begin compressing. Most compression algorithms offer a tunable
* time/compression tradeoff parameter generally represented by
* an integer in the range of 1 to 9.
@@ -66,6 +82,22 @@ class BOTAN_PUBLIC_API(2,0) Decompression_Algorithm
{
public:
/**
+ * Create an instance based on a name, or return null if the
+ * algo/provider combination cannot be found. If provider is
+ * empty then best available is chosen.
+ */
+ static std::unique_ptr<Decompression_Algorithm>
+ create(const std::string& algo_spec);
+
+ /**
+ * Create an instance based on a name
+ * @param algo_spec algorithm name
+ * Throws Lookup_Error if not not found.
+ */
+ static std::unique_ptr<Decompression_Algorithm>
+ create_or_throw(const std::string& algo_spec);
+
+ /**
* Begin decompressing.
* Decompression does not support levels, as compression does.
*/
diff --git a/src/tests/test_compression.cpp b/src/tests/test_compression.cpp
index 04eb26200..d9045b23e 100644
--- a/src/tests/test_compression.cpp
+++ b/src/tests/test_compression.cpp
@@ -154,6 +154,64 @@ class Compression_Tests final : public Test
BOTAN_REGISTER_TEST("compression", Compression_Tests);
+class CompressionCreate_Tests final : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
+
+ for(std::string algo : { "zlib", "deflate", "gzip", "bz2", "lzma" })
+ {
+ try
+ {
+ Test::Result result(algo + " create compression");
+
+ std::unique_ptr<Botan::Compression_Algorithm> c1(Botan::Compression_Algorithm::create(algo));
+ std::unique_ptr<Botan::Decompression_Algorithm> d1(Botan::Decompression_Algorithm::create(algo));
+
+ if(!c1 || !d1)
+ {
+ result.note_missing(algo);
+ continue;
+ }
+ result.test_ne("Not the same name after create", c1->name(), d1->name());
+
+ std::unique_ptr<Botan::Compression_Algorithm> c2(Botan::Compression_Algorithm::create_or_throw(algo));
+ std::unique_ptr<Botan::Decompression_Algorithm> d2(Botan::Decompression_Algorithm::create_or_throw(algo));
+
+ if(!c2 || !d2)
+ {
+ result.note_missing(algo);
+ continue;
+ }
+ result.test_ne("Not the same name after create_or_throw", c2->name(), d2->name());
+
+ results.push_back(result);
+ }
+ catch(std::exception& e)
+ {
+ results.push_back(Test::Result::Failure("testing " + algo, e.what()));
+ }
+ }
+
+ {
+ Test::Result result("create invalid compression");
+ result.test_throws("lookup error",
+ "Unavailable Compression bogocompress",
+ [&]() { Botan::Compression_Algorithm::create_or_throw("bogocompress"); });
+ result.test_throws("lookup error",
+ "Unavailable Decompression bogocompress",
+ [&]() { Botan::Decompression_Algorithm::create_or_throw("bogocompress"); });
+ results.push_back(result);
+ }
+
+ return results;
+ }
+ };
+
+BOTAN_REGISTER_TEST("create_compression", CompressionCreate_Tests);
+
}
#endif