inflate_stream.hpp 10 KB

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