LCOV - code coverage report
Current view: top level - http_proto/detail/impl - zlib_codec.ipp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 21 202 10.4 %
Date: 2023-02-10 23:49:12 Functions: 4 30 13.3 %

          Line data    Source code
       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           0 : make_error_code(
      56             :     zlib_error ev) noexcept
      57             : {
      58             :     struct cat_t : error_category
      59             :     {
      60           0 :         cat_t() noexcept
      61           0 :             : error_category(
      62           0 :                 0xe6c6d0215d1d6e22)
      63             :         {
      64           0 :         }
      65             :             
      66             :         const char*
      67           0 :         name() const noexcept override
      68             :         {
      69           0 :             return "boost.http.proto.zlib_error";
      70             :         }
      71             : 
      72             :         std::string
      73           0 :         message(int ev) const override
      74             :         {
      75           0 :             switch(static_cast<zlib_error>(ev))
      76             :             {
      77           0 :             case zlib_error::ok: return "Z_OK";
      78           0 :             case zlib_error::stream_end: return "Z_STREAM_END";
      79           0 :             case zlib_error::need_dict: return "Z_NEED_DICT";
      80           0 :             case zlib_error::errno_: return "Z_ERRNO";
      81           0 :             case zlib_error::stream_err: return "Z_STREAM_ERROR";
      82           0 :             case zlib_error::data_err: return "Z_DATA_ERROR";
      83           0 :             case zlib_error::mem_err: return "Z_MEM_ERROR";
      84           0 :             case zlib_error::buf_err: return "Z_BUF_ERROR";
      85           0 :             case zlib_error::version_err: return "Z_VERSION_ERROR";
      86           0 :             default:
      87           0 :                 return "unknown";
      88             :             }
      89             :         }
      90             :     };
      91           0 :     static cat_t const cat{};
      92             :     return error_code{static_cast<
      93             :         std::underlying_type<
      94           0 :             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           4 : gzip_decoder::
     121           2 : ~gzip_decoder()
     122             : {
     123           2 :     auto zs = reinterpret_cast<
     124             :         ::z_stream*>(zs_);
     125           2 :     if(zs)
     126             :     {
     127           2 :         ::inflateEnd(zs);
     128           2 :         delete zs;
     129             :     }
     130           4 : }
     131             : 
     132           2 : gzip_decoder::
     133           2 : gzip_decoder()
     134             : {
     135           2 :     ::z_stream* zs = new ::z_stream;
     136           2 :     zs->zalloc = nullptr;
     137           2 :     zs->zfree = nullptr;
     138           2 :     zs->opaque = nullptr;
     139           2 :     int const ec = ::inflateInit(zs);
     140           2 :     if(ec == Z_OK)
     141             :     {
     142           2 :         zs_ = zs;
     143           2 :         return;
     144             :     }
     145           0 :     delete zs;
     146           0 :     throw_exception(
     147           0 :         system_error(error_code(
     148             :             static_cast<zlib_error>(ec))),
     149           0 :         BOOST_CURRENT_LOCATION);
     150             : }
     151             : 
     152           0 : gzip_decoder::
     153             : gzip_decoder(
     154           0 :     gzip_decoder&& other) noexcept
     155           0 :     : zs_(other.zs_)
     156             : {
     157           0 :     other.zs_ = nullptr;
     158           0 : }
     159             : 
     160             : auto
     161           0 : 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           0 :     auto zs = reinterpret_cast<
     170             :         ::z_stream*>(zs_);
     171             :     // VFALCO zlib seems to need const_cast
     172           0 :     zs->next_in =
     173             :         const_cast<Bytef z_const*>(
     174             :             reinterpret_cast<
     175             :                 Bytef const*>(input));
     176           0 :     zs->avail_in = static_cast<uInt>(input_size);
     177           0 :     zs->next_out = reinterpret_cast<
     178             :         Bytef*>(output);
     179           0 :     zs->avail_out = static_cast<uInt>(output_size);
     180           0 :     results rv;
     181             :     rv.ec = static_cast<zlib_error>(
     182           0 :         ::inflate(zs, Z_NO_FLUSH));
     183           0 :     rv.input_used =
     184           0 :         input_size - zs->avail_in;
     185           0 :     rv.output_used =
     186           0 :         output_size - zs->avail_out;
     187           0 :     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           0 : gzip_encoder::
     214           0 : ~gzip_encoder()
     215             : {
     216           0 :     auto zs = reinterpret_cast<
     217             :         ::z_stream*>(zs_);
     218           0 :     if(zs)
     219             :     {
     220           0 :         ::deflateEnd(zs);
     221           0 :         delete zs;
     222             :     }
     223           0 : }
     224             : 
     225           0 : gzip_encoder::
     226           0 : gzip_encoder()
     227             : {
     228           0 :     ::z_stream* zs = new ::z_stream;
     229           0 :     zs->zalloc = nullptr;
     230           0 :     zs->zfree = nullptr;
     231           0 :     zs->opaque = nullptr;
     232           0 :     int const ec = ::deflateInit(zs,
     233             :         Z_DEFAULT_COMPRESSION);
     234           0 :     if(ec == Z_OK)
     235             :     {
     236           0 :         zs_ = zs;
     237           0 :         return;
     238             :     }
     239           0 :     delete zs;
     240           0 :     throw_exception(
     241           0 :         system_error(error_code(
     242             :             static_cast<zlib_error>(ec))),
     243           0 :         BOOST_CURRENT_LOCATION);
     244             : }
     245             : 
     246           0 : gzip_encoder::
     247             : gzip_encoder(
     248           0 :     gzip_encoder&& other) noexcept
     249           0 :     : zs_(other.zs_)
     250             : {
     251           0 :     other.zs_ = nullptr;
     252           0 : }
     253             : 
     254             : auto
     255           0 : 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           0 :     auto zs = reinterpret_cast<
     264             :         ::z_stream*>(zs_);
     265             :     // VFALCO zlib seems to need const_cast
     266           0 :     zs->next_in =
     267             :         const_cast<Bytef z_const*>(
     268             :             reinterpret_cast<
     269             :                 Bytef const*>(input));
     270           0 :     zs->avail_in = static_cast<uInt>(input_size);
     271           0 :     zs->next_out = reinterpret_cast<
     272             :         Bytef*>(output);
     273           0 :     zs->avail_out = static_cast<uInt>(output_size);
     274           0 :     results rv;
     275             :     rv.ec = static_cast<zlib_error>(
     276           0 :         ::deflate(zs, Z_NO_FLUSH));
     277           0 :     rv.input_used =
     278           0 :         input_size - zs->avail_in;
     279           0 :     rv.output_used =
     280           0 :         output_size - zs->avail_out;
     281           0 :     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           0 : deflate_decoder::
     308           0 : ~deflate_decoder()
     309             : {
     310           0 :     auto zs = reinterpret_cast<
     311             :         ::z_stream*>(zs_);
     312           0 :     if(zs)
     313             :     {
     314           0 :         ::inflateEnd(zs);
     315           0 :         delete zs;
     316             :     }
     317           0 : }
     318             : 
     319           0 : deflate_decoder::
     320           0 : deflate_decoder()
     321             : {
     322           0 :     ::z_stream* zs = new ::z_stream;
     323           0 :     zs->zalloc = nullptr;
     324           0 :     zs->zfree = nullptr;
     325           0 :     zs->opaque = nullptr;
     326           0 :     int const ec = ::inflateInit(zs);
     327           0 :     if(ec == Z_OK)
     328             :     {
     329           0 :         zs_ = zs;
     330           0 :         return;
     331             :     }
     332           0 :     delete zs;
     333           0 :     throw_exception(
     334           0 :         system_error(error_code(
     335             :             static_cast<zlib_error>(ec))),
     336           0 :         BOOST_CURRENT_LOCATION);
     337             : }
     338             : 
     339           0 : deflate_decoder::
     340             : deflate_decoder(
     341           0 :     deflate_decoder&& other) noexcept
     342           0 :     : zs_(other.zs_)
     343             : {
     344           0 :     other.zs_ = nullptr;
     345           0 : }
     346             : 
     347             : auto
     348           0 : 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           0 :     auto zs = reinterpret_cast<
     357             :         ::z_stream*>(zs_);
     358             :     // VFALCO zlib seems to need const_cast
     359           0 :     zs->next_in =
     360             :         const_cast<Bytef z_const*>(
     361             :             reinterpret_cast<
     362             :                 Bytef const*>(input));
     363           0 :     zs->avail_in = static_cast<uInt>(input_size);
     364           0 :     zs->next_out = reinterpret_cast<
     365             :         Bytef*>(output);
     366           0 :     zs->avail_out = static_cast<uInt>(output_size);
     367           0 :     results rv;
     368             :     rv.ec = static_cast<zlib_error>(
     369           0 :         ::inflate(zs, Z_NO_FLUSH));
     370           0 :     rv.input_used =
     371           0 :         input_size - zs->avail_in;
     372           0 :     rv.output_used =
     373           0 :         output_size - zs->avail_out;
     374           0 :     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           0 : deflate_encoder::
     401           0 : ~deflate_encoder()
     402             : {
     403           0 :     auto zs = reinterpret_cast<
     404             :         ::z_stream*>(zs_);
     405           0 :     if(zs)
     406             :     {
     407           0 :         ::deflateEnd(zs);
     408           0 :         delete zs;
     409             :     }
     410           0 : }
     411             : 
     412           0 : deflate_encoder::
     413           0 : deflate_encoder()
     414             : {
     415           0 :     ::z_stream* zs = new ::z_stream;
     416           0 :     zs->zalloc = nullptr;
     417           0 :     zs->zfree = nullptr;
     418           0 :     zs->opaque = nullptr;
     419           0 :     int const ec = ::deflateInit(zs,
     420             :         Z_DEFAULT_COMPRESSION);
     421           0 :     if(ec == Z_OK)
     422             :     {
     423           0 :         zs_ = zs;
     424           0 :         return;
     425             :     }
     426           0 :     delete zs;
     427           0 :     throw_exception(
     428           0 :         system_error(error_code(
     429             :             static_cast<zlib_error>(ec))),
     430           0 :         BOOST_CURRENT_LOCATION);
     431             : }
     432             : 
     433           0 : deflate_encoder::
     434             : deflate_encoder(
     435           0 :     deflate_encoder&& other) noexcept
     436           0 :     : zs_(other.zs_)
     437             : {
     438           0 :     other.zs_ = nullptr;
     439           0 : }
     440             : 
     441             : auto
     442           0 : 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           0 :     auto zs = reinterpret_cast<
     451             :         ::z_stream*>(zs_);
     452             :     // VFALCO zlib seems to need const_cast
     453           0 :     zs->next_in =
     454             :         const_cast<Bytef z_const*>(
     455             :             reinterpret_cast<
     456             :                 Bytef const*>(input));
     457           0 :     zs->avail_in = static_cast<uInt>(input_size);
     458           0 :     zs->next_out = reinterpret_cast<
     459             :         Bytef*>(output);
     460           0 :     zs->avail_out = static_cast<uInt>(output_size);
     461           0 :     results rv;
     462             :     rv.ec = static_cast<zlib_error>(
     463           0 :         ::deflate(zs, Z_NO_FLUSH));
     464           0 :     rv.input_used =
     465           0 :         input_size - zs->avail_in;
     466           0 :     rv.output_used =
     467           0 :         output_size - zs->avail_out;
     468           0 :     return rv;
     469             : }
     470             : 
     471             : } // detail
     472             : 
     473             : //------------------------------------------------
     474             : 
     475             : void
     476           0 : parser::
     477             : apply_param(
     478             :     deflate_decoder_t const&)
     479             : {
     480           0 :     dec_[deflate_codec].reset(
     481           0 :         new detail::deflate_decoder);
     482           0 : }
     483             : 
     484             : void
     485           2 : parser::
     486             : apply_param(
     487             :     gzip_decoder_t const&)
     488             : {
     489           2 :     dec_[gzip_codec].reset(
     490           2 :         new detail::gzip_decoder);
     491           2 : }
     492             : 
     493             : //------------------------------------------------
     494             : 
     495             : void
     496           0 : serializer::
     497             : apply_param(
     498             :     deflate_decoder_t const&)
     499             : {
     500           0 :     dec_[deflate_codec].reset(
     501           0 :         new detail::deflate_decoder);
     502           0 : }
     503             : 
     504             : void
     505           0 : serializer::
     506             : apply_param(
     507             :     deflate_encoder_t const&)
     508             : {
     509           0 :     enc_[deflate_codec].reset(
     510           0 :         new detail::deflate_encoder);
     511           0 : }
     512             : 
     513             : void
     514           0 : serializer::
     515             : apply_param(
     516             :     gzip_decoder_t const&)
     517             : {
     518           0 :     dec_[gzip_codec].reset(
     519           0 :         new detail::gzip_decoder);
     520           0 : }
     521             : 
     522             : void
     523           0 : serializer::
     524             : apply_param(
     525             :     gzip_encoder_t const&)
     526             : {
     527           0 :     enc_[gzip_codec].reset(
     528           0 :         new detail::gzip_encoder);
     529           0 : }
     530             : 
     531             : } // http_proto
     532             : } // boost
     533             : 
     534             : #endif
     535             : #endif

Generated by: LCOV version 1.15