LCOV - code coverage report
Current view: top level - http_proto/service/impl - zlib_service.ipp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 45 71 63.4 %
Date: 2023-02-27 20:43:06 Functions: 8 13 61.5 %

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

Generated by: LCOV version 1.15