3
* (C) 2001 Peter J Jones
4
* 2001-2007,2014 Jack Lloyd
7
* Botan is released under the Simplified BSD License (see license.txt)
10
#include <botan/zlib.h>
11
#include <botan/internal/compress_utils.h>
12
#include <botan/exceptn.h>
19
class Zlib_Stream : public Zlib_Style_Stream<z_stream, Bytef>
24
streamp()->opaque = alloc();
25
streamp()->zalloc = Compression_Alloc_Info::malloc<unsigned int>;
26
streamp()->zfree = Compression_Alloc_Info::free;
29
uint32_t run_flag() const override { return Z_NO_FLUSH; }
30
uint32_t flush_flag() const override { return Z_SYNC_FLUSH; }
31
uint32_t finish_flag() const override { return Z_FINISH; }
33
int compute_window_bits(int wbits, int wbits_offset) const
35
if(wbits_offset == -1)
38
return wbits + wbits_offset;
42
class Zlib_Compression_Stream : public Zlib_Stream
45
Zlib_Compression_Stream(size_t level, int wbits, int wbits_offset = 0)
47
wbits = compute_window_bits(wbits, wbits_offset);
54
int rc = ::deflateInit2(streamp(), level, Z_DEFLATED, wbits, 8, Z_DEFAULT_STRATEGY);
57
throw Exception("zlib deflate initialization failed");
60
~Zlib_Compression_Stream()
62
::deflateEnd(streamp());
65
bool run(uint32_t flags) override
67
int rc = ::deflate(streamp(), flags);
70
throw Exception("zlib memory allocation failure");
71
else if(rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR)
72
throw Exception("zlib deflate error " + std::to_string(rc));
74
return (rc == Z_STREAM_END);
78
class Zlib_Decompression_Stream : public Zlib_Stream
81
Zlib_Decompression_Stream(int wbits, int wbits_offset = 0)
83
int rc = ::inflateInit2(streamp(), compute_window_bits(wbits, wbits_offset));
86
throw Exception("zlib memory allocation failure");
88
throw Exception("zlib inflate initialization failed");
91
~Zlib_Decompression_Stream()
93
::inflateEnd(streamp());
96
bool run(uint32_t flags) override
98
int rc = ::inflate(streamp(), flags);
100
if(rc == Z_MEM_ERROR)
101
throw Exception("zlib memory allocation failure");
102
else if(rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR)
103
throw Exception("zlib inflate error " + std::to_string(rc));
105
return (rc == Z_STREAM_END);
109
class Deflate_Compression_Stream final : public Zlib_Compression_Stream
112
Deflate_Compression_Stream(size_t level, int wbits) :
113
Zlib_Compression_Stream(level, wbits, -1) {}
116
class Deflate_Decompression_Stream final : public Zlib_Decompression_Stream
119
explicit Deflate_Decompression_Stream(int wbits) : Zlib_Decompression_Stream(wbits, -1) {}
122
class Gzip_Compression_Stream final : public Zlib_Compression_Stream
125
Gzip_Compression_Stream(size_t level, int wbits, uint8_t os_code, uint64_t hdr_time) :
126
Zlib_Compression_Stream(level, wbits, 16)
128
clear_mem(&m_header, 1);
129
m_header.os = os_code;
130
m_header.time = static_cast<uLong>(hdr_time);
132
int rc = deflateSetHeader(streamp(), &m_header);
134
throw Exception("setting gzip header failed");
138
::gz_header m_header;
141
class Gzip_Decompression_Stream final : public Zlib_Decompression_Stream
144
explicit Gzip_Decompression_Stream(int wbits) : Zlib_Decompression_Stream(wbits, 16) {}
149
Compression_Stream* Zlib_Compression::make_stream(size_t level) const
151
return new Zlib_Compression_Stream(level, 15);
154
Compression_Stream* Zlib_Decompression::make_stream() const
156
return new Zlib_Decompression_Stream(15);
159
Compression_Stream* Deflate_Compression::make_stream(size_t level) const
161
return new Deflate_Compression_Stream(level, 15);
164
Compression_Stream* Deflate_Decompression::make_stream() const
166
return new Deflate_Decompression_Stream(15);
169
Compression_Stream* Gzip_Compression::make_stream(size_t level) const
171
return new Gzip_Compression_Stream(level, 15, m_os_code, m_hdr_time);
174
Compression_Stream* Gzip_Decompression::make_stream() const
176
return new Gzip_Decompression_Stream(15);