GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/detail/impl/zlib_codec.ipp
Date: 2023-02-02 18:17:22
Exec Total Coverage
Lines: 21 189 11.1%
Functions: 3 26 11.5%
Branches: 6 102 5.9%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/CPPAlliance/http_proto
8 //
9
10 #ifndef BOOST_HTTP_PROTO_DETAIL_IMPL_ZLIB_CODEC_IPP
11 #define BOOST_HTTP_PROTO_DETAIL_IMPL_ZLIB_CODEC_IPP
12
13 #ifdef BOOST_HTTP_PROTO_HAS_ZLIB
14
15 #include <boost/http_proto/parser.hpp>
16 #include <boost/http_proto/serializer.hpp>
17 #include <boost/http_proto/detail/codec.hpp>
18 #include <boost/core/ignore_unused.hpp>
19 #include <boost/throw_exception.hpp>
20 #include "zlib.h"
21
22 namespace boost {
23 namespace http_proto {
24 namespace detail {
25
26 enum class zlib_error
27 {
28 ok = 0,
29 stream_end = 1,
30 need_dict = 2,
31 errno_ = -1,
32 stream_err = -2,
33 data_err = -3,
34 mem_err = -4,
35 buf_err = -5,
36 version_err = -6
37 };
38
39 //------------------------------------------------
40 } // detail
41 } // http_proto
42 namespace system {
43 template<>
44 struct is_error_code_enum<
45 ::boost::http_proto::detail::zlib_error>
46 {
47 static bool const value = true;
48 };
49 } // system
50 namespace http_proto {
51 namespace detail {
52 //------------------------------------------------
53
54 error_code
55 make_error_code(
56 zlib_error ev) noexcept
57 {
58 struct cat_t : error_category
59 {
60 cat_t() noexcept
61 : error_category(
62 0xe6c6d0215d1d6e22)
63 {
64 }
65
66 const char*
67 name() const noexcept override
68 {
69 return "boost.http.proto.zlib_error";
70 }
71
72 std::string
73 message(int ev) const override
74 {
75 switch(static_cast<zlib_error>(ev))
76 {
77 case zlib_error::ok: return "Z_OK";
78 case zlib_error::stream_end: return "Z_STREAM_END";
79 case zlib_error::need_dict: return "Z_NEED_DICT";
80 case zlib_error::errno_: return "Z_ERRNO";
81 case zlib_error::stream_err: return "Z_STREAM_ERROR";
82 case zlib_error::data_err: return "Z_DATA_ERROR";
83 case zlib_error::mem_err: return "Z_MEM_ERROR";
84 case zlib_error::buf_err: return "Z_BUF_ERROR";
85 case zlib_error::version_err: return "Z_VERSION_ERROR";
86 default:
87 return "unknown";
88 }
89 }
90 };
91 static cat_t const cat{};
92 return error_code{static_cast<
93 std::underlying_type<
94 error>::type>(ev), cat};
95 }
96
97 //------------------------------------------------
98
99 class gzip_decoder : public codec
100 {
101 void* zs_ = nullptr;
102
103 public:
104 ~gzip_decoder() override;
105 gzip_decoder();
106
107 gzip_decoder(
108 gzip_decoder&&) noexcept;
109 gzip_decoder& operator=(
110 gzip_decoder&&) = delete;
111
112 results
113 exchange(
114 void* output,
115 std::size_t output_size,
116 void const* input,
117 std::size_t input_size) override;
118 };
119
120 8 gzip_decoder::
121 4 ~gzip_decoder()
122 {
123 4 auto zs = reinterpret_cast<
124 ::z_stream*>(zs_);
125
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if(zs)
126 {
127 4 ::inflateEnd(zs);
128
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 delete zs;
129 }
130 8 }
131
132 2 gzip_decoder::
133 2 gzip_decoder()
134 {
135
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 ::z_stream* zs = new ::z_stream;
136 2 zs->zalloc = nullptr;
137 2 zs->zfree = nullptr;
138 2 zs->opaque = nullptr;
139
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 int const ec = ::inflateInit(zs);
140
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if(ec == Z_OK)
141 {
142 2 zs_ = zs;
143 2 return;
144 }
145 delete zs;
146 throw_exception(
147 system_error(error_code(
148 static_cast<zlib_error>(ec))),
149 BOOST_CURRENT_LOCATION);
150 }
151
152 gzip_decoder::
153 gzip_decoder(
154 gzip_decoder&& other) noexcept
155 : zs_(other.zs_)
156 {
157 other.zs_ = nullptr;
158 }
159
160 auto
161 gzip_decoder::
162 exchange(
163 void* output,
164 std::size_t output_size,
165 void const* input,
166 std::size_t input_size) ->
167 results
168 {
169 auto zs = reinterpret_cast<
170 ::z_stream*>(zs_);
171 // VFALCO zlib seems to need const_cast
172 zs->next_in =
173 const_cast<Bytef z_const*>(
174 reinterpret_cast<
175 Bytef const*>(input));
176 zs->avail_in = static_cast<uInt>(input_size);
177 zs->next_out = reinterpret_cast<
178 Bytef*>(output);
179 zs->avail_out = static_cast<uInt>(output_size);
180 results rv;
181 rv.ec = static_cast<zlib_error>(
182 ::inflate(zs, Z_NO_FLUSH));
183 rv.input_used =
184 input_size - zs->avail_in;
185 rv.output_used =
186 output_size - zs->avail_out;
187 return rv;
188 }
189
190 //------------------------------------------------
191
192 class gzip_encoder : public codec
193 {
194 void* zs_ = nullptr;
195
196 public:
197 ~gzip_encoder() override;
198 gzip_encoder();
199
200 gzip_encoder(
201 gzip_encoder&&) noexcept;
202 gzip_encoder& operator=(
203 gzip_encoder&&) = delete;
204
205 results
206 exchange(
207 void* output,
208 std::size_t output_size,
209 void const* input,
210 std::size_t input_size) override;
211 };
212
213 gzip_encoder::
214 ~gzip_encoder()
215 {
216 auto zs = reinterpret_cast<
217 ::z_stream*>(zs_);
218 if(zs)
219 {
220 ::deflateEnd(zs);
221 delete zs;
222 }
223 }
224
225 gzip_encoder::
226 gzip_encoder()
227 {
228 ::z_stream* zs = new ::z_stream;
229 zs->zalloc = nullptr;
230 zs->zfree = nullptr;
231 zs->opaque = nullptr;
232 int const ec = ::deflateInit(zs,
233 Z_DEFAULT_COMPRESSION);
234 if(ec == Z_OK)
235 {
236 zs_ = zs;
237 return;
238 }
239 delete zs;
240 throw_exception(
241 system_error(error_code(
242 static_cast<zlib_error>(ec))),
243 BOOST_CURRENT_LOCATION);
244 }
245
246 gzip_encoder::
247 gzip_encoder(
248 gzip_encoder&& other) noexcept
249 : zs_(other.zs_)
250 {
251 other.zs_ = nullptr;
252 }
253
254 auto
255 gzip_encoder::
256 exchange(
257 void* output,
258 std::size_t output_size,
259 void const* input,
260 std::size_t input_size) ->
261 results
262 {
263 auto zs = reinterpret_cast<
264 ::z_stream*>(zs_);
265 // VFALCO zlib seems to need const_cast
266 zs->next_in =
267 const_cast<Bytef z_const*>(
268 reinterpret_cast<
269 Bytef const*>(input));
270 zs->avail_in = static_cast<uInt>(input_size);
271 zs->next_out = reinterpret_cast<
272 Bytef*>(output);
273 zs->avail_out = static_cast<uInt>(output_size);
274 results rv;
275 rv.ec = static_cast<zlib_error>(
276 ::deflate(zs, Z_NO_FLUSH));
277 rv.input_used =
278 input_size - zs->avail_in;
279 rv.output_used =
280 output_size - zs->avail_out;
281 return rv;
282 }
283
284 //------------------------------------------------
285
286 class deflate_decoder : public codec
287 {
288 void* zs_ = nullptr;
289
290 public:
291 ~deflate_decoder() override;
292 deflate_decoder();
293
294 deflate_decoder(
295 deflate_decoder&&) noexcept;
296 deflate_decoder& operator=(
297 deflate_decoder&&) = delete;
298
299 results
300 exchange(
301 void* output,
302 std::size_t output_size,
303 void const* input,
304 std::size_t input_size) override;
305 };
306
307 deflate_decoder::
308 ~deflate_decoder()
309 {
310 auto zs = reinterpret_cast<
311 ::z_stream*>(zs_);
312 if(zs)
313 {
314 ::inflateEnd(zs);
315 delete zs;
316 }
317 }
318
319 deflate_decoder::
320 deflate_decoder()
321 {
322 ::z_stream* zs = new ::z_stream;
323 zs->zalloc = nullptr;
324 zs->zfree = nullptr;
325 zs->opaque = nullptr;
326 int const ec = ::inflateInit(zs);
327 if(ec == Z_OK)
328 {
329 zs_ = zs;
330 return;
331 }
332 delete zs;
333 throw_exception(
334 system_error(error_code(
335 static_cast<zlib_error>(ec))),
336 BOOST_CURRENT_LOCATION);
337 }
338
339 deflate_decoder::
340 deflate_decoder(
341 deflate_decoder&& other) noexcept
342 : zs_(other.zs_)
343 {
344 other.zs_ = nullptr;
345 }
346
347 auto
348 deflate_decoder::
349 exchange(
350 void* output,
351 std::size_t output_size,
352 void const* input,
353 std::size_t input_size) ->
354 results
355 {
356 auto zs = reinterpret_cast<
357 ::z_stream*>(zs_);
358 // VFALCO zlib seems to need const_cast
359 zs->next_in =
360 const_cast<Bytef z_const*>(
361 reinterpret_cast<
362 Bytef const*>(input));
363 zs->avail_in = static_cast<uInt>(input_size);
364 zs->next_out = reinterpret_cast<
365 Bytef*>(output);
366 zs->avail_out = static_cast<uInt>(output_size);
367 results rv;
368 rv.ec = static_cast<zlib_error>(
369 ::inflate(zs, Z_NO_FLUSH));
370 rv.input_used =
371 input_size - zs->avail_in;
372 rv.output_used =
373 output_size - zs->avail_out;
374 return rv;
375 }
376
377 //------------------------------------------------
378
379 class deflate_encoder : public codec
380 {
381 void* zs_ = nullptr;
382
383 public:
384 ~deflate_encoder() override;
385 deflate_encoder();
386
387 deflate_encoder(
388 deflate_encoder&&) noexcept;
389 deflate_encoder& operator=(
390 deflate_encoder&&) = delete;
391
392 results
393 exchange(
394 void* output,
395 std::size_t output_size,
396 void const* input,
397 std::size_t input_size) override;
398 };
399
400 deflate_encoder::
401 ~deflate_encoder()
402 {
403 auto zs = reinterpret_cast<
404 ::z_stream*>(zs_);
405 if(zs)
406 {
407 ::deflateEnd(zs);
408 delete zs;
409 }
410 }
411
412 deflate_encoder::
413 deflate_encoder()
414 {
415 ::z_stream* zs = new ::z_stream;
416 zs->zalloc = nullptr;
417 zs->zfree = nullptr;
418 zs->opaque = nullptr;
419 int const ec = ::deflateInit(zs,
420 Z_DEFAULT_COMPRESSION);
421 if(ec == Z_OK)
422 {
423 zs_ = zs;
424 return;
425 }
426 delete zs;
427 throw_exception(
428 system_error(error_code(
429 static_cast<zlib_error>(ec))),
430 BOOST_CURRENT_LOCATION);
431 }
432
433 deflate_encoder::
434 deflate_encoder(
435 deflate_encoder&& other) noexcept
436 : zs_(other.zs_)
437 {
438 other.zs_ = nullptr;
439 }
440
441 auto
442 deflate_encoder::
443 exchange(
444 void* output,
445 std::size_t output_size,
446 void const* input,
447 std::size_t input_size) ->
448 results
449 {
450 auto zs = reinterpret_cast<
451 ::z_stream*>(zs_);
452 // VFALCO zlib seems to need const_cast
453 zs->next_in =
454 const_cast<Bytef z_const*>(
455 reinterpret_cast<
456 Bytef const*>(input));
457 zs->avail_in = static_cast<uInt>(input_size);
458 zs->next_out = reinterpret_cast<
459 Bytef*>(output);
460 zs->avail_out = static_cast<uInt>(output_size);
461 results rv;
462 rv.ec = static_cast<zlib_error>(
463 ::deflate(zs, Z_NO_FLUSH));
464 rv.input_used =
465 input_size - zs->avail_in;
466 rv.output_used =
467 output_size - zs->avail_out;
468 return rv;
469 }
470
471 } // detail
472
473 //------------------------------------------------
474
475 void
476 parser::
477 apply_param(
478 deflate_decoder_t const&)
479 {
480 dec_[deflate_codec].reset(
481 new detail::deflate_decoder);
482 }
483
484 void
485 2 parser::
486 apply_param(
487 gzip_decoder_t const&)
488 {
489 2 dec_[gzip_codec].reset(
490
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 new detail::gzip_decoder);
491 2 }
492
493 //------------------------------------------------
494
495 void
496 serializer::
497 apply_param(
498 deflate_decoder_t const&)
499 {
500 dec_[deflate_codec].reset(
501 new detail::deflate_decoder);
502 }
503
504 void
505 serializer::
506 apply_param(
507 deflate_encoder_t const&)
508 {
509 enc_[deflate_codec].reset(
510 new detail::deflate_encoder);
511 }
512
513 void
514 serializer::
515 apply_param(
516 gzip_decoder_t const&)
517 {
518 dec_[gzip_codec].reset(
519 new detail::gzip_decoder);
520 }
521
522 void
523 serializer::
524 apply_param(
525 gzip_encoder_t const&)
526 {
527 enc_[gzip_codec].reset(
528 new detail::gzip_encoder);
529 }
530
531 } // http_proto
532 } // boost
533
534 #endif
535 #endif
536