aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/compression
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/compression')
-rw-r--r--src/lib/compression/bzip2/bzip2.cpp3
-rw-r--r--src/lib/compression/compress_utils.cpp189
-rw-r--r--src/lib/compression/compress_utils.h5
-rw-r--r--src/lib/compression/compression.cpp266
-rw-r--r--src/lib/compression/compression.h9
-rw-r--r--src/lib/compression/lzma/lzma.cpp3
-rw-r--r--src/lib/compression/zlib/zlib.cpp5
7 files changed, 248 insertions, 232 deletions
diff --git a/src/lib/compression/bzip2/bzip2.cpp b/src/lib/compression/bzip2/bzip2.cpp
index 565eb09fc..1d1af7e29 100644
--- a/src/lib/compression/bzip2/bzip2.cpp
+++ b/src/lib/compression/bzip2/bzip2.cpp
@@ -8,6 +8,7 @@
*/
#include <botan/bzip2.h>
+#include <botan/exceptn.h>
#include <botan/internal/compress_utils.h>
#define BZ_NO_STDIO
@@ -15,8 +16,6 @@
namespace Botan {
-BOTAN_REGISTER_COMPRESSION(Bzip2_Compression, Bzip2_Decompression);
-
namespace {
class Bzip2_Stream : public Zlib_Style_Stream<bz_stream, char>
diff --git a/src/lib/compression/compress_utils.cpp b/src/lib/compression/compress_utils.cpp
new file mode 100644
index 000000000..2af629b9c
--- /dev/null
+++ b/src/lib/compression/compress_utils.cpp
@@ -0,0 +1,189 @@
+/*
+* Compression Utils
+* (C) 2014,2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/internal/compress_utils.h>
+#include <botan/exceptn.h>
+
+namespace Botan {
+
+void* Compression_Alloc_Info::do_malloc(size_t n, size_t size)
+ {
+ const size_t total_size = n * size;
+
+ BOTAN_ASSERT_EQUAL(total_size / size, n, "Overflow check");
+
+ // TODO maximum length check here?
+
+ void* ptr = std::malloc(total_size);
+
+ /*
+ * Return null rather than throwing here as we are being called by a
+ * C library and it may not be possible for an exception to unwind
+ * the call stack from here. The compression library is expecting a
+ * function written in C and a null return on error, which it will
+ * send upwards to the compression wrappers.
+ */
+
+ if(ptr)
+ {
+ std::memset(ptr, 0, total_size);
+ m_current_allocs[ptr] = total_size;
+ }
+
+ return ptr;
+ }
+
+void Compression_Alloc_Info::do_free(void* ptr)
+ {
+ if(ptr)
+ {
+ auto i = m_current_allocs.find(ptr);
+
+ if(i == m_current_allocs.end())
+ throw Exception("Compression_Alloc_Info::free got pointer not allocated by us");
+
+ zero_mem(ptr, i->second);
+ std::free(ptr);
+ m_current_allocs.erase(i);
+ }
+ }
+
+void Stream_Compression::clear()
+ {
+ m_stream.reset();
+ }
+
+void Stream_Compression::start(size_t level)
+ {
+ m_stream.reset(make_stream(level));
+ }
+
+void Stream_Compression::process(secure_vector<byte>& buf, size_t offset, u32bit flags)
+ {
+ BOTAN_ASSERT(m_stream, "Initialized");
+ BOTAN_ASSERT(buf.size() >= offset, "Offset is sane");
+
+ if(m_buffer.size() < buf.size() + offset)
+ m_buffer.resize(buf.size() + offset);
+
+ // If the output buffer has zero length, .data() might return nullptr. This would
+ // make some compression algorithms (notably those provided by zlib) fail.
+ // Any small positive value works fine, but we choose 32 as it is the smallest power
+ // of two that is large enough to hold all the headers and trailers of the common
+ // formats, preventing further resizings to make room for output data.
+ if(m_buffer.size() == 0)
+ m_buffer.resize(32);
+
+ m_stream->next_in(buf.data() + offset, buf.size() - offset);
+ m_stream->next_out(m_buffer.data() + offset, m_buffer.size() - offset);
+
+ while(true)
+ {
+ m_stream->run(flags);
+
+ if(m_stream->avail_out() == 0)
+ {
+ const size_t added = 8 + m_buffer.size();
+ m_buffer.resize(m_buffer.size() + added);
+ m_stream->next_out(m_buffer.data() + m_buffer.size() - added, added);
+ }
+ else if(m_stream->avail_in() == 0)
+ {
+ m_buffer.resize(m_buffer.size() - m_stream->avail_out());
+ break;
+ }
+ }
+
+ copy_mem(m_buffer.data(), buf.data(), offset);
+ buf.swap(m_buffer);
+ }
+
+void Stream_Compression::update(secure_vector<byte>& buf, size_t offset, bool flush)
+ {
+ BOTAN_ASSERT(m_stream, "Initialized");
+ process(buf, offset, flush ? m_stream->flush_flag() : m_stream->run_flag());
+ }
+
+void Stream_Compression::finish(secure_vector<byte>& buf, size_t offset)
+ {
+ BOTAN_ASSERT(m_stream, "Initialized");
+ process(buf, offset, m_stream->finish_flag());
+ clear();
+ }
+
+void Stream_Decompression::clear()
+ {
+ m_stream.reset();
+ }
+
+void Stream_Decompression::start()
+ {
+ m_stream.reset(make_stream());
+ }
+
+void Stream_Decompression::process(secure_vector<byte>& buf, size_t offset, u32bit flags)
+ {
+ BOTAN_ASSERT(m_stream, "Initialized");
+ BOTAN_ASSERT(buf.size() >= offset, "Offset is sane");
+
+ if(m_buffer.size() < buf.size() + offset)
+ m_buffer.resize(buf.size() + offset);
+
+ m_stream->next_in(buf.data() + offset, buf.size() - offset);
+ m_stream->next_out(m_buffer.data() + offset, m_buffer.size() - offset);
+
+ while(true)
+ {
+ const bool stream_end = m_stream->run(flags);
+
+ if(stream_end)
+ {
+ if(m_stream->avail_in() == 0) // all data consumed?
+ {
+ m_buffer.resize(m_buffer.size() - m_stream->avail_out());
+ clear();
+ break;
+ }
+
+ // More data follows: try to process as a following stream
+ const size_t read = (buf.size() - offset) - m_stream->avail_in();
+ start();
+ m_stream->next_in(buf.data() + offset + read, buf.size() - offset - read);
+ }
+
+ if(m_stream->avail_out() == 0)
+ {
+ const size_t added = 8 + m_buffer.size();
+ m_buffer.resize(m_buffer.size() + added);
+ m_stream->next_out(m_buffer.data() + m_buffer.size() - added, added);
+ }
+ else if(m_stream->avail_in() == 0)
+ {
+ m_buffer.resize(m_buffer.size() - m_stream->avail_out());
+ break;
+ }
+ }
+
+ copy_mem(m_buffer.data(), buf.data(), offset);
+ buf.swap(m_buffer);
+ }
+
+void Stream_Decompression::update(secure_vector<byte>& buf, size_t offset)
+ {
+ process(buf, offset, m_stream->run_flag());
+ }
+
+void Stream_Decompression::finish(secure_vector<byte>& buf, size_t offset)
+ {
+ if(buf.size() != offset || m_stream.get())
+ process(buf, offset, m_stream->finish_flag());
+
+ if(m_stream.get())
+ throw Exception(name() + " finished but not at stream end");
+ }
+
+}
diff --git a/src/lib/compression/compress_utils.h b/src/lib/compression/compress_utils.h
index a60ae3c22..9f6871a0b 100644
--- a/src/lib/compression/compress_utils.h
+++ b/src/lib/compression/compress_utils.h
@@ -9,7 +9,6 @@
#define BOTAN_COMPRESSION_UTILS_H__
#include <botan/compression.h>
-#include <botan/internal/algo_registry.h>
#include <memory>
#include <unordered_map>
@@ -85,10 +84,6 @@ class Zlib_Style_Stream : public Compression_Stream
std::unique_ptr<Compression_Alloc_Info> m_allocs;
};
-#define BOTAN_REGISTER_COMPRESSION(C, D) \
- BOTAN_REGISTER_T_NOARGS(Compression_Algorithm, C); \
- BOTAN_REGISTER_T_NOARGS(Decompression_Algorithm, D)
-
}
#endif
diff --git a/src/lib/compression/compression.cpp b/src/lib/compression/compression.cpp
index f289aa79f..92004a071 100644
--- a/src/lib/compression/compression.cpp
+++ b/src/lib/compression/compression.cpp
@@ -1,233 +1,75 @@
/*
-* Compression Transform
-* (C) 2014 Jack Lloyd
+* Compression Factory
+* (C) 2014,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/compression.h>
-#include <botan/internal/compress_utils.h>
#include <botan/mem_ops.h>
#include <cstdlib>
-namespace Botan {
-
-void* Compression_Alloc_Info::do_malloc(size_t n, size_t size)
- {
- const size_t total_size = n * size;
-
- BOTAN_ASSERT_EQUAL(total_size / size, n, "Overflow check");
-
- // TODO maximum length check here?
-
- void* ptr = std::malloc(total_size);
-
- /*
- * Return null rather than throwing here as we are being called by a
- * C library and it may not be possible for an exception to unwind
- * the call stack from here. The compression library is expecting a
- * function written in C and a null return on error, which it will
- * send upwards to the compression wrappers.
- */
-
- if(ptr)
- {
- std::memset(ptr, 0, total_size);
- m_current_allocs[ptr] = total_size;
- }
-
- return ptr;
- }
-
-void Compression_Alloc_Info::do_free(void* ptr)
- {
- if(ptr)
- {
- auto i = m_current_allocs.find(ptr);
-
- if(i == m_current_allocs.end())
- throw Exception("Compression_Alloc_Info::free got pointer not allocated by us");
-
- zero_mem(ptr, i->second);
- std::free(ptr);
- m_current_allocs.erase(i);
- }
- }
-
-Compression_Algorithm* make_compressor(const std::string& type)
- {
- const std::map<std::string, std::string> trans{
- {"zlib", "Zlib"},
- {"deflate", "Deflate"},
- {"gzip", "Gzip"},
- {"gz", "Gzip"},
- {"bzip2", "Bzip2"},
- {"bz2", "Bzip2"},
- {"lzma", "LZMA"},
- {"xz", "LZMA"}};
-
- auto i = trans.find(type);
-
- if(i == trans.end())
- return nullptr;
-
- const SCAN_Name t_name(i->second + "_Compression");
- return Algo_Registry<Compression_Algorithm>::global_registry().make(t_name);
- }
-
-Decompression_Algorithm* make_decompressor(const std::string& type)
- {
- const std::map<std::string, std::string> trans{
- {"zlib", "Zlib"},
- {"deflate", "Deflate"},
- {"gzip", "Gzip"},
- {"gz", "Gzip"},
- {"bzip2", "Bzip2"},
- {"bz2", "Bzip2"},
- {"lzma", "LZMA"},
- {"xz", "LZMA"}};
-
- auto i = trans.find(type);
-
- if(i == trans.end())
- return nullptr;
-
- const SCAN_Name t_name(i->second + "_Decompression");
- return Algo_Registry<Decompression_Algorithm>::global_registry().make(t_name);
- }
-
-void Stream_Compression::clear()
- {
- m_stream.reset();
- }
-
-void Stream_Compression::start(size_t level)
- {
- m_stream.reset(make_stream(level));
- }
-
-void Stream_Compression::process(secure_vector<byte>& buf, size_t offset, u32bit flags)
- {
- BOTAN_ASSERT(m_stream, "Initialized");
- BOTAN_ASSERT(buf.size() >= offset, "Offset is sane");
-
- if(m_buffer.size() < buf.size() + offset)
- m_buffer.resize(buf.size() + offset);
-
- // If the output buffer has zero length, .data() might return nullptr. This would
- // make some compression algorithms (notably those provided by zlib) fail.
- // Any small positive value works fine, but we choose 32 as it is the smallest power
- // of two that is large enough to hold all the headers and trailers of the common
- // formats, preventing further resizings to make room for output data.
- if(m_buffer.size() == 0)
- m_buffer.resize(32);
-
- m_stream->next_in(buf.data() + offset, buf.size() - offset);
- m_stream->next_out(m_buffer.data() + offset, m_buffer.size() - offset);
-
- while(true)
- {
- m_stream->run(flags);
+#if defined(BOTAN_HAS_ZLIB)
+ #include <botan/zlib.h>
+#endif
- if(m_stream->avail_out() == 0)
- {
- const size_t added = 8 + m_buffer.size();
- m_buffer.resize(m_buffer.size() + added);
- m_stream->next_out(m_buffer.data() + m_buffer.size() - added, added);
- }
- else if(m_stream->avail_in() == 0)
- {
- m_buffer.resize(m_buffer.size() - m_stream->avail_out());
- break;
- }
- }
+#if defined(BOTAN_HAS_BZIP2)
+ #include <botan/bzip2.h>
+#endif
- copy_mem(m_buffer.data(), buf.data(), offset);
- buf.swap(m_buffer);
- }
-
-void Stream_Compression::update(secure_vector<byte>& buf, size_t offset, bool flush)
- {
- BOTAN_ASSERT(m_stream, "Initialized");
- process(buf, offset, flush ? m_stream->flush_flag() : m_stream->run_flag());
- }
+#if defined(BOTAN_HAS_LZMA)
+ #include <botan/lzma.h>
+#endif
-void Stream_Compression::finish(secure_vector<byte>& buf, size_t offset)
- {
- BOTAN_ASSERT(m_stream, "Initialized");
- process(buf, offset, m_stream->finish_flag());
- clear();
- }
-
-void Stream_Decompression::clear()
- {
- m_stream.reset();
- }
+namespace Botan {
-void Stream_Decompression::start()
+Compression_Algorithm* make_compressor(const std::string& name)
{
- m_stream.reset(make_stream());
+#if defined(BOTAN_HAS_ZLIB)
+ if(name == "Zlib" || name == "zlib")
+ return new Zlib_Compression;
+ if(name == "Gzip" || name == "gzip" || name == "gz")
+ return new Gzip_Compression;
+ if(name == "Deflate" || name == "deflate")
+ return new Deflate_Compression;
+#endif
+
+#if defined(BOTAN_HAS_BZIP2)
+ if(name == "bzip2" || name == "bz2" || name == "Bzip2")
+ return new Bzip2_Compression;
+#endif
+
+#if defined(BOTAN_HAS_LZMA)
+ if(name == "lzma" || name == "xz" || name == "LZMA")
+ return new LZMA_Compression;
+#endif
+
+ return nullptr;
}
-void Stream_Decompression::process(secure_vector<byte>& buf, size_t offset, u32bit flags)
+Decompression_Algorithm* make_decompressor(const std::string& name)
{
- BOTAN_ASSERT(m_stream, "Initialized");
- BOTAN_ASSERT(buf.size() >= offset, "Offset is sane");
-
- if(m_buffer.size() < buf.size() + offset)
- m_buffer.resize(buf.size() + offset);
-
- m_stream->next_in(buf.data() + offset, buf.size() - offset);
- m_stream->next_out(m_buffer.data() + offset, m_buffer.size() - offset);
-
- while(true)
- {
- const bool stream_end = m_stream->run(flags);
-
- if(stream_end)
- {
- if(m_stream->avail_in() == 0) // all data consumed?
- {
- m_buffer.resize(m_buffer.size() - m_stream->avail_out());
- clear();
- break;
- }
-
- // More data follows: try to process as a following stream
- const size_t read = (buf.size() - offset) - m_stream->avail_in();
- start();
- m_stream->next_in(buf.data() + offset + read, buf.size() - offset - read);
- }
-
- if(m_stream->avail_out() == 0)
- {
- const size_t added = 8 + m_buffer.size();
- m_buffer.resize(m_buffer.size() + added);
- m_stream->next_out(m_buffer.data() + m_buffer.size() - added, added);
- }
- else if(m_stream->avail_in() == 0)
- {
- m_buffer.resize(m_buffer.size() - m_stream->avail_out());
- break;
- }
- }
-
- copy_mem(m_buffer.data(), buf.data(), offset);
- buf.swap(m_buffer);
- }
-
-void Stream_Decompression::update(secure_vector<byte>& buf, size_t offset)
- {
- process(buf, offset, m_stream->run_flag());
+#if defined(BOTAN_HAS_ZLIB)
+ if(name == "Zlib" || name == "zlib")
+ return new Zlib_Decompression;
+ if(name == "Gzip" || name == "gzip" || name == "gz")
+ return new Gzip_Decompression;
+ if(name == "Deflate" || name == "deflate")
+ return new Deflate_Decompression;
+#endif
+
+#if defined(BOTAN_HAS_BZIP2)
+ if(name == "bzip2" || name == "bz2" || name == "Bzip2")
+ return new Bzip2_Decompression;
+#endif
+
+#if defined(BOTAN_HAS_LZMA)
+ if(name == "lzma" || name == "xz" || name == "LZMA")
+ return new LZMA_Decompression;
+#endif
+
+ return nullptr;
}
-void Stream_Decompression::finish(secure_vector<byte>& buf, size_t offset)
- {
- if(buf.size() != offset || m_stream.get())
- process(buf, offset, m_stream->finish_flag());
-
- if(m_stream.get())
- throw Exception(name() + " finished but not at stream end");
- }
}
diff --git a/src/lib/compression/compression.h b/src/lib/compression/compression.h
index f135f6d04..693772b6a 100644
--- a/src/lib/compression/compression.h
+++ b/src/lib/compression/compression.h
@@ -9,7 +9,6 @@
#define BOTAN_COMPRESSION_TRANSFORM_H__
#include <botan/secmem.h>
-#include <botan/scan_name.h>
namespace Botan {
@@ -19,8 +18,6 @@ namespace Botan {
class BOTAN_DLL Compression_Algorithm
{
public:
- typedef SCAN_Name Spec;
-
/**
* Begin compressing. Most compression algorithms offer a tunable
* time/compression tradeoff parameter generally represented by
@@ -67,8 +64,6 @@ class BOTAN_DLL Compression_Algorithm
class BOTAN_DLL Decompression_Algorithm
{
public:
- typedef SCAN_Name Spec;
-
/**
* Begin decompressing.
* Decompression does not support levels, as compression does.
@@ -108,7 +103,7 @@ BOTAN_DLL Compression_Algorithm* make_compressor(const std::string& type);
BOTAN_DLL Decompression_Algorithm* make_decompressor(const std::string& type);
/**
-* FIXME add doc
+* Adapts a zlib style API
*/
class Compression_Stream
{
@@ -131,7 +126,7 @@ class Compression_Stream
};
/**
-* FIXME add doc
+* Used to implement compression using Compression_Stream
*/
class Stream_Compression : public Compression_Algorithm
{
diff --git a/src/lib/compression/lzma/lzma.cpp b/src/lib/compression/lzma/lzma.cpp
index 18701278d..3831ef68c 100644
--- a/src/lib/compression/lzma/lzma.cpp
+++ b/src/lib/compression/lzma/lzma.cpp
@@ -10,12 +10,11 @@
#include <botan/lzma.h>
#include <botan/internal/compress_utils.h>
+#include <botan/exceptn.h>
#include <lzma.h>
namespace Botan {
-BOTAN_REGISTER_COMPRESSION(LZMA_Compression, LZMA_Decompression);
-
namespace {
class LZMA_Stream : public Zlib_Style_Stream<lzma_stream, byte>
diff --git a/src/lib/compression/zlib/zlib.cpp b/src/lib/compression/zlib/zlib.cpp
index 836925a68..27ae6fb20 100644
--- a/src/lib/compression/zlib/zlib.cpp
+++ b/src/lib/compression/zlib/zlib.cpp
@@ -9,15 +9,12 @@
#include <botan/zlib.h>
#include <botan/internal/compress_utils.h>
+#include <botan/exceptn.h>
#include <ctime>
#include <zlib.h>
namespace Botan {
-BOTAN_REGISTER_COMPRESSION(Zlib_Compression, Zlib_Decompression);
-BOTAN_REGISTER_COMPRESSION(Gzip_Compression, Gzip_Decompression);
-BOTAN_REGISTER_COMPRESSION(Deflate_Compression, Deflate_Decompression);
-
namespace {
class Zlib_Stream : public Zlib_Style_Stream<z_stream, Bytef>