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

Generated by: LCOV version 1.15