Botan  2.4.0
Crypto and TLS for C++11
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 
15 namespace Botan {
16 
17 namespace {
18 
19 class Zlib_Stream : public Zlib_Style_Stream<z_stream, Bytef>
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 
42 class 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(), level, Z_DEFLATED, wbits, 8, Z_DEFAULT_STRATEGY);
55 
56  if(rc != Z_OK)
57  throw Exception("zlib deflate initialization failed");
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_MEM_ERROR)
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));
73 
74  return (rc == Z_STREAM_END);
75  }
76  };
77 
78 class Zlib_Decompression_Stream : public Zlib_Stream
79  {
80  public:
81  Zlib_Decompression_Stream(int wbits, int wbits_offset = 0)
82  {
83  int rc = ::inflateInit2(streamp(), compute_window_bits(wbits, wbits_offset));
84 
85  if(rc == Z_MEM_ERROR)
86  throw Exception("zlib memory allocation failure");
87  else if(rc != Z_OK)
88  throw Exception("zlib inflate initialization failed");
89  }
90 
91  ~Zlib_Decompression_Stream()
92  {
93  ::inflateEnd(streamp());
94  }
95 
96  bool run(uint32_t flags) override
97  {
98  int rc = ::inflate(streamp(), flags);
99 
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));
104 
105  return (rc == Z_STREAM_END);
106  }
107  };
108 
109 class Deflate_Compression_Stream final : public Zlib_Compression_Stream
110  {
111  public:
112  Deflate_Compression_Stream(size_t level, int wbits) :
113  Zlib_Compression_Stream(level, wbits, -1) {}
114  };
115 
116 class Deflate_Decompression_Stream final : public Zlib_Decompression_Stream
117  {
118  public:
119  explicit Deflate_Decompression_Stream(int wbits) : Zlib_Decompression_Stream(wbits, -1) {}
120  };
121 
122 class Gzip_Compression_Stream final : public Zlib_Compression_Stream
123  {
124  public:
125  Gzip_Compression_Stream(size_t level, int wbits, uint8_t os_code, uint64_t hdr_time) :
126  Zlib_Compression_Stream(level, wbits, 16)
127  {
128  clear_mem(&m_header, 1);
129  m_header.os = os_code;
130  m_header.time = static_cast<uLong>(hdr_time);
131 
132  int rc = deflateSetHeader(streamp(), &m_header);
133  if(rc != Z_OK)
134  throw Exception("setting gzip header failed");
135  }
136 
137  private:
138  ::gz_header m_header;
139  };
140 
141 class Gzip_Decompression_Stream final : public Zlib_Decompression_Stream
142  {
143  public:
144  explicit Gzip_Decompression_Stream(int wbits) : Zlib_Decompression_Stream(wbits, 16) {}
145  };
146 
147 }
148 
149 Compression_Stream* Zlib_Compression::make_stream(size_t level) const
150  {
151  return new Zlib_Compression_Stream(level, 15);
152  }
153 
154 Compression_Stream* Zlib_Decompression::make_stream() const
155  {
156  return new Zlib_Decompression_Stream(15);
157  }
158 
159 Compression_Stream* Deflate_Compression::make_stream(size_t level) const
160  {
161  return new Deflate_Compression_Stream(level, 15);
162  }
163 
164 Compression_Stream* Deflate_Decompression::make_stream() const
165  {
166  return new Deflate_Decompression_Stream(15);
167  }
168 
169 Compression_Stream* Gzip_Compression::make_stream(size_t level) const
170  {
171  return new Gzip_Compression_Stream(level, 15, m_os_code, m_hdr_time);
172  }
173 
174 Compression_Stream* Gzip_Decompression::make_stream() const
175  {
176  return new Gzip_Decompression_Stream(15);
177  }
178 
179 }
static void free(void *self, void *ptr)
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:86
Flags flags(Flag flags)
Definition: p11.h:858
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:108
Definition: alg_id.cpp:13