1//
2// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// Official repository: https://github.com/boostorg/beast
8//
9
10// Test that header file is self-contained.
11#include <beast/detail/zlib/deflate_stream.hpp>
12#include <beast/detail/zlib/inflate_stream.hpp>
13
14#include <beast/unit_test/suite.hpp>
15#include <array>
16#include <cassert>
17#include <memory>
18#include <random>
19
20namespace boost {
21namespace beast {
22namespace zlib {
23
24class zlib_test : public beast::unit_test::suite
25{
26public:
27 class buffer
28 {
29 std::size_t size_ = 0;
30 std::size_t capacity_ = 0;
31 std::unique_ptr<std::uint8_t[]> p_;
32
33 public:
34 buffer() = default;
35 buffer(buffer&&) = default;
36 buffer& operator=(buffer&&) = default;
37
38
39 explicit
40 buffer(std::size_t capacity)
41 {
42 reserve(capacity);
43 }
44
45 bool
46 empty() const
47 {
48 return size_ == 0;
49 }
50
51 std::size_t
52 size() const
53 {
54 return size_;
55 }
56
57 std::size_t
58 capacity() const
59 {
60 return capacity_;
61 }
62
63 std::uint8_t const*
64 data() const
65 {
66 return p_.get();
67 }
68
69 std::uint8_t*
70 data()
71 {
72 return p_.get();
73 }
74
75 void
76 reserve(std::size_t capacity)
77 {
78 if(capacity != capacity_)
79 {
80 p_.reset(p: new std::uint8_t[capacity]);
81 capacity_ = capacity;
82 }
83 }
84
85 void
86 resize(std::size_t size)
87 {
88 assert(size <= capacity_);
89 size_ = size;
90 }
91 };
92
93 buffer
94 make_source1(std::size_t size)
95 {
96 std::mt19937 rng;
97 buffer b(size);
98 auto p = b.data();
99 std::size_t n = 0;
100 static std::string const chars(
101 "01234567890{}\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
102 "{{{{{{{{{{}}}}}}}}}} ");
103 while(n < size)
104 {
105 *p++ = chars[rng()%chars.size()];
106 ++n;
107 }
108 b.resize(size: n);
109 return b;
110 }
111
112 buffer
113 make_source2(std::size_t size)
114 {
115 std::mt19937 rng;
116 std::array<double, 2> const i{0, 65535};
117 std::array<double, 2> const w{0, 1};
118 std::piecewise_linear_distribution<double> d(
119 i.begin(), i.end(), w.begin());
120 buffer b(size);
121 auto p = b.data();
122 std::size_t n = 0;
123 while(n < size)
124 {
125 if(n == 1)
126 {
127 *p++ = rng()%256;
128 ++n;
129 continue;
130 }
131 auto const v = static_cast<std::uint16_t>(d(rng));
132 *p++ = v>>8;
133 *p++ = v&0xff;
134 n += 2;
135
136 }
137 b.resize(size: n);
138 return b;
139 }
140
141 void
142 checkInflate(buffer const& input, buffer const& original)
143 {
144 for(std::size_t i = 0; i < input.size(); ++i)
145 {
146 buffer output(original.size());
147 inflate_stream zs;
148 zs.avail_in = 0;
149 zs.next_in = 0;
150 zs.next_out = output.data();
151 zs.avail_out = output.capacity();
152 if(i > 0)
153 {
154 zs.next_in = (Byte*)input.data();
155 zs.avail_in = i;
156 auto result = zs.write(Z_FULL_FLUSH);
157 expect(result == Z_OK);
158 }
159 zs.next_in = (Byte*)input.data() + i;
160 zs.avail_in = input.size() - i;
161 auto result = zs.write(Z_FULL_FLUSH);
162 output.resize(size: output.capacity() - zs.avail_out);
163 expect(result == Z_OK);
164 expect(output.size() == original.size());
165 expect(std::memcmp(
166 output.data(), original.data(), original.size()) == 0);
167 }
168 }
169
170 void testSpecial()
171 {
172 {
173 deflate_stream zs;
174 }
175 {
176 inflate_stream zs;
177 }
178 }
179
180 void testCompress()
181 {
182 static std::size_t constexpr N = 2048;
183 for(int source = 0; source <= 1; ++source)
184 {
185 buffer original;
186 switch(source)
187 {
188 case 0:
189 original = make_source1(size: N);
190 break;
191 case 1:
192 original = make_source2(size: N);
193 break;
194 }
195 for(int level = 0; level <= 9; ++level)
196 {
197 for(int strategy = 0; strategy <= 4; ++strategy)
198 {
199 for(int wbits = 15; wbits <= 15; ++wbits)
200 {
201 deflate_stream zs;
202 zs.avail_in = 0;
203 zs.next_in = 0;
204 expect(deflate_stream::deflateInit2(&zs,
205 level,
206 wbits,
207 4,
208 strategy) == Z_OK);
209 buffer output(deflate_stream::deflateBound(&zs, original.size()));
210 zs.next_in = (Byte*)original.data();
211 zs.avail_in = original.size();
212 zs.next_out = output.data();
213 zs.avail_out = output.capacity();
214 auto result = zs.deflate(Z_FULL_FLUSH);
215 expect(result == Z_OK);
216 output.resize(size: output.capacity() - zs.avail_out);
217 checkInflate(input: output, original);
218 }
219 }
220 }
221 }
222 }
223
224 void run() override
225 {
226 testSpecial();
227 testCompress();
228 }
229};
230
231BEAST_DEFINE_TESTSUITE(zlib,core,beast);
232
233} // zlib
234} // beast
235} // boost
236

source code of boost/libs/beast/test/beast/core/zlib.cpp