Botan  2.9.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 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 
76 class 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 
103 class 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 
110 class 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 
116 class 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 
135 class 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 
143 Compression_Stream* Zlib_Compression::make_stream(size_t level) const
144  {
145  return new Zlib_Compression_Stream(level, 15);
146  }
147 
148 Compression_Stream* Zlib_Decompression::make_stream() const
149  {
150  return new Zlib_Decompression_Stream(15);
151  }
152 
153 Compression_Stream* Deflate_Compression::make_stream(size_t level) const
154  {
155  return new Deflate_Compression_Stream(level, 15);
156  }
157 
158 Compression_Stream* Deflate_Decompression::make_stream() const
159  {
160  return new Deflate_Decompression_Stream(15);
161  }
162 
163 Compression_Stream* Gzip_Compression::make_stream(size_t level) const
164  {
165  return new Gzip_Compression_Stream(level, 15, m_os_code, m_hdr_time);
166  }
167 
168 Compression_Stream* Gzip_Decompression::make_stream() const
169  {
170  return new Gzip_Decompression_Stream(15);
171  }
172 
173 }
static void free(void *self, void *ptr)
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:111
int(* final)(unsigned char *, CTX *)
Flags flags(Flag flags)
Definition: p11.h:858
Definition: alg_id.cpp:13