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 73 61.6 %
Date: 2023-03-01 04:29:22 Functions: 8 14 57.1 %

          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           1 :     error_cat_type() noexcept
      64           1 :         : error_category(
      65           1 :             0xe6c6d0215d1d6e22)
      66             :     {
      67           1 :     }
      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           4 : make_error_code(
     106             :     error ev) noexcept
     107             : {
     108             :     static BOOST_SYSTEM_CONSTEXPR
     109           4 :         error_cat_type cat{};
     110             :     return system::error_code{static_cast<
     111             :         std::underlying_type<
     112           4 :             error>::type>(ev), cat};
     113             : }
     114             : 
     115             : //------------------------------------------------
     116             : 
     117             : // probes memory usage for a config
     118             : class probe
     119             : {
     120             : public:
     121             :     explicit
     122           1 :     probe() noexcept
     123           1 :     {
     124           1 :         zs_.zalloc = &zalloc;
     125           1 :         zs_.zfree = &zfree;
     126           1 :         zs_.opaque = this;
     127           1 :     }
     128             : 
     129             :     system::result<std::size_t>
     130           1 :     deflate_init(
     131             :         int level)
     132             :     {
     133           1 :         n_ = 0;
     134           1 :         system::error_code ec;
     135             :         ec = static_cast<error>(
     136           1 :             deflateInit(&zs_, level));
     137           1 :         if(ec.failed())
     138           0 :             return ec;
     139           1 :         Bytef tmp[24]{};
     140           1 :         zs_.next_in = &tmp[0];
     141           1 :         zs_.avail_in = 1;
     142           1 :         zs_.next_out = &tmp[1];
     143           1 :         zs_.avail_out = 23;
     144             :         ec = static_cast<error>(
     145           1 :             deflate(&zs_,
     146           1 :                 Z_FINISH));
     147           2 :         if( ec.failed() &&
     148           2 :             ec != error::stream_end)
     149           0 :             return ec;
     150             :         ec = static_cast<error>(
     151           1 :             deflateEnd(&zs_));
     152           1 :         if(ec.failed())
     153           0 :             return ec;
     154           1 :         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           5 :     static void* zalloc(void* opaque,
     195             :         uInt num, uInt size)
     196             :     {
     197           5 :         auto& self =
     198             :             *reinterpret_cast<
     199             :                 probe*>(opaque);
     200           5 :         self.n_ += num * size;
     201           5 :         return new char[num * size];
     202             :     }
     203             : 
     204           5 :     static void zfree(
     205             :         void*, void* address)
     206             :     {
     207             :         delete[] reinterpret_cast<
     208           5 :             char*>(address);
     209           5 :     }
     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           1 :     deflate_decoder_service_impl(
     226             :         context& ctx,
     227             :         config const& cfg)
     228           1 :         : cfg_(cfg)
     229             :     {
     230             :         (void)ctx;
     231           1 :         probe p;
     232           0 :         auto n0 = p.deflate_init(
     233           1 :             Z_DEFAULT_COMPRESSION).value();
     234             :         (void)n0;
     235           1 :     }
     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           0 :     space_needed() const noexcept override
     248             :     {
     249           0 :         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           1 : deflate_decoder_service::
     266             : config::
     267             : install(context& ctx)
     268             : {
     269             :     ctx.make_service<
     270           1 :         detail::deflate_decoder_service_impl>(*this);
     271           1 : }
     272             : 
     273             : } // zlib
     274             : } // http_proto
     275             : } // boost
     276             : 
     277             : #endif

Generated by: LCOV version 1.15