Botan  2.1.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 <ctime>
14 #include <zlib.h>
15 
16 namespace Botan {
17 
18 namespace {
19 
20 class Zlib_Stream : public Zlib_Style_Stream<z_stream, Bytef>
21  {
22  public:
23  Zlib_Stream()
24  {
25  streamp()->opaque = alloc();
26  streamp()->zalloc = Compression_Alloc_Info::malloc<unsigned int>;
27  streamp()->zfree = Compression_Alloc_Info::free;
28  }
29 
30  uint32_t run_flag() const override { return Z_NO_FLUSH; }
31  uint32_t flush_flag() const override { return Z_SYNC_FLUSH; }
32  uint32_t finish_flag() const override { return Z_FINISH; }
33 
34  int compute_window_bits(int wbits, int wbits_offset) const
35  {
36  if(wbits_offset == -1)
37  return -wbits;
38  else
39  return wbits + wbits_offset;
40  }
41  };
42 
43 class Zlib_Compression_Stream : public Zlib_Stream
44  {
45  public:
46  Zlib_Compression_Stream(size_t level, int wbits, int wbits_offset = 0)
47  {
48  wbits = compute_window_bits(wbits, wbits_offset);
49 
50  if(level >= 9)
51  level = 9;
52  else if(level == 0)
53  level = 6;
54 
55  int rc = ::deflateInit2(streamp(), level, Z_DEFLATED, wbits, 8, Z_DEFAULT_STRATEGY);
56 
57  if(rc != Z_OK)
58  throw Exception("zlib deflate initialization failed");
59  }
60 
61  ~Zlib_Compression_Stream()
62  {
63  ::deflateEnd(streamp());
64  }
65 
66  bool run(uint32_t flags) override
67  {
68  int rc = ::deflate(streamp(), flags);
69 
70  if(rc == Z_MEM_ERROR)
71  throw Exception("zlib memory allocation failure");
72  else if(rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR)
73  throw Exception("zlib deflate error " + std::to_string(rc));
74 
75  return (rc == Z_STREAM_END);
76  }
77  };
78 
79 class Zlib_Decompression_Stream : public Zlib_Stream
80  {
81  public:
82  Zlib_Decompression_Stream(int wbits, int wbits_offset = 0)
83  {
84  int rc = ::inflateInit2(streamp(), compute_window_bits(wbits, wbits_offset));
85 
86  if(rc == Z_MEM_ERROR)
87  throw Exception("zlib memory allocation failure");
88  else if(rc != Z_OK)
89  throw Exception("zlib inflate initialization failed");
90  }
91 
92  ~Zlib_Decompression_Stream()
93  {
94  ::inflateEnd(streamp());
95  }
96 
97  bool run(uint32_t flags) override
98  {
99  int rc = ::inflate(streamp(), flags);
100 
101  if(rc == Z_MEM_ERROR)
102  throw Exception("zlib memory allocation failure");
103  else if(rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR)
104  throw Exception("zlib inflate error " + std::to_string(rc));
105 
106  return (rc == Z_STREAM_END);
107  }
108  };
109 
110 class Deflate_Compression_Stream : public Zlib_Compression_Stream
111  {
112  public:
113  Deflate_Compression_Stream(size_t level, int wbits) :
114  Zlib_Compression_Stream(level, wbits, -1) {}
115  };
116 
117 class Deflate_Decompression_Stream : public Zlib_Decompression_Stream
118  {
119  public:
120  explicit Deflate_Decompression_Stream(int wbits) : Zlib_Decompression_Stream(wbits, -1) {}
121  };
122 
123 class Gzip_Compression_Stream : public Zlib_Compression_Stream
124  {
125  public:
126  Gzip_Compression_Stream(size_t level, int wbits, uint8_t os_code) :
127  Zlib_Compression_Stream(level, wbits, 16)
128  {
129  clear_mem(&m_header, 1);
130  m_header.os = os_code;
131  m_header.time = std::time(nullptr);
132 
133  int rc = deflateSetHeader(streamp(), &m_header);
134  if(rc != Z_OK)
135  throw Exception("setting gzip header failed");
136  }
137 
138  private:
139  ::gz_header m_header;
140  };
141 
142 class Gzip_Decompression_Stream : public Zlib_Decompression_Stream
143  {
144  public:
145  explicit Gzip_Decompression_Stream(int wbits) : Zlib_Decompression_Stream(wbits, 16) {}
146  };
147 
148 }
149 
150 Compression_Stream* Zlib_Compression::make_stream(size_t level) const
151  {
152  return new Zlib_Compression_Stream(level, 15);
153  }
154 
155 Compression_Stream* Zlib_Decompression::make_stream() const
156  {
157  return new Zlib_Decompression_Stream(15);
158  }
159 
160 Compression_Stream* Deflate_Compression::make_stream(size_t level) const
161  {
162  return new Deflate_Compression_Stream(level, 15);
163  }
164 
165 Compression_Stream* Deflate_Decompression::make_stream() const
166  {
167  return new Deflate_Decompression_Stream(15);
168  }
169 
170 Compression_Stream* Gzip_Compression::make_stream(size_t level) const
171  {
172  return new Gzip_Compression_Stream(level, 15, m_os_code);
173  }
174 
175 Compression_Stream* Gzip_Decompression::make_stream() const
176  {
177  return new Gzip_Decompression_Stream(15);
178  }
179 
180 }
static void free(void *self, void *ptr)
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:57
Flags flags(Flag flags)
Definition: p11.h:858
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
::gz_header m_header
Definition: zlib.cpp:139
Definition: alg_id.cpp:13