]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // |
92f5a8d4 | 2 | // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) |
7c673cae FG |
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 | // | |
b32b8144 FG |
7 | // Official repository: https://github.com/boostorg/beast |
8 | // | |
7c673cae FG |
9 | // This is a derivative work based on Zlib, copyright below: |
10 | /* | |
11 | Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler | |
12 | ||
13 | This software is provided 'as-is', without any express or implied | |
14 | warranty. In no event will the authors be held liable for any damages | |
15 | arising from the use of this software. | |
16 | ||
17 | Permission is granted to anyone to use this software for any purpose, | |
18 | including commercial applications, and to alter it and redistribute it | |
19 | freely, subject to the following restrictions: | |
20 | ||
21 | 1. The origin of this software must not be misrepresented; you must not | |
22 | claim that you wrote the original software. If you use this software | |
23 | in a product, an acknowledgment in the product documentation would be | |
24 | appreciated but is not required. | |
25 | 2. Altered source versions must be plainly marked as such, and must not be | |
26 | misrepresented as being the original software. | |
27 | 3. This notice may not be removed or altered from any source distribution. | |
28 | ||
29 | Jean-loup Gailly Mark Adler | |
30 | jloup@gzip.org madler@alumni.caltech.edu | |
31 | ||
32 | The data format used by the zlib library is described by RFCs (Request for | |
33 | Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 | |
34 | (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). | |
35 | */ | |
36 | ||
92f5a8d4 TL |
37 | #ifndef BOOST_BEAST_ZLIB_INFLATE_STREAM_HPP |
38 | #define BOOST_BEAST_ZLIB_INFLATE_STREAM_HPP | |
39 | ||
40 | #include <boost/beast/core/detail/config.hpp> | |
41 | #include <boost/beast/zlib/detail/inflate_stream.hpp> | |
42 | ||
b32b8144 | 43 | namespace boost { |
7c673cae FG |
44 | namespace beast { |
45 | namespace zlib { | |
46 | ||
47 | /** Raw deflate stream decompressor. | |
48 | ||
49 | This implements a raw deflate stream decompressor. The deflate | |
50 | protocol is a compression protocol described in | |
51 | "DEFLATE Compressed Data Format Specification version 1.3" | |
52 | located here: https://tools.ietf.org/html/rfc1951 | |
53 | ||
54 | The implementation is a refactored port to C++ of ZLib's "inflate". | |
55 | A more detailed description of ZLib is at http://zlib.net/. | |
56 | ||
57 | Compression can be done in a single step if the buffers are large | |
58 | enough (for example if an input file is memory mapped), or can be done | |
59 | by repeated calls of the compression function. In the latter case, the | |
60 | application must provide more input and/or consume the output (providing | |
61 | more output space) before each call. | |
62 | */ | |
63 | class inflate_stream | |
64 | : private detail::inflate_stream | |
65 | { | |
66 | public: | |
67 | /** Construct a raw deflate decompression stream. | |
68 | ||
69 | The window size is set to the default of 15 bits. | |
70 | */ | |
71 | inflate_stream() = default; | |
72 | ||
73 | /** Reset the stream. | |
74 | ||
75 | This puts the stream in a newly constructed state with | |
76 | the previously specified window size, but without de-allocating | |
77 | any dynamically created structures. | |
78 | */ | |
79 | void | |
80 | reset() | |
81 | { | |
82 | doReset(); | |
83 | } | |
84 | ||
85 | /** Reset the stream. | |
86 | ||
87 | This puts the stream in a newly constructed state with the | |
88 | specified window size, but without de-allocating any dynamically | |
89 | created structures. | |
90 | */ | |
91 | void | |
92 | reset(int windowBits) | |
93 | { | |
94 | doReset(windowBits); | |
95 | } | |
96 | ||
97 | /** Put the stream in a newly constructed state. | |
98 | ||
99 | All dynamically allocated memory is de-allocated. | |
100 | */ | |
101 | void | |
102 | clear() | |
103 | { | |
104 | doClear(); | |
105 | } | |
106 | ||
107 | /** Decompress input and produce output. | |
108 | ||
109 | This function decompresses as much data as possible, and stops when | |
110 | the input buffer becomes empty or the output buffer becomes full. It | |
111 | may introduce some output latency (reading input without producing any | |
112 | output) except when forced to flush. | |
113 | ||
114 | One or both of the following actions are performed: | |
115 | ||
116 | @li Decompress more input starting at `zs.next_in` and update `zs.next_in` | |
117 | and `zs.avail_in` accordingly. If not all input can be processed (because | |
118 | there is not enough room in the output buffer), `zs.next_in` is updated | |
119 | and processing will resume at this point for the next call. | |
120 | ||
121 | @li Provide more output starting at `zs.next_out` and update `zs.next_out` | |
122 | and `zs.avail_out` accordingly. `write` provides as much output as | |
123 | possible, until there is no more input data or no more space in the output | |
124 | buffer (see below about the flush parameter). | |
125 | ||
126 | Before the call, the application should ensure that at least one of the | |
127 | actions is possible, by providing more input and/or consuming more output, | |
128 | and updating the values in `zs` accordingly. The application can consume | |
129 | the uncompressed output when it wants, for example when the output buffer | |
130 | is full (`zs.avail_out == 0`), or after each call. If `write` returns no | |
131 | error and with zero `zs.avail_out`, it must be called again after making | |
132 | room in the output buffer because there might be more output pending. | |
133 | ||
134 | The flush parameter may be `Flush::none`, `Flush::sync`, `Flush::finish`, | |
135 | `Flush::block`, or `Flush::trees`. `Flush::sync` requests to flush as much | |
136 | output as possible to the output buffer. `Flush::block` requests to stop if | |
137 | and when it gets to the next deflate block boundary. When decoding the | |
138 | zlib or gzip format, this will cause `write` to return immediately after | |
139 | the header and before the first block. When doing a raw inflate, `write` will | |
140 | go ahead and process the first block, and will return when it gets to the | |
141 | end of that block, or when it runs out of data. | |
142 | ||
143 | The `Flush::block` option assists in appending to or combining deflate | |
144 | streams. Also to assist in this, on return `write` will set `zs.data_type` | |
145 | to the number of unused bits in the last byte taken from `zs.next_in`, plus | |
146 | 64 if `write` is currently decoding the last block in the deflate stream, | |
147 | plus 128 if `write` returned immediately after decoding an end-of-block code | |
148 | or decoding the complete header up to just before the first byte of the | |
149 | deflate stream. The end-of-block will not be indicated until all of the | |
150 | uncompressed data from that block has been written to `zs.next_out`. The | |
151 | number of unused bits may in general be greater than seven, except when | |
152 | bit 7 of `zs.data_type` is set, in which case the number of unused bits | |
153 | will be less than eight. `zs.data_type` is set as noted here every time | |
154 | `write` returns for all flush options, and so can be used to determine the | |
155 | amount of currently consumed input in bits. | |
156 | ||
157 | The `Flush::trees` option behaves as `Flush::block` does, but it also returns | |
158 | when the end of each deflate block header is reached, before any actual data | |
159 | in that block is decoded. This allows the caller to determine the length of | |
160 | the deflate block header for later use in random access within a deflate block. | |
161 | 256 is added to the value of `zs.data_type` when `write` returns immediately | |
162 | after reaching the end of the deflate block header. | |
163 | ||
164 | `write` should normally be called until it returns `error::end_of_stream` or | |
165 | another error. However if all decompression is to be performed in a single | |
166 | step (a single call of `write`), the parameter flush should be set to | |
167 | `Flush::finish`. In this case all pending input is processed and all pending | |
168 | output is flushed; `zs.avail_out` must be large enough to hold all of the | |
169 | uncompressed data for the operation to complete. (The size of the uncompressed | |
170 | data may have been saved by the compressor for this purpose.) The use of | |
171 | `Flush::finish` is not required to perform an inflation in one step. However | |
172 | it may be used to inform inflate that a faster approach can be used for the | |
173 | single call. `Flush::finish` also informs inflate to not maintain a sliding | |
174 | window if the stream completes, which reduces inflate's memory footprint. | |
175 | If the stream does not complete, either because not all of the stream is | |
176 | provided or not enough output space is provided, then a sliding window will be | |
177 | allocated and `write` can be called again to continue the operation as if | |
178 | `Flush::none` had been used. | |
179 | ||
180 | In this implementation, `write` always flushes as much output as possible to | |
181 | the output buffer, and always uses the faster approach on the first call. So | |
182 | the effects of the flush parameter in this implementation are on the return value | |
183 | of `write` as noted below, when `write` returns early when `Flush::block` or | |
184 | `Flush::trees` is used, and when `write` avoids the allocation of memory for a | |
92f5a8d4 | 185 | sliding window when `Flush::finish` is used. |
7c673cae FG |
186 | |
187 | If a preset dictionary is needed after this call, | |
188 | `write` sets `zs.adler` to the Adler-32 checksum of the dictionary chosen by | |
189 | the compressor and returns `error::need_dictionary`; otherwise it sets | |
190 | `zs.adler` to the Adler-32 checksum of all output produced so far (that is, | |
191 | `zs.total_out bytes`) and returns no error, `error::end_of_stream`, or an | |
192 | error code as described below. At the end of the stream, `write` checks that | |
193 | its computed adler32 checksum is equal to that saved by the compressor and | |
194 | returns `error::end_of_stream` only if the checksum is correct. | |
195 | ||
196 | This function returns no error if some progress has been made (more input | |
197 | processed or more output produced), `error::end_of_stream` if the end of the | |
198 | compressed data has been reached and all uncompressed output has been produced, | |
199 | `error::need_dictionary` if a preset dictionary is needed at this point, | |
200 | `error::invalid_data` if the input data was corrupted (input stream not | |
201 | conforming to the zlib format or incorrect check value), `error::stream_error` | |
202 | if the stream structure was inconsistent (for example if `zs.next_in` or | |
203 | `zs.next_out` was null), `error::need_buffers` if no progress is possible or | |
204 | if there was not enough room in the output buffer when `Flush::finish` is | |
205 | used. Note that `error::need_buffers` is not fatal, and `write` can be called | |
206 | again with more input and more output space to continue decompressing. | |
207 | */ | |
208 | void | |
209 | write(z_params& zs, Flush flush, error_code& ec) | |
210 | { | |
211 | doWrite(zs, flush, ec); | |
212 | } | |
213 | }; | |
214 | ||
215 | } // zlib | |
216 | } // beast | |
b32b8144 | 217 | } // boost |
7c673cae FG |
218 | |
219 | #endif |