| 1 | // |
| 2 | // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot 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/boostorg/beast |
| 8 | // |
| 9 | // This is a derivative work based on Zlib, copyright below: |
| 10 | /* |
| 11 | Copyright (C) 1995-2022 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 | |
| 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 | |
| 43 | namespace boost { |
| 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 |
| 185 | sliding window when `Flush::finish` is used. |
| 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 |
| 217 | } // boost |
| 218 | |
| 219 | #endif |
| 220 | |