Line data Source code
1 : //
2 : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2024 Christian Mazakas
4 : // Copyright (c) 2024 Mohammad Nejati
5 : //
6 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 : //
9 : // Official repository: https://github.com/cppalliance/http_proto
10 : //
11 :
12 : #ifndef BOOST_HTTP_PROTO_SERVICE_ZLIB_SERVICE_HPP
13 : #define BOOST_HTTP_PROTO_SERVICE_ZLIB_SERVICE_HPP
14 :
15 : #include <boost/http_proto/context.hpp>
16 : #include <boost/http_proto/detail/config.hpp>
17 : #include <boost/http_proto/detail/workspace.hpp>
18 : #include <boost/http_proto/service/service.hpp>
19 :
20 : namespace boost {
21 : namespace http_proto {
22 : namespace zlib {
23 :
24 : struct decoder_config
25 : {
26 : unsigned max_window_bits = 15;
27 : unsigned mem_level = 8;
28 : };
29 :
30 : constexpr
31 : inline
32 : std::size_t
33 24 : encoding_size_hint(decoder_config cfg = {}) noexcept
34 : {
35 : // from: https://www.zlib.net/zlib_tech.html
36 : //
37 : // Memory Footprint
38 : //
39 : // zlib's memory footprint can also be specified fairly
40 : // precisely. It is larger for compression than for
41 : // decompression, and the exact requirements depend on
42 : // how the library was compiled.
43 : //
44 : // The memory requirements for compression depend on two
45 : // parameters, windowBits and memLevel:
46 : // deflate memory usage (bytes) = (1 << (windowBits+2)) + (1 << (memLevel+9)) + 6 KB
47 : return
48 24 : (1 << (cfg.max_window_bits + 2)) +
49 24 : (1 << (cfg.mem_level + 9)) +
50 24 : (6 * 1024);
51 : }
52 :
53 : /** Error codes returned from compression/decompression functions.
54 :
55 : Negative values are errors, positive values are used
56 : for special but normal events.
57 : */
58 : enum class error
59 : {
60 : ok = 0,
61 : stream_end = 1,
62 : need_dict = 2,
63 : errno_ = -1,
64 : stream_err = -2,
65 : data_err = -3,
66 : mem_err = -4,
67 : buf_err = -5,
68 : version_err = -6
69 : };
70 :
71 : /// Flush methods.
72 : enum class flush
73 : {
74 : none,
75 : partial,
76 : sync,
77 : full,
78 : finish,
79 : block,
80 : trees
81 : };
82 :
83 : /** Input and output buffers.
84 :
85 : The application must update `next_in` and `avail_in` when `avail_in`
86 : has dropped to zero. It must update `next_out` and `avail_out` when
87 : `avail_out` has dropped to zero.
88 : */
89 : struct params
90 : {
91 : /// Next input byte
92 : void const* next_in;
93 :
94 : /// Number of bytes available at `next_in`
95 : std::size_t avail_in;
96 :
97 : /// Next output byte
98 : void* next_out;
99 :
100 : /// Number of bytes remaining free at `next_out`
101 : std::size_t avail_out;
102 : };
103 :
104 : /// Abstract interface for deflator/inflator streams.
105 : struct stream
106 : {
107 : /** Call the underling compression/decompression algorithm.
108 :
109 : @param p The input and output buffers.
110 :
111 : @param f The flush method.
112 :
113 : @return The result of operation that contains a value
114 : of @ref error.
115 : */
116 : virtual system::error_code
117 : write(params& p, flush f) noexcept = 0;
118 : };
119 :
120 : /** Provides in-memory compression and decompression functions
121 : using zlib underneath.
122 : */
123 : struct BOOST_HTTP_PROTO_DECL
124 : service
125 : : http_proto::service
126 : {
127 : virtual
128 : std::size_t
129 : space_needed() const noexcept = 0;
130 :
131 : /** Create a deflator stream by calling zlib `deflateInit2()`.
132 :
133 : @param ws A reference to the workspace used for constructing the
134 : deflator stream object and for storage used by zlib.
135 :
136 : @param level The compression level.
137 :
138 : @param window_bits The window size.
139 :
140 : @param mem_level Specifies how much memory should be allocated
141 : for the internal compression state.
142 :
143 : @return A reference to the created deflator stream.
144 :
145 : @throws std::length_error If there is insufficient free space in
146 : @ref `http_proto::detail::workspace`.
147 : */
148 : virtual stream&
149 : make_deflator(
150 : http_proto::detail::workspace& ws,
151 : int level,
152 : int window_bits,
153 : int mem_level) const = 0;
154 :
155 : /** Create an inflator stream by calling zlib `inflateInit2()`.
156 :
157 : @param ws A reference to the workspace used for constructing the
158 : inflator stream object and for storage used by zlib.
159 :
160 : @param window_bits The window size.
161 :
162 : @return A reference to the created inflator stream.
163 :
164 : @throws std::length_error If there is insufficient free space in
165 : @ref `http_proto::detail::workspace`.
166 : */
167 : virtual stream&
168 : make_inflator(
169 : http_proto::detail::workspace& ws,
170 : int window_bits) const = 0;
171 : };
172 :
173 : /** Installs a zlib service on the provided context.
174 :
175 : @param ctx A reference to the @ref context where the service
176 : will be installed.
177 :
178 : @throw std::invalid_argument If the zlib service already
179 : exist on the context.
180 : */
181 : BOOST_HTTP_PROTO_ZLIB_DECL
182 : void
183 : install_service(context& ctx);
184 :
185 : } // zlib
186 : } // http_proto
187 : } // boost
188 :
189 : #include <boost/http_proto/service/impl/zlib_service.hpp>
190 :
191 : #endif
|