Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:44:07

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 #ifndef BOOST_BEAST_ZLIB_DEFLATE_STREAM_HPP
0011 #define BOOST_BEAST_ZLIB_DEFLATE_STREAM_HPP
0012 
0013 #include <boost/beast/core/detail/config.hpp>
0014 #include <boost/beast/zlib/error.hpp>
0015 #include <boost/beast/zlib/zlib.hpp>
0016 #include <boost/beast/zlib/detail/deflate_stream.hpp>
0017 #include <algorithm>
0018 #include <cstdlib>
0019 #include <cstdint>
0020 #include <cstring>
0021 #include <memory>
0022 
0023 namespace boost {
0024 namespace beast {
0025 namespace zlib {
0026 
0027 // This is a derivative work based on Zlib, copyright below:
0028 /*
0029     Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
0030 
0031     This software is provided 'as-is', without any express or implied
0032     warranty.  In no event will the authors be held liable for any damages
0033     arising from the use of this software.
0034 
0035     Permission is granted to anyone to use this software for any purpose,
0036     including commercial applications, and to alter it and redistribute it
0037     freely, subject to the following restrictions:
0038 
0039     1. The origin of this software must not be misrepresented; you must not
0040        claim that you wrote the original software. If you use this software
0041        in a product, an acknowledgment in the product documentation would be
0042        appreciated but is not required.
0043     2. Altered source versions must be plainly marked as such, and must not be
0044        misrepresented as being the original software.
0045     3. This notice may not be removed or altered from any source distribution.
0046 
0047     Jean-loup Gailly        Mark Adler
0048     jloup@gzip.org          madler@alumni.caltech.edu
0049 
0050     The data format used by the zlib library is described by RFCs (Request for
0051     Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
0052     (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
0053 */
0054 
0055 /** Raw deflate compressor.
0056 
0057     This is a port of zlib's "deflate" functionality to C++.
0058 */
0059 class deflate_stream
0060     : private detail::deflate_stream
0061 {
0062 public:
0063     /** Construct a default deflate stream.
0064 
0065         Upon construction, the stream settings will be set
0066         to these default values:
0067 
0068         @li `level = 6`
0069 
0070         @li `windowBits = 15`
0071 
0072         @li `memLevel = 8`
0073 
0074         @li `strategy = Strategy::normal`
0075 
0076         Although the stream is ready to be used immediately
0077         after construction, any required internal buffers are
0078         not dynamically allocated until needed.
0079     */
0080     deflate_stream()
0081     {
0082         reset(6, 15, def_mem_level, Strategy::normal);
0083     }
0084 
0085     /** Reset the stream and compression settings.
0086 
0087         This function initializes the stream to the specified
0088         compression settings.
0089 
0090         Although the stream is ready to be used immediately
0091         after a reset, any required internal buffers are not
0092         dynamically allocated until needed.
0093 
0094         @param level Compression level from 0 to 9.
0095 
0096         @param windowBits The base two logarithm of the window size, or the
0097         history buffer. It should be in the range 9..15.
0098 
0099         @param memLevel How much memory should be allocated for the internal
0100         compression state, with level from from 1 to 9.
0101 
0102         @param strategy Strategy to tune the compression algorithm.
0103 
0104         @note Any unprocessed input or pending output from
0105         previous calls are discarded.
0106     */
0107     void
0108     reset(
0109         int level,
0110         int windowBits,
0111         int memLevel,
0112         Strategy strategy)
0113     {
0114         doReset(level, windowBits, memLevel, strategy);
0115     }
0116 
0117     /** Reset the stream without deallocating memory.
0118 
0119         This function performs the equivalent of calling `clear`
0120         followed by `reset` with the same compression settings,
0121         without deallocating the internal buffers.
0122 
0123         @note Any unprocessed input or pending output from
0124         previous calls are discarded.
0125     */
0126     void
0127     reset()
0128     {
0129         doReset();
0130     }
0131 
0132     /** Clear the stream.
0133 
0134         This function resets the stream and frees all dynamically
0135         allocated internal buffers. The compression settings are
0136         left unchanged.
0137 
0138         @note Any unprocessed input or pending output from
0139         previous calls are discarded.
0140     */
0141     void
0142     clear()
0143     {
0144         doClear();
0145     }
0146 
0147     /** Returns the upper limit on the size of a compressed block.
0148 
0149         This function makes a conservative estimate of the maximum number
0150         of bytes needed to store the result of compressing a block of
0151         data based on the current compression level and strategy.
0152 
0153         @param sourceLen The size of the uncompressed data.
0154 
0155         @return The maximum number of resulting compressed bytes.
0156     */
0157     std::size_t
0158     upper_bound(std::size_t sourceLen) const
0159     {
0160         return doUpperBound(sourceLen);
0161     }
0162 
0163     /** Fine tune internal compression parameters.
0164 
0165         Compression parameters should only be tuned by someone who
0166         understands the algorithm used by zlib's deflate for searching
0167         for the best matching string, and even then only by the most
0168         fanatic optimizer trying to squeeze out the last compressed bit
0169         for their specific input data. Read the deflate.c source code
0170         (ZLib) for the meaning of the max_lazy, good_length, nice_length,
0171         and max_chain parameters.
0172     */
0173     void
0174     tune(
0175         int good_length,
0176         int max_lazy,
0177         int nice_length,
0178         int max_chain)
0179     {
0180         doTune(good_length, max_lazy, nice_length, max_chain);
0181     }
0182 
0183     /** Compress input and write output.
0184 
0185         This function compresses as much data as possible, and stops when
0186         the input buffer becomes empty or the output buffer becomes full.
0187         It may introduce some output latency (reading input without
0188         producing any output) except when forced to flush.
0189 
0190         In each call, one or both of these actions are performed:
0191 
0192         @li Compress more input starting at `zs.next_in` and update
0193         `zs.next_in` and `zs.avail_in` accordingly. If not all
0194         input can be processed (because there is not enough room in
0195         the output buffer), `zs.next_in` and `zs.avail_in` are updated
0196         and processing will resume at this point for the next call.
0197 
0198         @li Provide more output starting at `zs.next_out` and update
0199         `zs.next_out` and `zs.avail_out` accordingly. This action is
0200         forced if the parameter flush is not `Flush::none`. Forcing
0201         flush frequently degrades the compression ratio, so this parameter
0202         should be set only when necessary (in interactive applications).
0203         Some output may be provided even if flush is not set.
0204 
0205         Before the call, the application must ensure that at least one
0206         of the actions is possible, by providing more input and/or
0207         consuming more output, and updating `zs.avail_in` or `zs.avail_out`
0208         accordingly; `zs.avail_out` should never be zero before the call.
0209         The application can consume the compressed output when it wants,
0210         for example when the output buffer is full (`zs.avail_out == 0`),
0211         or after each call of `write`. If `write` returns no error
0212         with zero `zs.avail_out`, it must be called again after making
0213         room in the output buffer because there might be more output
0214         pending.
0215 
0216         Normally the parameter flush is set to `Flush::none`, which allows
0217         deflate to decide how much data to accumulate before producing
0218         output, in order to maximize compression.
0219 
0220         If the parameter flush is set to `Flush::sync`, all pending output
0221         is flushed to the output buffer and the output is aligned on a
0222         byte boundary, so that the decompressor can get all input data
0223         available so far. In particular `zs.avail_in` is zero after the
0224         call if enough output space has been provided before the call.
0225         Flushing may degrade compression for some compression algorithms
0226         and so it should be used only when necessary. This completes the
0227         current deflate block and follows it with an empty stored block
0228         that is three bits plus filler bits to the next byte, followed
0229         by the four bytes `{ 0x00, 0x00 0xff 0xff }`.
0230 
0231         If flush is set to `Flush::partial`, all pending output is flushed
0232         to the output buffer, but the output is not aligned to a byte
0233         boundary. All of the input data so far will be available to the
0234         decompressor, as for Z_SYNC_FLUSH. This completes the current
0235         deflate block and follows it with an empty fixed codes block that
0236         is 10 bits long. This assures that enough bytes are output in order
0237         for the decompressor to finish the block before the empty fixed
0238         code block.
0239 
0240         If flush is set to `Flush::block`, a deflate block is completed
0241         and emitted, as for `Flush::sync`, but the output is not aligned
0242         on a byte boundary, and up to seven bits of the current block are
0243         held to be written as the next byte after the next deflate block
0244         is completed. In this case, the decompressor may not be provided
0245         enough bits at this point in order to complete decompression of
0246         the data provided so far to the compressor. It may need to wait
0247         for the next block to be emitted. This is for advanced applications
0248         that need to control the emission of deflate blocks.
0249 
0250         If flush is set to `Flush::full`, all output is flushed as with
0251         `Flush::sync`, and the compression state is reset so that
0252         decompression can restart from this point if previous compressed
0253         data has been damaged or if random access is desired. Using
0254         `Flush::full` too often can seriously degrade compression.
0255 
0256         If `write` returns with `zs.avail_out == 0`, this function must
0257         be called again with the same value of the flush parameter and
0258         more output space (updated `zs.avail_out`), until the flush is
0259         complete (`write` returns with non-zero `zs.avail_out`). In the
0260         case of a `Flush::full`or `Flush::sync`, make sure that
0261         `zs.avail_out` is greater than six to avoid repeated flush markers
0262         due to `zs.avail_out == 0` on return.
0263 
0264         If the parameter flush is set to `Flush::finish`, pending input
0265         is processed, pending output is flushed and deflate returns the
0266         error `error::end_of_stream` if there was enough output space;
0267         if deflate returns with no error, this function must be called
0268         again with `Flush::finish` and more output space (updated
0269         `zs.avail_out`) but no more input data, until it returns the
0270         error `error::end_of_stream` or another error. After `write` has
0271         returned the `error::end_of_stream` error, the only possible
0272         operations on the stream are to reset or destroy.
0273 
0274         `Flush::finish` can be used immediately after initialization
0275         if all the compression is to be done in a single step. In this
0276         case, `zs.avail_out` must be at least value returned by
0277         `upper_bound` (see below). Then `write` is guaranteed to return
0278         the `error::end_of_stream` error. If not enough output space
0279         is provided, deflate will not return `error::end_of_stream`,
0280         and it must be called again as described above.
0281 
0282         `write` returns no error if some progress has been made (more
0283         input processed or more output produced), `error::end_of_stream`
0284         if all input has been consumed and all output has been produced
0285         (only when flush is set to `Flush::finish`), `error::stream_error`
0286         if the stream state was inconsistent (for example if `zs.next_in`
0287         or `zs.next_out` was `nullptr`), `error::need_buffers` if no
0288         progress is possible (for example `zs.avail_in` or `zs.avail_out`
0289         was zero). Note that `error::need_buffers` is not fatal, and
0290         `write` can be called again with more input and more output space
0291         to continue compressing.
0292     */
0293     void
0294     write(
0295         z_params& zs,
0296         Flush flush,
0297         error_code& ec)
0298     {
0299         doWrite(zs, flush, ec);
0300     }
0301 
0302     /** Update the compression level and strategy.
0303 
0304         This function dynamically updates the compression level and
0305         compression strategy. The interpretation of level and strategy
0306         is as in @ref reset. This can be used to switch between compression
0307         and straight copy of the input data, or to switch to a different kind
0308         of input data requiring a different strategy. If the compression level
0309         is changed, the input available so far is compressed with the old level
0310         (and may be flushed); the new level will take effect only at the next
0311         call of @ref write.
0312 
0313         Before the call of `params`, the stream state must be set as for a
0314         call of @ref write, since the currently available input may have to be
0315         compressed and flushed. In particular, `zs.avail_out` must be non-zero.
0316 
0317         @return `Z_OK` if success, `Z_STREAM_ERROR` if the source stream state
0318         was inconsistent or if a parameter was invalid, `error::need_buffers`
0319         if `zs.avail_out` was zero.
0320     */
0321     void
0322     params(
0323         z_params& zs,
0324         int level,
0325         Strategy strategy,
0326         error_code& ec)
0327     {
0328         doParams(zs, level, strategy, ec);
0329     }
0330 
0331     /** Return bits pending in the output.
0332 
0333         This function returns the number of bytes and bits of output
0334         that have been generated, but not yet provided in the available
0335         output. The bytes not provided would be due to the available
0336         output space having being consumed. The number of bits of output
0337         not provided are between 0 and 7, where they await more bits to
0338         join them in order to fill out a full byte. If pending or bits
0339         are `nullptr`, then those values are not set.
0340 
0341         @return `Z_OK` if success, or `Z_STREAM_ERROR` if the source
0342         stream state was inconsistent.
0343     */
0344     void
0345     pending(unsigned *value, int *bits)
0346     {
0347         doPending(value, bits);
0348     }
0349 
0350     /** Insert bits into the compressed output stream.
0351 
0352         This function inserts bits in the deflate output stream. The
0353         intent is that this function is used to start off the deflate
0354         output with the bits leftover from a previous deflate stream when
0355         appending to it. As such, this function can only be used for raw
0356         deflate, and must be used before the first `write` call after an
0357         initialization. `bits` must be less than or equal to 16, and that
0358         many of the least significant bits of `value` will be inserted in
0359         the output.
0360 
0361         @return `error::need_buffers` if there was not enough room in
0362         the internal buffer to insert the bits.
0363     */
0364     void
0365     prime(int bits, int value, error_code& ec)
0366     {
0367         return doPrime(bits, value, ec);
0368     }
0369 };
0370 
0371 /** Returns the upper limit on the size of a compressed block.
0372 
0373     This function makes a conservative estimate of the maximum number
0374     of bytes needed to store the result of compressing a block of
0375     data.
0376 
0377 
0378 
0379     @param bytes The size of the uncompressed data.
0380 
0381     @return The maximum number of resulting compressed bytes.
0382 */
0383 std::size_t
0384 deflate_upper_bound(std::size_t bytes);
0385 
0386 /*  For the default windowBits of 15 and memLevel of 8, this function returns
0387     a close to exact, as well as small, upper bound on the compressed size.
0388     They are coded as constants here for a reason--if the #define's are
0389     changed, then this function needs to be changed as well.  The return
0390     value for 15 and 8 only works for those exact settings.
0391 
0392     For any setting other than those defaults for windowBits and memLevel,
0393     the value returned is a conservative worst case for the maximum expansion
0394     resulting from using fixed blocks instead of stored blocks, which deflate
0395     can emit on compressed data for some combinations of the parameters.
0396 
0397     This function could be more sophisticated to provide closer upper bounds for
0398     every combination of windowBits and memLevel.  But even the conservative
0399     upper bound of about 14% expansion does not seem onerous for output buffer
0400     allocation.
0401 */
0402 inline
0403 std::size_t
0404 deflate_upper_bound(std::size_t bytes)
0405 {
0406     return bytes +
0407         ((bytes + 7) >> 3) +
0408         ((bytes + 63) >> 6) + 5 +
0409         6;
0410 }
0411 
0412 } // zlib
0413 } // beast
0414 } // boost
0415 
0416 #endif