diff options
author | lloyd <[email protected]> | 2014-11-18 13:42:36 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2014-11-18 13:42:36 +0000 |
commit | dec2e0d9e493b53c48ca26b47028ab309d3cc586 (patch) | |
tree | 2242f756ece5e1a9cc728dc208c154e694314d5a /src/lib/compression | |
parent | b5e2a1ce3044084e43ff523f148b0cc8e95ce283 (diff) |
Convert compression filters to in-place transforms and refactor
to minimize the amount of logic needed in the files specific to each
library.
Diffstat (limited to 'src/lib/compression')
-rw-r--r-- | src/lib/compression/bzip2/bzip2.cpp | 112 | ||||
-rw-r--r-- | src/lib/compression/bzip2/bzip2.h | 50 | ||||
-rw-r--r-- | src/lib/compression/bzip2/info.txt | 7 | ||||
-rw-r--r-- | src/lib/compression/comp_util.cpp | 34 | ||||
-rw-r--r-- | src/lib/compression/comp_util.h | 90 | ||||
-rw-r--r-- | src/lib/compression/compression.cpp | 152 | ||||
-rw-r--r-- | src/lib/compression/compression.h | 99 | ||||
-rw-r--r-- | src/lib/compression/info.txt | 9 | ||||
-rw-r--r-- | src/lib/compression/lzma/info.txt | 7 | ||||
-rw-r--r-- | src/lib/compression/lzma/lzma.cpp | 94 | ||||
-rw-r--r-- | src/lib/compression/lzma/lzma.h | 51 | ||||
-rw-r--r-- | src/lib/compression/zlib/info.txt | 7 | ||||
-rw-r--r-- | src/lib/compression/zlib/zlib.cpp | 106 | ||||
-rw-r--r-- | src/lib/compression/zlib/zlib.h | 61 |
14 files changed, 879 insertions, 0 deletions
diff --git a/src/lib/compression/bzip2/bzip2.cpp b/src/lib/compression/bzip2/bzip2.cpp new file mode 100644 index 000000000..440c21477 --- /dev/null +++ b/src/lib/compression/bzip2/bzip2.cpp @@ -0,0 +1,112 @@ +/* +* Bzip Compressor +* (C) 2001 Peter J Jones +* 2001-2007,2014 Jack Lloyd +* 2006 Matt Johnston +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/bzip2.h> +#include <botan/internal/comp_util.h> + +#define BZ_NO_STDIO +#include <bzlib.h> + +namespace Botan { + +namespace { + +class Bzip_Stream : public Zlib_Style_Stream<bz_stream, char> + { + public: + Bzip_Stream() + { + streamp()->opaque = alloc(); + streamp()->bzalloc = Compression_Alloc_Info::malloc<int>; + streamp()->bzfree = Compression_Alloc_Info::free; + } + + u32bit run_flag() const override { return BZ_RUN; } + u32bit flush_flag() const override { return BZ_FLUSH; } + u32bit finish_flag() const override { return BZ_FINISH; } + }; + +class Bzip_Compression_Stream : public Bzip_Stream + { + public: + Bzip_Compression_Stream(size_t level) + { + int rc = BZ2_bzCompressInit(streamp(), level, 0, 0); + + if(rc == BZ_MEM_ERROR) + throw std::bad_alloc(); + else if(rc != BZ_OK) + throw std::runtime_error("bzip compress initialization failed"); + } + + ~Bzip_Compression_Stream() + { + BZ2_bzCompressEnd(streamp()); + } + + bool run(u32bit flags) override + { + int rc = BZ2_bzCompress(streamp(), flags); + + if(rc == BZ_MEM_ERROR) + throw std::bad_alloc(); + else if(rc < 0) + throw std::runtime_error("bzip compress error"); + + return (rc == BZ_STREAM_END); + } + + private: + size_t m_level; + }; + +class Bzip_Decompression_Stream : public Bzip_Stream + { + public: + Bzip_Decompression_Stream() + { + int rc = BZ2_bzDecompressInit(streamp(), 0, 0); + + if(rc == BZ_MEM_ERROR) + throw std::bad_alloc(); + else if(rc != BZ_OK) + throw std::runtime_error("bzip decompress initialization failed"); + } + + ~Bzip_Decompression_Stream() + { + BZ2_bzDecompressEnd(streamp()); + } + + bool run(u32bit flags) override + { + int rc = BZ2_bzDecompress(streamp()); + + if(rc == BZ_MEM_ERROR) + throw std::bad_alloc(); + else if(rc != BZ_OK && rc != BZ_STREAM_END) + throw std::runtime_error("bzip decompress error"); + + return (rc == BZ_STREAM_END); + } + }; + +} + +Compression_Stream* Bzip_Compression::make_stream() const + { + return new Bzip_Compression_Stream(m_level); + } + +Compression_Stream* Bzip_Decompression::make_stream() const + { + return new Bzip_Decompression_Stream; + } + +} diff --git a/src/lib/compression/bzip2/bzip2.h b/src/lib/compression/bzip2/bzip2.h new file mode 100644 index 000000000..945f6a051 --- /dev/null +++ b/src/lib/compression/bzip2/bzip2.h @@ -0,0 +1,50 @@ +/* +* Bzip Compressor +* (C) 2001 Peter J Jones +* 2001-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_BZIP2_H__ +#define BOTAN_BZIP2_H__ + +#include <botan/compression.h> + +namespace Botan { + +/** +* Bzip Compression +*/ +class BOTAN_DLL Bzip_Compression : public Stream_Compression + { + public: + /** + * @param level how much effort to use on compressing (0 to 9); + * higher levels are slower but tend to give better + * compression + */ + Bzip_Compression(size_t level = 6) : m_level(level) {} + + std::string name() const override { return "Bzip_Compression"; } + + private: + Compression_Stream* make_stream() const; + + const size_t m_level; + }; + +/** +* Bzip Deccompression +*/ +class BOTAN_DLL Bzip_Decompression : public Stream_Decompression + { + public: + std::string name() const override { return "Bzip_Decompression"; } + private: + Compression_Stream* make_stream() const; + }; + +} + +#endif diff --git a/src/lib/compression/bzip2/info.txt b/src/lib/compression/bzip2/info.txt new file mode 100644 index 000000000..a0f8d82ee --- /dev/null +++ b/src/lib/compression/bzip2/info.txt @@ -0,0 +1,7 @@ +define BZIP2_TRANSFORM 20141118 + +load_on request + +<libs> +all -> bz2 +</libs> diff --git a/src/lib/compression/comp_util.cpp b/src/lib/compression/comp_util.cpp new file mode 100644 index 000000000..7fca1852d --- /dev/null +++ b/src/lib/compression/comp_util.cpp @@ -0,0 +1,34 @@ +/* +* Allocation Tracker +* (C) 2014 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/internal/comp_util.h> +#include <cstring> +#include <cstdlib> + +namespace Botan { + +void* Compression_Alloc_Info::do_malloc(size_t n, size_t size) + { + const size_t total_sz = n * size; + + void* ptr = std::malloc(total_sz); + m_current_allocs[ptr] = total_sz; + return ptr; + } + +void Compression_Alloc_Info::do_free(void* ptr) + { + auto i = m_current_allocs.find(ptr); + if(i == m_current_allocs.end()) + throw std::runtime_error("Compression_Alloc_Info::free got pointer not allocated by us"); + + std::memset(ptr, 0, i->second); + std::free(ptr); + m_current_allocs.erase(i); + } + +} diff --git a/src/lib/compression/comp_util.h b/src/lib/compression/comp_util.h new file mode 100644 index 000000000..15fc23418 --- /dev/null +++ b/src/lib/compression/comp_util.h @@ -0,0 +1,90 @@ +/* +* Shared code for compression libraries +* (C) 2014 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_COMPRESSION_UTILS_H__ +#define BOTAN_COMPRESSION_UTILS_H__ + +#include <botan/compression.h> +#include <cstring> +#include <memory> +#include <unordered_map> + +namespace Botan { + +/* +* Allocation Size Tracking Helper for Zlib/Bzlib/LZMA +*/ +class Compression_Alloc_Info + { + public: + template<typename T> + static void* malloc(void* self, T n, T size) + { + return static_cast<Compression_Alloc_Info*>(self)->do_malloc(n, size); + } + + static void free(void* self, void* ptr) + { + static_cast<Compression_Alloc_Info*>(self)->do_free(ptr); + } + + private: + void* do_malloc(size_t n, size_t size); + void do_free(void* ptr); + + std::unordered_map<void*, size_t> m_current_allocs; + }; + +/** +* Wrapper for Zlib/Bzlib/LZMA stream types +*/ +template<typename Stream, typename ByteType> +class Zlib_Style_Stream : public Compression_Stream + { + public: + void next_in(byte* b, size_t len) override + { + m_stream.next_in = reinterpret_cast<ByteType*>(b); + m_stream.avail_in = len; + } + + void next_out(byte* b, size_t len) override + { + m_stream.next_out = reinterpret_cast<ByteType*>(b); + m_stream.avail_out = len; + } + + size_t avail_in() const override { return m_stream.avail_in; } + + size_t avail_out() const override { return m_stream.avail_out; } + + Zlib_Style_Stream() + { + std::memset(&m_stream, 0, sizeof(stream_t)); + m_allocs.reset(new Compression_Alloc_Info); + } + + ~Zlib_Style_Stream() + { + std::memset(&m_stream, 0, sizeof(stream_t)); + m_allocs.reset(); + } + + protected: + typedef Stream stream_t; + + stream_t* streamp() { return &m_stream; } + + Compression_Alloc_Info* alloc() { return m_allocs.get(); } + private: + stream_t m_stream; + std::unique_ptr<Compression_Alloc_Info> m_allocs; + }; + +} + +#endif diff --git a/src/lib/compression/compression.cpp b/src/lib/compression/compression.cpp new file mode 100644 index 000000000..3eb26e81b --- /dev/null +++ b/src/lib/compression/compression.cpp @@ -0,0 +1,152 @@ +/* +* Compression Transform +* (C) 2014 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/compression.h> + +namespace Botan { + +void Stream_Compression::clear() + { + m_stream.reset(); + } + +secure_vector<byte> Stream_Compression::start_raw(const byte[], size_t nonce_len) + { + if(!valid_nonce_length(nonce_len)) + throw Invalid_IV_Length(name(), nonce_len); + + clear(); + m_stream.reset(make_stream()); + return secure_vector<byte>(); + } + +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); + + m_stream->next_in(&buf[offset], buf.size() - offset); + m_stream->next_out(&m_buffer[offset], m_buffer.size() - offset); + + while(true) + { + const bool end = 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[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[0], &buf[0], offset); + buf.swap(m_buffer); + } + +void Stream_Compression::update(secure_vector<byte>& buf, size_t offset) + { + process(buf, offset, m_stream->run_flag()); + } + +void Stream_Compression::flush(secure_vector<byte>& buf, size_t offset) + { + process(buf, offset, m_stream->flush_flag()); + } + +void Stream_Compression::finish(secure_vector<byte>& buf, size_t offset) + { + process(buf, offset, m_stream->finish_flag()); + clear(); + } + +void Stream_Decompression::clear() + { + m_stream.reset(); + } + +secure_vector<byte> Stream_Decompression::start_raw(const byte[], size_t nonce_len) + { + if(!valid_nonce_length(nonce_len)) + throw Invalid_IV_Length(name(), nonce_len); + + clear(); + m_stream.reset(make_stream()); + + return secure_vector<byte>(); + } + +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[offset], buf.size() - offset); + m_stream->next_out(&m_buffer[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[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[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[0], &buf[0], 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 std::runtime_error(name() + " finished but not at stream end"); + } + +} diff --git a/src/lib/compression/compression.h b/src/lib/compression/compression.h new file mode 100644 index 000000000..10c7f1a64 --- /dev/null +++ b/src/lib/compression/compression.h @@ -0,0 +1,99 @@ +/* +* Compression Transform +* (C) 2014 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_COMPRESSION_TRANSFORM_H__ +#define BOTAN_COMPRESSION_TRANSFORM_H__ + +#include <botan/transform.h> + +namespace Botan { + +class BOTAN_DLL Compressor_Transformation : public Transformation + { + public: + size_t update_granularity() const override { return 1; } + + size_t minimum_final_size() const override { return 0; } + + size_t default_nonce_length() const override { return 0; } + + bool valid_nonce_length(size_t nonce_len) const override + { return nonce_len == 0; } + + virtual void flush(secure_vector<byte>& buf, size_t offset = 0) { update(buf, offset); } + + size_t output_length(size_t) const override + { + throw std::runtime_error(name() + " output length indeterminate"); + } + }; + +class Compression_Stream + { + public: + virtual ~Compression_Stream() {} + + virtual void next_in(byte* b, size_t len) = 0; + + virtual void next_out(byte* b, size_t len) = 0; + + virtual size_t avail_in() const = 0; + + virtual size_t avail_out() const = 0; + + virtual u32bit run_flag() const = 0; + virtual u32bit flush_flag() const = 0; + virtual u32bit finish_flag() const = 0; + + virtual bool run(u32bit flags) = 0; + }; + +class BOTAN_DLL Stream_Compression : public Compressor_Transformation + { + public: + void update(secure_vector<byte>& buf, size_t offset = 0) override; + + void flush(secure_vector<byte>& buf, size_t offset = 0) override; + + void finish(secure_vector<byte>& buf, size_t offset = 0) override; + + void clear() override; + + private: + secure_vector<byte> start_raw(const byte[], size_t) override; + + void process(secure_vector<byte>& buf, size_t offset, u32bit flags); + + virtual Compression_Stream* make_stream() const = 0; + + secure_vector<byte> m_buffer; + std::unique_ptr<Compression_Stream> m_stream; + }; + +class BOTAN_DLL Stream_Decompression : public Compressor_Transformation + { + public: + void update(secure_vector<byte>& buf, size_t offset = 0) override; + + void finish(secure_vector<byte>& buf, size_t offset = 0) override; + + void clear() override; + + private: + secure_vector<byte> start_raw(const byte[], size_t) override; + + void process(secure_vector<byte>& buf, size_t offset, u32bit flags); + + virtual Compression_Stream* make_stream() const = 0; + + secure_vector<byte> m_buffer; + std::unique_ptr<Compression_Stream> m_stream; + }; + +} + +#endif diff --git a/src/lib/compression/info.txt b/src/lib/compression/info.txt new file mode 100644 index 000000000..f1a3fa696 --- /dev/null +++ b/src/lib/compression/info.txt @@ -0,0 +1,9 @@ +define COMPRESSION 20141117 + +<header:internal> +comp_util.h +</header:internal> + +<header:public> +compression.h +</header:public> diff --git a/src/lib/compression/lzma/info.txt b/src/lib/compression/lzma/info.txt new file mode 100644 index 000000000..1ec668ca8 --- /dev/null +++ b/src/lib/compression/lzma/info.txt @@ -0,0 +1,7 @@ +define LZMA_TRANSFORM 20141118 + +load_on request + +<libs> +all -> lzma +</libs> diff --git a/src/lib/compression/lzma/lzma.cpp b/src/lib/compression/lzma/lzma.cpp new file mode 100644 index 000000000..d145ed305 --- /dev/null +++ b/src/lib/compression/lzma/lzma.cpp @@ -0,0 +1,94 @@ +/* +* Lzma Compressor +* (C) 2001 Peter J Jones +* 2001-2007,2014 Jack Lloyd +* 2006 Matt Johnston +* 2012 Vojtech Kral +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/lzma.h> +#include <botan/internal/comp_util.h> +#include <lzma.h> + +namespace Botan { + +namespace { + +class LZMA_Stream : public Zlib_Style_Stream<lzma_stream, byte> + { + public: + LZMA_Stream() + { + streamp()->allocator = new ::lzma_allocator; + streamp()->allocator->opaque = alloc(); + streamp()->allocator->alloc = Compression_Alloc_Info::malloc<size_t>; + streamp()->allocator->free = Compression_Alloc_Info::free; + } + + ~LZMA_Stream() + { + ::lzma_end(streamp()); + delete streamp()->allocator; + } + + bool run(u32bit flags) override + { + lzma_ret rc = ::lzma_code(streamp(), static_cast<lzma_action>(flags)); + + if(rc == LZMA_MEM_ERROR) + throw std::bad_alloc(); + else if (rc != LZMA_OK && rc != LZMA_STREAM_END) + throw std::runtime_error("Lzma error"); + + return (rc == LZMA_STREAM_END); + } + + u32bit run_flag() const override { return LZMA_RUN; } + u32bit flush_flag() const override { return LZMA_FULL_FLUSH; } + u32bit finish_flag() const override { return LZMA_FINISH; } + }; + +class LZMA_Compression_Stream : public LZMA_Stream + { + public: + LZMA_Compression_Stream(size_t level) + { + lzma_ret rc = ::lzma_easy_encoder(streamp(), level, LZMA_CHECK_CRC64); + + if(rc == LZMA_MEM_ERROR) + throw std::bad_alloc(); + else if(rc != LZMA_OK) + throw std::runtime_error("lzma compress initialization failed"); + } + }; + +class LZMA_Decompression_Stream : public LZMA_Stream + { + public: + LZMA_Decompression_Stream() + { + lzma_ret rc = ::lzma_stream_decoder(streamp(), UINT64_MAX, + LZMA_TELL_UNSUPPORTED_CHECK); + + if(rc == LZMA_MEM_ERROR) + throw std::bad_alloc(); + else if(rc != LZMA_OK) + throw std::runtime_error("Bad setting in lzma_stream_decoder"); + } + }; + +} + +Compression_Stream* LZMA_Compression::make_stream() const + { + return new LZMA_Compression_Stream(m_level); + } + +Compression_Stream* LZMA_Decompression::make_stream() const + { + return new LZMA_Decompression_Stream; + } + +} diff --git a/src/lib/compression/lzma/lzma.h b/src/lib/compression/lzma/lzma.h new file mode 100644 index 000000000..0761a8194 --- /dev/null +++ b/src/lib/compression/lzma/lzma.h @@ -0,0 +1,51 @@ +/* +* Lzma Compressor +* (C) 2001 Peter J Jones +* 2001-2007 Jack Lloyd +* 2012 Vojtech Kral +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_LZMA_H__ +#define BOTAN_LZMA_H__ + +#include <botan/compression.h> + +namespace Botan { + +/** +* LZMA Compression +*/ +class BOTAN_DLL LZMA_Compression : public Stream_Compression + { + public: + /** + * @param level how much effort to use on compressing (0 to 9); + * higher levels are slower but tend to give better + * compression + */ + LZMA_Compression(size_t level = 6) : m_level(level) {} + + std::string name() const override { return "LZMA_Compression"; } + + private: + Compression_Stream* make_stream() const; + + const size_t m_level; + }; + +/** +* LZMA Deccompression +*/ +class BOTAN_DLL LZMA_Decompression : public Stream_Decompression + { + public: + std::string name() const override { return "LZMA_Decompression"; } + private: + Compression_Stream* make_stream() const; + }; + +} + +#endif diff --git a/src/lib/compression/zlib/info.txt b/src/lib/compression/zlib/info.txt new file mode 100644 index 000000000..ba5abd4ec --- /dev/null +++ b/src/lib/compression/zlib/info.txt @@ -0,0 +1,7 @@ +define ZLIB_TRANSFORM 20141118 + +load_on request + +<libs> +all -> z +</libs> diff --git a/src/lib/compression/zlib/zlib.cpp b/src/lib/compression/zlib/zlib.cpp new file mode 100644 index 000000000..b18621640 --- /dev/null +++ b/src/lib/compression/zlib/zlib.cpp @@ -0,0 +1,106 @@ +/* +* Zlib Compressor +* (C) 2001 Peter J Jones +* 2001-2007,2014 Jack Lloyd +* 2006 Matt Johnston +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/zlib.h> +#include <botan/internal/comp_util.h> +#include <zlib.h> + +namespace Botan { + +namespace { + +class Zlib_Stream : public Zlib_Style_Stream<z_stream, Bytef> + { + public: + Zlib_Stream() + { + streamp()->opaque = alloc(); + streamp()->zalloc = Compression_Alloc_Info::malloc<unsigned int>; + streamp()->zfree = Compression_Alloc_Info::free; + } + + u32bit run_flag() const override { return Z_NO_FLUSH; } + u32bit flush_flag() const override { return Z_FULL_FLUSH; } + u32bit finish_flag() const override { return Z_FINISH; } + }; + +class Zlib_Compression_Stream : public Zlib_Stream + { + public: + Zlib_Compression_Stream(size_t level, bool raw_deflate) + { + // FIXME: allow specifiying memLevel and strategy + int rc = deflateInit2(streamp(), level, Z_DEFLATED, + (raw_deflate ? -15 : 15), 8, Z_DEFAULT_STRATEGY); + if(rc != Z_OK) + throw std::runtime_error("zlib deflate initialization failed"); + } + + ~Zlib_Compression_Stream() + { + deflateEnd(streamp()); + } + + bool run(u32bit flags) override + { + int rc = deflate(streamp(), flags); + + if(rc == Z_MEM_ERROR) + throw std::bad_alloc(); + else if(rc != Z_OK && rc != Z_STREAM_END) + throw std::runtime_error("zlib deflate error"); + + return (rc == Z_STREAM_END); + } + }; + +class Zlib_Decompression_Stream : public Zlib_Stream + { + public: + Zlib_Decompression_Stream(bool raw_deflate) + { + int rc = inflateInit2(streamp(), (raw_deflate ? -15 : 15)); + + if(rc == Z_MEM_ERROR) + throw std::bad_alloc(); + else if(rc != Z_OK) + throw std::runtime_error("zlib inflate initialization failed"); + } + + ~Zlib_Decompression_Stream() + { + inflateEnd(streamp()); + } + + bool run(u32bit flags) override + { + int rc = inflate(streamp(), flags); + + if(rc == Z_MEM_ERROR) + throw std::bad_alloc(); + else if(rc != Z_OK && rc != Z_STREAM_END) + throw std::runtime_error("zlib deflate error"); + + return (rc == Z_STREAM_END); + } + }; + +} + +Compression_Stream* Zlib_Compression::make_stream() const + { + return new Zlib_Compression_Stream(m_level, m_raw_deflate); + } + +Compression_Stream* Zlib_Decompression::make_stream() const + { + return new Zlib_Decompression_Stream(m_raw_deflate); + } + +} diff --git a/src/lib/compression/zlib/zlib.h b/src/lib/compression/zlib/zlib.h new file mode 100644 index 000000000..55da47a0d --- /dev/null +++ b/src/lib/compression/zlib/zlib.h @@ -0,0 +1,61 @@ +/* +* Zlib Compressor +* (C) 2001 Peter J Jones +* 2001-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_ZLIB_H__ +#define BOTAN_ZLIB_H__ + +#include <botan/compression.h> + +namespace Botan { + +/** +* Zlib Compression +*/ +class BOTAN_DLL Zlib_Compression : public Stream_Compression + { + public: + /** + * @param level how much effort to use on compressing (0 to 9); + * higher levels are slower but tend to give better + * compression + * @param raw_deflate if true no zlib header/trailer will be used + */ + Zlib_Compression(size_t level = 6, bool raw_deflate = false) : + m_level(level), m_raw_deflate(raw_deflate) {} + + std::string name() const override { return "Zlib_Compression"; } + + private: + Compression_Stream* make_stream() const; + + const size_t m_level; + const bool m_raw_deflate; + }; + +/** +* Zlib Deccompression +*/ +class BOTAN_DLL Zlib_Decompression : public Stream_Decompression + { + public: + /** + * @param raw_deflate if true no zlib header/trailer will be used + */ + Zlib_Decompression( bool raw_deflate = false) : m_raw_deflate(raw_deflate) {} + + std::string name() const override { return "Zlib_Decompression"; } + + private: + Compression_Stream* make_stream() const; + + const bool m_raw_deflate; + }; + +} + +#endif |