Botan 3.0.0
Crypto and TLS for C&
zlib.cpp
Go to the documentation of this file.
1/*
2* Zlib Compressor
3* (C) 2001 Peter J Jones
4* 2001-2007,2014 Jack Lloyd
5* 2006 Matt Johnston
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#include <botan/zlib.h>
11#include <botan/internal/compress_utils.h>
12#include <botan/exceptn.h>
13#include <zlib.h>
14
15namespace Botan {
16
17namespace {
18
19class Zlib_Stream : public Zlib_Style_Stream<z_stream, Bytef, unsigned int>
20 {
21 public:
22 Zlib_Stream()
23 {
24 streamp()->opaque = alloc();
25 streamp()->zalloc = Compression_Alloc_Info::malloc<unsigned int>;
26 streamp()->zfree = Compression_Alloc_Info::free;
27 }
28
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; }
32
33 int compute_window_bits(int wbits, int wbits_offset) const
34 {
35 if(wbits_offset == -1)
36 return -wbits;
37 else
38 return wbits + wbits_offset;
39 }
40 };
41
42class Zlib_Compression_Stream : public Zlib_Stream
43 {
44 public:
45 Zlib_Compression_Stream(size_t level, int wbits, int wbits_offset = 0)
46 {
47 wbits = compute_window_bits(wbits, wbits_offset);
48
49 if(level >= 9)
50 level = 9;
51 else if(level == 0)
52 level = 6;
53
54 int rc = ::deflateInit2(streamp(), static_cast<int>(level), Z_DEFLATED, wbits, 8, Z_DEFAULT_STRATEGY);
55
56 if(rc != Z_OK)
57 throw Compression_Error("deflateInit2", ErrorType::ZlibError, rc);
58 }
59
60 ~Zlib_Compression_Stream()
61 {
62 ::deflateEnd(streamp());
63 }
64
65 bool run(uint32_t flags) override
66 {
67 int rc = ::deflate(streamp(), flags);
68
69 if(rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR)
70 throw Compression_Error("zlib deflate", ErrorType::ZlibError, rc);
71
72 return (rc == Z_STREAM_END);
73 }
74 };
75
76class Zlib_Decompression_Stream : public Zlib_Stream
77 {
78 public:
79 Zlib_Decompression_Stream(int wbits, int wbits_offset = 0)
80 {
81 int rc = ::inflateInit2(streamp(), compute_window_bits(wbits, wbits_offset));
82
83 if(rc != Z_OK)
84 throw Compression_Error("inflateInit2", ErrorType::ZlibError, rc);
85 }
86
87 ~Zlib_Decompression_Stream()
88 {
89 ::inflateEnd(streamp());
90 }
91
92 bool run(uint32_t flags) override
93 {
94 int rc = ::inflate(streamp(), flags);
95
96 if(rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR)
97 throw Compression_Error("zlib inflate", ErrorType::ZlibError, rc);
98
99 return (rc == Z_STREAM_END);
100 }
101 };
102
103class Deflate_Compression_Stream final : public Zlib_Compression_Stream
104 {
105 public:
106 Deflate_Compression_Stream(size_t level, int wbits) :
107 Zlib_Compression_Stream(level, wbits, -1) {}
108 };
109
110class Deflate_Decompression_Stream final : public Zlib_Decompression_Stream
111 {
112 public:
113 explicit Deflate_Decompression_Stream(int wbits) : Zlib_Decompression_Stream(wbits, -1) {}
114 };
115
116class Gzip_Compression_Stream final : public Zlib_Compression_Stream
117 {
118 public:
119 Gzip_Compression_Stream(size_t level, int wbits, uint8_t os_code, uint64_t hdr_time) :
120 Zlib_Compression_Stream(level, wbits, 16)
121 {
122 clear_mem(&m_header, 1);
123 m_header.os = os_code;
124 m_header.time = static_cast<uLong>(hdr_time);
125
126 int rc = deflateSetHeader(streamp(), &m_header);
127 if(rc != Z_OK)
128 throw Compression_Error("deflateSetHeader", ErrorType::ZlibError, rc);
129 }
130
131 private:
132 ::gz_header m_header;
133 };
134
135class Gzip_Decompression_Stream final : public Zlib_Decompression_Stream
136 {
137 public:
138 explicit Gzip_Decompression_Stream(int wbits) : Zlib_Decompression_Stream(wbits, 16) {}
139 };
140
141}
142
143std::unique_ptr<Compression_Stream> Zlib_Compression::make_stream(size_t level) const
144 {
145 return std::make_unique<Zlib_Compression_Stream>(level, 15);
146 }
147
148std::unique_ptr<Compression_Stream> Zlib_Decompression::make_stream() const
149 {
150 return std::make_unique<Zlib_Decompression_Stream>(15);
151 }
152
153std::unique_ptr<Compression_Stream> Deflate_Compression::make_stream(size_t level) const
154 {
155 return std::make_unique<Deflate_Compression_Stream>(level, 15);
156 }
157
158std::unique_ptr<Compression_Stream> Deflate_Decompression::make_stream() const
159 {
160 return std::make_unique<Deflate_Decompression_Stream>(15);
161 }
162
163std::unique_ptr<Compression_Stream> Gzip_Compression::make_stream(size_t level) const
164 {
165 return std::make_unique<Gzip_Compression_Stream>(level, 15, m_os_code, m_hdr_time);
166 }
167
168std::unique_ptr<Compression_Stream> Gzip_Decompression::make_stream() const
169 {
170 return std::make_unique<Gzip_Decompression_Stream>(15);
171 }
172
173}
static void free(void *self, void *ptr)
int(* final)(unsigned char *, CTX *)
Definition: alg_id.cpp:12
constexpr void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:115
Public Header.