LCOV - code coverage report
Current view: top level - libs/http_proto/src_zlib/service/zlib_service.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 66.2 % 74 49
Test Date: 2024-06-05 19:28:02 Functions: 64.3 % 14 9

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2021 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_SERVICE_IMPL_ZLIB_SERVICE_IPP
      11              : #define BOOST_HTTP_PROTO_SERVICE_IMPL_ZLIB_SERVICE_IPP
      12              : 
      13              : #include <boost/http_proto/service/zlib_service.hpp>
      14              : #include <boost/system/result.hpp>
      15              : #include "zlib.h"
      16              : 
      17              : namespace boost {
      18              : namespace http_proto {
      19              : namespace zlib {
      20              : namespace detail {
      21              : 
      22              : /*
      23              :     DEFLATE Compressed Data Format Specification version 1.3
      24              :     https://www.rfc-editor.org/rfc/rfc1951
      25              : */
      26              : 
      27              : //------------------------------------------------
      28              : 
      29              : enum class error
      30              : {
      31              :     ok          =  0,
      32              :     stream_end  =  1,
      33              :     need_dict   =  2,
      34              :     errno_      = -1,
      35              :     stream_err  = -2,
      36              :     data_err    = -3,
      37              :     mem_err     = -4,
      38              :     buf_err     = -5,
      39              :     version_err = -6
      40              : };
      41              : 
      42              : //------------------------------------------------
      43              : } // detail
      44              : } // zlib
      45              : } // http_proto
      46              : namespace system {
      47              : template<>
      48              : struct is_error_code_enum<
      49              :     ::boost::http_proto::zlib::detail::error>
      50              : {
      51              :     static bool const value = true;
      52              : };
      53              : } // system
      54              : namespace http_proto {
      55              : namespace zlib {
      56              : namespace detail {
      57              : //------------------------------------------------
      58              : 
      59              : struct error_cat_type
      60              :     : system::error_category
      61              : {
      62              :     BOOST_SYSTEM_CONSTEXPR
      63            2 :     error_cat_type() noexcept
      64            2 :         : error_category(
      65            2 :             0xe6c6d0215d1d6e22)
      66              :     {
      67            2 :     }
      68              : 
      69              :     const char*
      70            0 :     name() const noexcept override
      71              :     {
      72            0 :         return "boost.http.proto.zlib";
      73              :     }
      74              : 
      75              :     std::string
      76            0 :     message( int ev ) const override
      77              :     {
      78            0 :         return message( ev, nullptr, 0 );
      79              :     }
      80              : 
      81              :     char const*
      82            0 :     message(
      83              :         int ev,
      84              :         char*,
      85              :         std::size_t) const noexcept override
      86              :     {
      87            0 :         switch(static_cast<error>(ev))
      88              :         {
      89            0 :         case error::ok: return "Z_OK";
      90            0 :         case error::stream_end: return "Z_STREAM_END";
      91            0 :         case error::need_dict: return "Z_NEED_DICT";
      92            0 :         case error::errno_: return "Z_ERRNO";
      93            0 :         case error::stream_err: return "Z_STREAM_ERROR";
      94            0 :         case error::data_err: return "Z_DATA_ERROR";
      95            0 :         case error::mem_err: return "Z_MEM_ERROR";
      96            0 :         case error::buf_err: return "Z_BUF_ERROR";
      97            0 :         case error::version_err: return "Z_VERSION_ERROR";
      98            0 :         default:
      99            0 :             return "unknown";
     100              :         }
     101              :     }
     102              : };
     103              : 
     104              : system::error_code
     105            8 : make_error_code(
     106              :     error ev) noexcept
     107              : {
     108              :     static BOOST_SYSTEM_CONSTEXPR
     109            8 :         error_cat_type cat{};
     110              :     return system::error_code{static_cast<
     111              :         std::underlying_type<
     112            8 :             error>::type>(ev), cat};
     113              : }
     114              : 
     115              : //------------------------------------------------
     116              : 
     117              : // probes memory usage for a config
     118              : class probe
     119              : {
     120              : public:
     121              :     explicit
     122            2 :     probe() noexcept
     123            2 :     {
     124            2 :         zs_.zalloc = &zalloc;
     125            2 :         zs_.zfree = &zfree;
     126            2 :         zs_.opaque = this;
     127            2 :     }
     128              : 
     129              :     system::result<std::size_t>
     130            2 :     deflate_init(
     131              :         int level)
     132              :     {
     133            2 :         n_ = 0;
     134            2 :         system::error_code ec;
     135              :         ec = static_cast<error>(
     136            2 :             deflateInit(&zs_, level));
     137            2 :         if(ec.failed())
     138            0 :             return ec;
     139            2 :         Bytef tmp[24]{};
     140            2 :         zs_.next_in = &tmp[0];
     141            2 :         zs_.avail_in = 1;
     142            2 :         zs_.next_out = &tmp[1];
     143            2 :         zs_.avail_out = 23;
     144              :         ec = static_cast<error>(
     145            2 :             deflate(&zs_,
     146            2 :                 Z_FINISH));
     147            4 :         if( ec.failed() &&
     148            4 :             ec != error::stream_end)
     149            0 :             return ec;
     150              :         ec = static_cast<error>(
     151            2 :             deflateEnd(&zs_));
     152            2 :         if(ec.failed())
     153            0 :             return ec;
     154            2 :         return n_;
     155              :     }
     156              : 
     157              :     system::result<std::size_t>
     158              :     deflate_init2(
     159              :         int level,
     160              :         int method,
     161              :         int windowBits,
     162              :         int memLevel,
     163              :         int strategy)
     164              :     {
     165              :         n_ = 0;
     166              :         system::error_code ec;
     167              :         ec = static_cast<error>(
     168              :             deflateInit2(&zs_,
     169              :                 level,
     170              :                 method,
     171              :                 windowBits,
     172              :                 memLevel,
     173              :                 strategy));
     174              :         if(ec.failed())
     175              :             return ec;
     176              :         Bytef tmp[2];
     177              :         zs_.next_in = &tmp[0];
     178              :         zs_.avail_in = 0;
     179              :         zs_.next_out = &tmp[1];
     180              :         zs_.avail_out = 0;
     181              :         ec = static_cast<error>(
     182              :             deflate(&zs_,
     183              :                 Z_FULL_FLUSH));
     184              :         if(ec.failed())
     185              :             return ec;
     186              :         ec = static_cast<error>(
     187              :             deflateEnd(&zs_));
     188              :         if(ec.failed())
     189              :             return ec;
     190              :         return n_;
     191              :     }
     192              : 
     193              : private:
     194           10 :     static void* zalloc(void* opaque,
     195              :         uInt num, uInt size)
     196              :     {
     197           10 :         auto& self =
     198              :             *reinterpret_cast<
     199              :                 probe*>(opaque);
     200           10 :         self.n_ += num * size;
     201           10 :         return new char[num * size];
     202              :     }
     203              : 
     204           10 :     static void zfree(
     205              :         void*, void* address)
     206              :     {
     207           10 :         delete[] reinterpret_cast<
     208           10 :             char*>(address);
     209           10 :     }
     210              : 
     211              :     z_stream_s zs_{};
     212              :     std::size_t n_ = 0;
     213              : };
     214              : 
     215              : //------------------------------------------------
     216              : 
     217              : struct
     218              :     deflate_decoder_service_impl
     219              :     : deflate_decoder_service
     220              : {
     221              :     using key_type =
     222              :         deflate_decoder_service;
     223              : 
     224              :     explicit
     225            2 :     deflate_decoder_service_impl(
     226              :         context& ctx,
     227              :         config const& cfg)
     228            2 :         : cfg_(cfg)
     229              :     {
     230              :         (void)ctx;
     231            2 :         probe p;
     232            2 :         auto n0 = p.deflate_init(
     233            2 :             Z_DEFAULT_COMPRESSION).value();
     234              :         (void)n0;
     235            2 :     }
     236              : 
     237              : private:
     238              :     config cfg_;
     239              : 
     240              :     config const&
     241            0 :     get_config() const noexcept override
     242              :     {
     243            0 :         return cfg_;
     244              :     }
     245              : 
     246              :     std::size_t
     247            1 :     space_needed() const noexcept override
     248              :     {
     249            1 :         return 0;
     250              :     }
     251              : 
     252              :     filter&
     253            0 :     make_filter(http_proto::detail::workspace& ws) const override
     254              :     {
     255              :         filter* p;
     256              :         (void)ws;
     257            0 :         p = nullptr;
     258            0 :         return *p;
     259              :     }
     260              : };
     261              : 
     262              : } // detail
     263              : 
     264              : void
     265            2 : deflate_decoder_service::
     266              : config::
     267              : install(context& ctx)
     268              : {
     269              :     ctx.make_service<
     270            2 :         detail::deflate_decoder_service_impl>(*this);
     271            2 : }
     272              : 
     273              : } // zlib
     274              : } // http_proto
     275              : } // boost
     276              : 
     277              : #endif
        

Generated by: LCOV version 2.1