GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/service/impl/zlib_service.ipp
Date: 2023-12-11 14:11:20
Exec Total Coverage
Lines: 0 73 0.0%
Functions: 0 14 0.0%
Branches: 0 38 0.0%

Line Branch Exec Source
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 error_cat_type() noexcept
64 : error_category(
65 0xe6c6d0215d1d6e22)
66 {
67 }
68
69 const char*
70 name() const noexcept override
71 {
72 return "boost.http.proto.zlib";
73 }
74
75 std::string
76 message( int ev ) const override
77 {
78 return message( ev, nullptr, 0 );
79 }
80
81 char const*
82 message(
83 int ev,
84 char*,
85 std::size_t) const noexcept override
86 {
87 switch(static_cast<error>(ev))
88 {
89 case error::ok: return "Z_OK";
90 case error::stream_end: return "Z_STREAM_END";
91 case error::need_dict: return "Z_NEED_DICT";
92 case error::errno_: return "Z_ERRNO";
93 case error::stream_err: return "Z_STREAM_ERROR";
94 case error::data_err: return "Z_DATA_ERROR";
95 case error::mem_err: return "Z_MEM_ERROR";
96 case error::buf_err: return "Z_BUF_ERROR";
97 case error::version_err: return "Z_VERSION_ERROR";
98 default:
99 return "unknown";
100 }
101 }
102 };
103
104 system::error_code
105 make_error_code(
106 error ev) noexcept
107 {
108 static BOOST_SYSTEM_CONSTEXPR
109 error_cat_type cat{};
110 return system::error_code{static_cast<
111 std::underlying_type<
112 error>::type>(ev), cat};
113 }
114
115 //------------------------------------------------
116
117 // probes memory usage for a config
118 class probe
119 {
120 public:
121 explicit
122 probe() noexcept
123 {
124 zs_.zalloc = &zalloc;
125 zs_.zfree = &zfree;
126 zs_.opaque = this;
127 }
128
129 system::result<std::size_t>
130 deflate_init(
131 int level)
132 {
133 n_ = 0;
134 system::error_code ec;
135 ec = static_cast<error>(
136 deflateInit(&zs_, level));
137 if(ec.failed())
138 return ec;
139 Bytef tmp[24]{};
140 zs_.next_in = &tmp[0];
141 zs_.avail_in = 1;
142 zs_.next_out = &tmp[1];
143 zs_.avail_out = 23;
144 ec = static_cast<error>(
145 deflate(&zs_,
146 Z_FINISH));
147 if( ec.failed() &&
148 ec != error::stream_end)
149 return ec;
150 ec = static_cast<error>(
151 deflateEnd(&zs_));
152 if(ec.failed())
153 return ec;
154 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 static void* zalloc(void* opaque,
195 uInt num, uInt size)
196 {
197 auto& self =
198 *reinterpret_cast<
199 probe*>(opaque);
200 self.n_ += num * size;
201 return new char[num * size];
202 }
203
204 static void zfree(
205 void*, void* address)
206 {
207 delete[] reinterpret_cast<
208 char*>(address);
209 }
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 deflate_decoder_service_impl(
226 context& ctx,
227 config const& cfg)
228 : cfg_(cfg)
229 {
230 (void)ctx;
231 probe p;
232 auto n0 = p.deflate_init(
233 Z_DEFAULT_COMPRESSION).value();
234 (void)n0;
235 }
236
237 private:
238 config cfg_;
239
240 config const&
241 get_config() const noexcept override
242 {
243 return cfg_;
244 }
245
246 std::size_t
247 space_needed() const noexcept override
248 {
249 return 0;
250 }
251
252 filter&
253 make_filter(http_proto::detail::workspace& ws) const override
254 {
255 filter* p;
256 (void)ws;
257 p = nullptr;
258 return *p;
259 }
260 };
261
262 } // detail
263
264 void
265 deflate_decoder_service::
266 config::
267 install(context& ctx)
268 {
269 ctx.make_service<
270 detail::deflate_decoder_service_impl>(*this);
271 }
272
273 } // zlib
274 } // http_proto
275 } // boost
276
277 #endif
278