diff options
author | lloyd <[email protected]> | 2014-11-19 02:52:04 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2014-11-19 02:52:04 +0000 |
commit | dfe33209a78f28e1b5b5b9a43d99d360fd029889 (patch) | |
tree | c19115343f564c00eaabe2dfb45822ba089b0742 /src/lib/compression | |
parent | 173ccf53649b4635df5fd51974c44dd59eaf9e95 (diff) |
Add gzip compression transform and compress command line prog.
Diffstat (limited to 'src/lib/compression')
-rw-r--r-- | src/lib/compression/bzip2/bzip2.cpp | 2 | ||||
-rw-r--r-- | src/lib/compression/compression.cpp | 64 | ||||
-rw-r--r-- | src/lib/compression/compression.h | 3 | ||||
-rw-r--r-- | src/lib/compression/zlib/zlib.cpp | 77 | ||||
-rw-r--r-- | src/lib/compression/zlib/zlib.h | 37 |
5 files changed, 171 insertions, 12 deletions
diff --git a/src/lib/compression/bzip2/bzip2.cpp b/src/lib/compression/bzip2/bzip2.cpp index 440c21477..313b1ed46 100644 --- a/src/lib/compression/bzip2/bzip2.cpp +++ b/src/lib/compression/bzip2/bzip2.cpp @@ -84,7 +84,7 @@ class Bzip_Decompression_Stream : public Bzip_Stream BZ2_bzDecompressEnd(streamp()); } - bool run(u32bit flags) override + bool run(u32bit) override { int rc = BZ2_bzDecompress(streamp()); diff --git a/src/lib/compression/compression.cpp b/src/lib/compression/compression.cpp index 3eb26e81b..35b2a4bc0 100644 --- a/src/lib/compression/compression.cpp +++ b/src/lib/compression/compression.cpp @@ -7,8 +7,68 @@ #include <botan/compression.h> +#if defined(BOTAN_HAS_ZLIB_TRANSFORM) + #include <botan/zlib.h> +#endif + +#if defined(BOTAN_HAS_BZIP_TRANSFORM) + #include <botan/bzip.h> +#endif + +#if defined(BOTAN_HAS_LZMA_TRANSFORM) + #include <botan/lzma.h> +#endif + namespace Botan { +Compressor_Transformation* make_compressor(const std::string& type, size_t level) + { +#if defined(BOTAN_HAS_ZLIB_TRANSFORM) + if(type == "zlib") + return new Zlib_Compression(level, false); + if(type == "deflate") + return new Zlib_Compression(level, true); + if(type == "gzip" || type == "gz") + return new Gzip_Compression(level); +#endif + +#if defined(BOTAN_HAS_BZIP_TRANSFORM) + if(type == "bzip2" || type == "bz2") + return new Bzip_Compression(level); +#endif + +#if defined(BOTAN_HAS_LZMA_TRANSFORM) + if(type == "lzma" || type == "xz") + return new LZMA_Compression(level); +#endif + + throw std::runtime_error("Unknown compression type " + type); + } + +Compressor_Transformation* make_decompressor(const std::string& type) + { +#if defined(BOTAN_HAS_ZLIB_TRANSFORM) + if(type == "zlib") + return new Zlib_Decompression(false); + if(type == "deflate") + return new Zlib_Decompression(true); + if(type == "gzip" || type == "gz") + return new Gzip_Decompression; +#endif + +#if defined(BOTAN_HAS_BZIP_TRANSFORM) + if(type == "bzip2" || type == "bz2") + return new Bzip_Decompression; +#endif + +#if defined(BOTAN_HAS_LZMA_TRANSFORM) + if(type == "lzma" || type == "xz") + return new LZMA_Decompression; +#endif + + throw std::runtime_error("Unknown compression type " + type); + } + void Stream_Compression::clear() { m_stream.reset(); @@ -19,7 +79,6 @@ 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>(); } @@ -37,7 +96,7 @@ void Stream_Compression::process(secure_vector<byte>& buf, size_t offset, u32bit while(true) { - const bool end = m_stream->run(flags); + m_stream->run(flags); if(m_stream->avail_out() == 0) { @@ -82,7 +141,6 @@ secure_vector<byte> Stream_Decompression::start_raw(const byte[], size_t nonce_l if(!valid_nonce_length(nonce_len)) throw Invalid_IV_Length(name(), nonce_len); - clear(); m_stream.reset(make_stream()); return secure_vector<byte>(); diff --git a/src/lib/compression/compression.h b/src/lib/compression/compression.h index 10c7f1a64..75a100cc6 100644 --- a/src/lib/compression/compression.h +++ b/src/lib/compression/compression.h @@ -32,6 +32,9 @@ class BOTAN_DLL Compressor_Transformation : public Transformation } }; +BOTAN_DLL Compressor_Transformation* make_compressor(const std::string& type, size_t level); +BOTAN_DLL Compressor_Transformation* make_decompressor(const std::string& type); + class Compression_Stream { public: diff --git a/src/lib/compression/zlib/zlib.cpp b/src/lib/compression/zlib/zlib.cpp index b18621640..c8f8757b1 100644 --- a/src/lib/compression/zlib/zlib.cpp +++ b/src/lib/compression/zlib/zlib.cpp @@ -9,6 +9,7 @@ #include <botan/zlib.h> #include <botan/internal/comp_util.h> +#include <ctime> #include <zlib.h> namespace Botan { @@ -28,16 +29,24 @@ class Zlib_Stream : public Zlib_Style_Stream<z_stream, Bytef> 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; } + + int compute_window_bits(int wbits, int wbits_offset) const + { + if(wbits_offset == -1) + return -wbits; + else + return wbits + wbits_offset; + } }; class Zlib_Compression_Stream : public Zlib_Stream { public: - Zlib_Compression_Stream(size_t level, bool raw_deflate) + Zlib_Compression_Stream(size_t level, int wbits, int wbits_offset = 0) { - // FIXME: allow specifiying memLevel and strategy int rc = deflateInit2(streamp(), level, Z_DEFLATED, - (raw_deflate ? -15 : 15), 8, Z_DEFAULT_STRATEGY); + compute_window_bits(wbits, wbits_offset), + 8, Z_DEFAULT_STRATEGY); if(rc != Z_OK) throw std::runtime_error("zlib deflate initialization failed"); } @@ -63,9 +72,9 @@ class Zlib_Compression_Stream : public Zlib_Stream class Zlib_Decompression_Stream : public Zlib_Stream { public: - Zlib_Decompression_Stream(bool raw_deflate) + Zlib_Decompression_Stream(int wbits, int wbits_offset = 0) { - int rc = inflateInit2(streamp(), (raw_deflate ? -15 : 15)); + int rc = inflateInit2(streamp(), compute_window_bits(wbits, wbits_offset)); if(rc == Z_MEM_ERROR) throw std::bad_alloc(); @@ -91,16 +100,70 @@ class Zlib_Decompression_Stream : public Zlib_Stream } }; +class Deflate_Compression_Stream : public Zlib_Compression_Stream + { + public: + Deflate_Compression_Stream(size_t level, int wbits) : + Zlib_Compression_Stream(level, wbits, -1) {} + }; + +class Deflate_Decompression_Stream : public Zlib_Decompression_Stream + { + public: + Deflate_Decompression_Stream(int wbits) : Zlib_Decompression_Stream(wbits, -1) {} + }; + +class Gzip_Compression_Stream : public Zlib_Compression_Stream + { + public: + Gzip_Compression_Stream(size_t level, int wbits, byte os_code) : + Zlib_Compression_Stream(level, wbits, 16) + { + std::memset(&m_header, 0, sizeof(m_header)); + m_header.os = os_code; + m_header.time = std::time(0); + + int rc = deflateSetHeader(streamp(), &m_header); + if(rc != Z_OK) + throw std::runtime_error("setting gzip header failed"); + } + + private: + ::gz_header m_header; + }; + +class Gzip_Decompression_Stream : public Zlib_Decompression_Stream + { + public: + Gzip_Decompression_Stream(int wbits) : Zlib_Decompression_Stream(wbits, 16) {} + }; + } Compression_Stream* Zlib_Compression::make_stream() const { - return new Zlib_Compression_Stream(m_level, m_raw_deflate); + if(m_raw_deflate) + return new Deflate_Compression_Stream(m_level, 15); + else + return new Zlib_Compression_Stream(m_level, 15); } Compression_Stream* Zlib_Decompression::make_stream() const { - return new Zlib_Decompression_Stream(m_raw_deflate); + if(m_raw_deflate) + return new Deflate_Decompression_Stream(15); + else + return new Zlib_Decompression_Stream(15); + } + +Compression_Stream* Gzip_Compression::make_stream() const + { + return new Gzip_Compression_Stream(m_level, 15, m_os_code); + } + +Compression_Stream* Gzip_Decompression::make_stream() const + { + return new Gzip_Decompression_Stream(15); } } diff --git a/src/lib/compression/zlib/zlib.h b/src/lib/compression/zlib/zlib.h index 55da47a0d..5805efb57 100644 --- a/src/lib/compression/zlib/zlib.h +++ b/src/lib/compression/zlib/zlib.h @@ -46,7 +46,7 @@ class BOTAN_DLL Zlib_Decompression : public Stream_Decompression /** * @param raw_deflate if true no zlib header/trailer will be used */ - Zlib_Decompression( bool raw_deflate = false) : m_raw_deflate(raw_deflate) {} + Zlib_Decompression(bool raw_deflate = false) : m_raw_deflate(raw_deflate) {} std::string name() const override { return "Zlib_Decompression"; } @@ -56,6 +56,41 @@ class BOTAN_DLL Zlib_Decompression : public Stream_Decompression const bool m_raw_deflate; }; +/** +* Gzip Compression +*/ +class BOTAN_DLL Gzip_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 + */ + Gzip_Compression(size_t level = 6, byte os_code = 255) : + m_level(level), m_os_code(os_code) {} + + std::string name() const override { return "Gzip_Compression"; } + + private: + Compression_Stream* make_stream() const; + + const size_t m_level; + const byte m_os_code; + }; + +/** +* Gzip Decompression +*/ +class BOTAN_DLL Gzip_Decompression : public Stream_Compression + { + public: + std::string name() const override { return "Gzip_Decompression"; } + + private: + Compression_Stream* make_stream() const; + }; + } #endif |