add boost on mac

This commit is contained in:
Bassem Girgis
2019-08-10 16:38:17 -05:00
parent 861b918727
commit be945cb63b
14105 changed files with 2714968 additions and 0 deletions

View File

@@ -0,0 +1,404 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
#ifndef BOOST_BEAST_ZLIB_DEFLATE_STREAM_HPP
#define BOOST_BEAST_ZLIB_DEFLATE_STREAM_HPP
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/zlib/error.hpp>
#include <boost/beast/zlib/zlib.hpp>
#include <boost/beast/zlib/detail/deflate_stream.hpp>
#include <algorithm>
#include <cstdlib>
#include <cstdint>
#include <cstring>
#include <memory>
namespace boost {
namespace beast {
namespace zlib {
// This is a derivative work based on Zlib, copyright below:
/*
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
/** Raw deflate compressor.
This is a port of zlib's "deflate" functionality to C++.
*/
class deflate_stream
: private detail::deflate_stream
{
public:
/** Construct a default deflate stream.
Upon construction, the stream settings will be set
to these default values:
@li `level = 6`
@li `windowBits = 15`
@li `memLevel = 8`
@li `strategy = Strategy::normal`
Although the stream is ready to be used immediately
after construction, any required internal buffers are
not dynamically allocated until needed.
*/
deflate_stream()
{
reset(6, 15, DEF_MEM_LEVEL, Strategy::normal);
}
/** Reset the stream and compression settings.
This function initializes the stream to the specified
compression settings.
Although the stream is ready to be used immediately
after a reset, any required internal buffers are not
dynamically allocated until needed.
@note Any unprocessed input or pending output from
previous calls are discarded.
*/
void
reset(
int level,
int windowBits,
int memLevel,
Strategy strategy)
{
doReset(level, windowBits, memLevel, strategy);
}
/** Reset the stream without deallocating memory.
This function performs the equivalent of calling `clear`
followed by `reset` with the same compression settings,
without deallocating the internal buffers.
@note Any unprocessed input or pending output from
previous calls are discarded.
*/
void
reset()
{
doReset();
}
/** Clear the stream.
This function resets the stream and frees all dynamically
allocated internal buffers. The compression settings are
left unchanged.
@note Any unprocessed input or pending output from
previous calls are discarded.
*/
void
clear()
{
doClear();
}
/** Returns the upper limit on the size of a compressed block.
This function makes a conservative estimate of the maximum number
of bytes needed to store the result of compressing a block of
data based on the current compression level and strategy.
@param sourceLen The size of the uncompressed data.
@return The maximum number of resulting compressed bytes.
*/
std::size_t
upper_bound(std::size_t sourceLen) const
{
return doUpperBound(sourceLen);
}
/** Fine tune internal compression parameters.
Compression parameters should only be tuned by someone who
understands the algorithm used by zlib's deflate for searching
for the best matching string, and even then only by the most
fanatic optimizer trying to squeeze out the last compressed bit
for their specific input data. Read the deflate.c source code
(ZLib) for the meaning of the max_lazy, good_length, nice_length,
and max_chain parameters.
*/
void
tune(
int good_length,
int max_lazy,
int nice_length,
int max_chain)
{
doTune(good_length, max_lazy, nice_length, max_chain);
}
/** Compress input and write output.
This function compresses as much data as possible, and stops when
the input buffer becomes empty or the output buffer becomes full.
It may introduce some output latency (reading input without
producing any output) except when forced to flush.
In each call, one or both of these actions are performed:
@li Compress more input starting at `zs.next_in` and update
`zs.next_in` and `zs.avail_in` accordingly. If not all
input can be processed (because there is not enough room in
the output buffer), `zs.next_in` and `zs.avail_in` are updated
and processing will resume at this point for the next call.
@li Provide more output starting at `zs.next_out` and update
`zs.next_out` and `zs.avail_out` accordingly. This action is
forced if the parameter flush is not `Flush::none`. Forcing
flush frequently degrades the compression ratio, so this parameter
should be set only when necessary (in interactive applications).
Some output may be provided even if flush is not set.
Before the call, the application must ensure that at least one
of the actions is possible, by providing more input and/or
consuming more output, and updating `zs.avail_in` or `zs.avail_out`
accordingly; `zs.avail_out` should never be zero before the call.
The application can consume the compressed output when it wants,
for example when the output buffer is full (`zs.avail_out == 0`),
or after each call of `write`. If `write` returns no error
with zero `zs.avail_out`, it must be called again after making
room in the output buffer because there might be more output
pending.
Normally the parameter flush is set to `Flush::none`, which allows
deflate to decide how much data to accumulate before producing
output, in order to maximize compression.
If the parameter flush is set to `Flush::sync`, all pending output
is flushed to the output buffer and the output is aligned on a
byte boundary, so that the decompressor can get all input data
available so far. In particular `zs.avail_in` is zero after the
call if enough output space has been provided before the call.
Flushing may degrade compression for some compression algorithms
and so it should be used only when necessary. This completes the
current deflate block and follows it with an empty stored block
that is three bits plus filler bits to the next byte, followed
by the four bytes `{ 0x00, 0x00 0xff 0xff }`.
If flush is set to `Flush::partial`, all pending output is flushed
to the output buffer, but the output is not aligned to a byte
boundary. All of the input data so far will be available to the
decompressor, as for Z_SYNC_FLUSH. This completes the current
deflate block and follows it with an empty fixed codes block that
is 10 bits long. This assures that enough bytes are output in order
for the decompressor to finish the block before the empty fixed
code block.
If flush is set to `Flush::block`, a deflate block is completed
and emitted, as for `Flush::sync`, but the output is not aligned
on a byte boundary, and up to seven bits of the current block are
held to be written as the next byte after the next deflate block
is completed. In this case, the decompressor may not be provided
enough bits at this point in order to complete decompression of
the data provided so far to the compressor. It may need to wait
for the next block to be emitted. This is for advanced applications
that need to control the emission of deflate blocks.
If flush is set to `Flush::full`, all output is flushed as with
`Flush::sync`, and the compression state is reset so that
decompression can restart from this point if previous compressed
data has been damaged or if random access is desired. Using
`Flush::full` too often can seriously degrade compression.
If `write` returns with `zs.avail_out == 0`, this function must
be called again with the same value of the flush parameter and
more output space (updated `zs.avail_out`), until the flush is
complete (`write` returns with non-zero `zs.avail_out`). In the
case of a `Flush::full`or `Flush::sync`, make sure that
`zs.avail_out` is greater than six to avoid repeated flush markers
due to `zs.avail_out == 0` on return.
If the parameter flush is set to `Flush::finish`, pending input
is processed, pending output is flushed and deflate returns the
error `error::end_of_stream` if there was enough output space;
if deflate returns with no error, this function must be called
again with `Flush::finish` and more output space (updated
`zs.avail_out`) but no more input data, until it returns the
error `error::end_of_stream` or another error. After `write` has
returned the `error::end_of_stream` error, the only possible
operations on the stream are to reset or destroy.
`Flush::finish` can be used immediately after initialization
if all the compression is to be done in a single step. In this
case, `zs.avail_out` must be at least value returned by
`upper_bound` (see below). Then `write` is guaranteed to return
the `error::end_of_stream` error. If not enough output space
is provided, deflate will not return `error::end_of_stream`,
and it must be called again as described above.
`write` returns no error if some progress has been made (more
input processed or more output produced), `error::end_of_stream`
if all input has been consumed and all output has been produced
(only when flush is set to `Flush::finish`), `error::stream_error`
if the stream state was inconsistent (for example if `zs.next_in`
or `zs.next_out` was `nullptr`), `error::need_buffers` if no
progress is possible (for example `zs.avail_in` or `zs.avail_out`
was zero). Note that `error::need_buffers` is not fatal, and
`write` can be called again with more input and more output space
to continue compressing.
*/
void
write(
z_params& zs,
Flush flush,
error_code& ec)
{
doWrite(zs, flush, ec);
}
/** Update the compression level and strategy.
This function dynamically updates the compression level and
compression strategy. The interpretation of level and strategy
is as in @ref reset. This can be used to switch between compression
and straight copy of the input data, or to switch to a different kind
of input data requiring a different strategy. If the compression level
is changed, the input available so far is compressed with the old level
(and may be flushed); the new level will take effect only at the next
call of @ref write.
Before the call of `params`, the stream state must be set as for a
call of @ref write, since the currently available input may have to be
compressed and flushed. In particular, `zs.avail_out` must be non-zero.
@return `Z_OK` if success, `Z_STREAM_ERROR` if the source stream state
was inconsistent or if a parameter was invalid, `error::need_buffers`
if `zs.avail_out` was zero.
*/
void
params(
z_params& zs,
int level,
Strategy strategy,
error_code& ec)
{
doParams(zs, level, strategy, ec);
}
/** Return bits pending in the output.
This function returns the number of bytes and bits of output
that have been generated, but not yet provided in the available
output. The bytes not provided would be due to the available
output space having being consumed. The number of bits of output
not provided are between 0 and 7, where they await more bits to
join them in order to fill out a full byte. If pending or bits
are `nullptr`, then those values are not set.
@return `Z_OK` if success, or `Z_STREAM_ERROR` if the source
stream state was inconsistent.
*/
void
pending(unsigned *value, int *bits)
{
doPending(value, bits);
}
/** Insert bits into the compressed output stream.
This function inserts bits in the deflate output stream. The
intent is that this function is used to start off the deflate
output with the bits leftover from a previous deflate stream when
appending to it. As such, this function can only be used for raw
deflate, and must be used before the first `write` call after an
initialization. `bits` must be less than or equal to 16, and that
many of the least significant bits of `value` will be inserted in
the output.
@return `error::need_buffers` if there was not enough room in
the internal buffer to insert the bits.
*/
void
prime(int bits, int value, error_code& ec)
{
return doPrime(bits, value, ec);
}
};
/** Returns the upper limit on the size of a compressed block.
This function makes a conservative estimate of the maximum number
of bytes needed to store the result of compressing a block of
data.
@param bytes The size of the uncompressed data.
@return The maximum number of resulting compressed bytes.
*/
std::size_t
deflate_upper_bound(std::size_t bytes);
/* For the default windowBits of 15 and memLevel of 8, this function returns
a close to exact, as well as small, upper bound on the compressed size.
They are coded as constants here for a reason--if the #define's are
changed, then this function needs to be changed as well. The return
value for 15 and 8 only works for those exact settings.
For any setting other than those defaults for windowBits and memLevel,
the value returned is a conservative worst case for the maximum expansion
resulting from using fixed blocks instead of stored blocks, which deflate
can emit on compressed data for some combinations of the parameters.
This function could be more sophisticated to provide closer upper bounds for
every combination of windowBits and memLevel. But even the conservative
upper bound of about 14% expansion does not seem onerous for output buffer
allocation.
*/
inline
std::size_t
deflate_upper_bound(std::size_t bytes)
{
return bytes +
((bytes + 7) >> 3) +
((bytes + 63) >> 6) + 5 +
6;
}
} // zlib
} // beast
} // boost
#endif

View File

@@ -0,0 +1,201 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// This is a derivative work based on Zlib, copyright below:
/*
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef BOOST_BEAST_ZLIB_DETAIL_BITSTREAM_HPP
#define BOOST_BEAST_ZLIB_DETAIL_BITSTREAM_HPP
#include <boost/assert.hpp>
#include <cstdint>
#include <iterator>
namespace boost {
namespace beast {
namespace zlib {
namespace detail {
class bitstream
{
using value_type = std::uint32_t;
value_type v_ = 0;
unsigned n_ = 0;
public:
// returns the number of bits in the reservoir
unsigned
size() const
{
return n_;
}
// discard n bits
void
drop(std::size_t n)
{
BOOST_ASSERT(n <= n_);
n_ -= static_cast<unsigned>(n);
v_ >>= n;
}
// flush everything
void
flush()
{
n_ = 0;
v_ = 0;
}
// flush to the next byte boundary
void
flush_byte()
{
drop(n_ % 8);
}
// ensure at least n bits
template<class FwdIt>
bool
fill(std::size_t n, FwdIt& first, FwdIt const& last);
// fill 8 bits, unchecked
template<class FwdIt>
void
fill_8(FwdIt& it);
// fill 16 bits, unchecked
template<class FwdIt>
void
fill_16(FwdIt& it);
// return n bits
template<class Unsigned>
void
peek(Unsigned& value, std::size_t n);
// return everything in the reservoir
value_type
peek_fast() const
{
return v_;
}
// return n bits, and consume
template<class Unsigned>
void
read(Unsigned& value, std::size_t n);
// rewind by the number of whole bytes stored (unchecked)
template<class BidirIt>
void
rewind(BidirIt& it);
};
template<class FwdIt>
bool
bitstream::
fill(std::size_t n, FwdIt& first, FwdIt const& last)
{
while(n_ < n)
{
if(first == last)
return false;
v_ += static_cast<value_type>(*first++) << n_;
n_ += 8;
}
return true;
}
template<class FwdIt>
void
bitstream::
fill_8(FwdIt& it)
{
v_ += static_cast<value_type>(*it++) << n_;
n_ += 8;
}
template<class FwdIt>
void
bitstream::
fill_16(FwdIt& it)
{
v_ += static_cast<value_type>(*it++) << n_;
n_ += 8;
v_ += static_cast<value_type>(*it++) << n_;
n_ += 8;
}
template<class Unsigned>
void
bitstream::
peek(Unsigned& value, std::size_t n)
{
BOOST_ASSERT(n <= sizeof(value)*8);
BOOST_ASSERT(n <= n_);
value = static_cast<Unsigned>(
v_ & ((1ULL << n) - 1));
}
template<class Unsigned>
void
bitstream::
read(Unsigned& value, std::size_t n)
{
BOOST_ASSERT(n < sizeof(v_)*8);
BOOST_ASSERT(n <= n_);
value = static_cast<Unsigned>(
v_ & ((1ULL << n) - 1));
v_ >>= n;
n_ -= static_cast<unsigned>(n);
}
template<class BidirIt>
void
bitstream::
rewind(BidirIt& it)
{
auto len = n_ >> 3;
it = std::prev(it, len);
n_ &= 7;
v_ &= (1U << n_) - 1;
}
} // detail
} // zlib
} // beast
} // boost
#endif

View File

@@ -0,0 +1,728 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// This is a derivative work based on Zlib, copyright below:
/*
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef BOOST_BEAST_ZLIB_DETAIL_DEFLATE_STREAM_HPP
#define BOOST_BEAST_ZLIB_DETAIL_DEFLATE_STREAM_HPP
#include <boost/beast/zlib/error.hpp>
#include <boost/beast/zlib/zlib.hpp>
#include <boost/beast/zlib/detail/ranges.hpp>
#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/optional.hpp>
#include <boost/throw_exception.hpp>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <stdexcept>
#include <type_traits>
namespace boost {
namespace beast {
namespace zlib {
namespace detail {
class deflate_stream
{
protected:
// Upper limit on code length
static std::uint8_t constexpr maxBits = 15;
// Number of length codes, not counting the special END_BLOCK code
static std::uint16_t constexpr lengthCodes = 29;
// Number of literal bytes 0..255
static std::uint16_t constexpr literals = 256;
// Number of Literal or Length codes, including the END_BLOCK code
static std::uint16_t constexpr lCodes = literals + 1 + lengthCodes;
// Number of distance code lengths
static std::uint16_t constexpr dCodes = 30;
// Number of codes used to transfer the bit lengths
static std::uint16_t constexpr blCodes = 19;
// Number of distance codes
static std::uint16_t constexpr distCodeLen = 512;
// Size limit on bit length codes
static std::uint8_t constexpr maxBlBits= 7;
static std::uint16_t constexpr minMatch = 3;
static std::uint16_t constexpr maxMatch = 258;
// Can't change minMatch without also changing code, see original zlib
BOOST_STATIC_ASSERT(minMatch == 3);
// end of block literal code
static std::uint16_t constexpr END_BLOCK = 256;
// repeat previous bit length 3-6 times (2 bits of repeat count)
static std::uint8_t constexpr REP_3_6 = 16;
// repeat a zero length 3-10 times (3 bits of repeat count)
static std::uint8_t constexpr REPZ_3_10 = 17;
// repeat a zero length 11-138 times (7 bits of repeat count)
static std::uint8_t constexpr REPZ_11_138 = 18;
// The three kinds of block type
static std::uint8_t constexpr STORED_BLOCK = 0;
static std::uint8_t constexpr STATIC_TREES = 1;
static std::uint8_t constexpr DYN_TREES = 2;
// Maximum value for memLevel in deflateInit2
static std::uint8_t constexpr max_mem_level = 9;
// Default memLevel
static std::uint8_t constexpr DEF_MEM_LEVEL = max_mem_level;
/* Note: the deflate() code requires max_lazy >= minMatch and max_chain >= 4
For deflate_fast() (levels <= 3) good is ignored and lazy has a different
meaning.
*/
// maximum heap size
static std::uint16_t constexpr HEAP_SIZE = 2 * lCodes + 1;
// size of bit buffer in bi_buf
static std::uint8_t constexpr Buf_size = 16;
// Matches of length 3 are discarded if their distance exceeds kTooFar
static std::size_t constexpr kTooFar = 4096;
/* Minimum amount of lookahead, except at the end of the input file.
See deflate.c for comments about the minMatch+1.
*/
static std::size_t constexpr kMinLookahead = maxMatch + minMatch+1;
/* Number of bytes after end of data in window to initialize in order
to avoid memory checker errors from longest match routines
*/
static std::size_t constexpr kWinInit = maxMatch;
// Describes a single value and its code string.
struct ct_data
{
std::uint16_t fc; // frequency count or bit string
std::uint16_t dl; // parent node in tree or length of bit string
bool
operator==(ct_data const& rhs) const
{
return fc == rhs.fc && dl == rhs.dl;
}
};
struct static_desc
{
ct_data const* static_tree;// static tree or NULL
std::uint8_t const* extra_bits; // extra bits for each code or NULL
std::uint16_t extra_base; // base index for extra_bits
std::uint16_t elems; // max number of elements in the tree
std::uint8_t max_length; // max bit length for the codes
};
struct lut_type
{
// Number of extra bits for each length code
std::uint8_t const extra_lbits[lengthCodes] = {
0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0
};
// Number of extra bits for each distance code
std::uint8_t const extra_dbits[dCodes] = {
0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13
};
// Number of extra bits for each bit length code
std::uint8_t const extra_blbits[blCodes] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7
};
// The lengths of the bit length codes are sent in order
// of decreasing probability, to avoid transmitting the
// lengths for unused bit length codes.
std::uint8_t const bl_order[blCodes] = {
16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15
};
ct_data ltree[lCodes + 2];
ct_data dtree[dCodes];
// Distance codes. The first 256 values correspond to the distances
// 3 .. 258, the last 256 values correspond to the top 8 bits of
// the 15 bit distances.
std::uint8_t dist_code[distCodeLen];
std::uint8_t length_code[maxMatch-minMatch+1];
std::uint8_t base_length[lengthCodes];
std::uint16_t base_dist[dCodes];
static_desc l_desc = {
ltree, extra_lbits, literals+1, lCodes, maxBits
};
static_desc d_desc = {
dtree, extra_dbits, 0, dCodes, maxBits
};
static_desc bl_desc =
{
nullptr, extra_blbits, 0, blCodes, maxBlBits
};
};
struct tree_desc
{
ct_data *dyn_tree; /* the dynamic tree */
int max_code; /* largest code with non zero frequency */
static_desc const* stat_desc; /* the corresponding static tree */
};
enum block_state
{
need_more, /* block not completed, need more input or more output */
block_done, /* block flush performed */
finish_started, /* finish started, need only more output at next deflate */
finish_done /* finish done, accept no more input or output */
};
// VFALCO This might not be needed, e.g. for zip/gzip
enum StreamStatus
{
EXTRA_STATE = 69,
NAME_STATE = 73,
COMMENT_STATE = 91,
HCRC_STATE = 103,
BUSY_STATE = 113,
FINISH_STATE = 666
};
/* A std::uint16_t is an index in the character window. We use short instead of int to
* save space in the various tables. IPos is used only for parameter passing.
*/
using IPos = unsigned;
using self = deflate_stream;
typedef block_state(self::*compress_func)(z_params& zs, Flush flush);
//--------------------------------------------------------------------------
lut_type const& lut_;
bool inited_ = false;
std::size_t buf_size_;
std::unique_ptr<std::uint8_t[]> buf_;
int status_; // as the name implies
Byte* pending_buf_; // output still pending
std::uint32_t
pending_buf_size_; // size of pending_buf
Byte* pending_out_; // next pending byte to output to the stream
uInt pending_; // nb of bytes in the pending buffer
boost::optional<Flush>
last_flush_; // value of flush param for previous deflate call
uInt w_size_; // LZ77 window size (32K by default)
uInt w_bits_; // log2(w_size) (8..16)
uInt w_mask_; // w_size - 1
/* Sliding window. Input bytes are read into the second half of the window,
and move to the first half later to keep a dictionary of at least wSize
bytes. With this organization, matches are limited to a distance of
wSize-maxMatch bytes, but this ensures that IO is always
performed with a length multiple of the block size. Also, it limits
the window size to 64K.
To do: use the user input buffer as sliding window.
*/
Byte *window_ = nullptr;
/* Actual size of window: 2*wSize, except when the user input buffer
is directly used as sliding window.
*/
std::uint32_t window_size_;
/* Link to older string with same hash index. To limit the size of this
array to 64K, this link is maintained only for the last 32K strings.
An index in this array is thus a window index modulo 32K.
*/
std::uint16_t* prev_;
std::uint16_t* head_; // Heads of the hash chains or 0
uInt ins_h_; // hash index of string to be inserted
uInt hash_size_; // number of elements in hash table
uInt hash_bits_; // log2(hash_size)
uInt hash_mask_; // hash_size-1
/* Number of bits by which ins_h must be shifted at each input
step. It must be such that after minMatch steps,
the oldest byte no longer takes part in the hash key, that is:
hash_shift * minMatch >= hash_bits
*/
uInt hash_shift_;
/* Window position at the beginning of the current output block.
Gets negative when the window is moved backwards.
*/
long block_start_;
uInt match_length_; // length of best match
IPos prev_match_; // previous match
int match_available_; // set if previous match exists
uInt strstart_; // start of string to insert
uInt match_start_; // start of matching string
uInt lookahead_; // number of valid bytes ahead in window
/* Length of the best match at previous step. Matches not greater
than this are discarded. This is used in the lazy match evaluation.
*/
uInt prev_length_;
/* To speed up deflation, hash chains are never searched beyond
this length. A higher limit improves compression ratio but
degrades the speed.
*/
uInt max_chain_length_;
/* Attempt to find a better match only when the current match is strictly
smaller than this value. This mechanism is used only for compression
levels >= 4.
OR Insert new strings in the hash table only if the match length is not
greater than this length. This saves time but degrades compression.
used only for compression levels <= 3.
*/
uInt max_lazy_match_;
int level_; // compression level (1..9)
Strategy strategy_; // favor or force Huffman coding
// Use a faster search when the previous match is longer than this
uInt good_match_;
int nice_match_; // Stop searching when current match exceeds this
ct_data dyn_ltree_[
HEAP_SIZE]; // literal and length tree
ct_data dyn_dtree_[
2*dCodes+1]; // distance tree
ct_data bl_tree_[
2*blCodes+1]; // Huffman tree for bit lengths
tree_desc l_desc_; // desc. for literal tree
tree_desc d_desc_; // desc. for distance tree
tree_desc bl_desc_; // desc. for bit length tree
// number of codes at each bit length for an optimal tree
std::uint16_t bl_count_[maxBits+1];
// Index within the heap array of least frequent node in the Huffman tree
static std::size_t constexpr kSmallest = 1;
/* The sons of heap[n] are heap[2*n] and heap[2*n+1].
heap[0] is not used. The same heap array is used to build all trees.
*/
int heap_[2*lCodes+1]; // heap used to build the Huffman trees
int heap_len_; // number of elements in the heap
int heap_max_; // element of largest frequency
// Depth of each subtree used as tie breaker for trees of equal frequency
std::uint8_t depth_[2*lCodes+1];
std::uint8_t *l_buf_; // buffer for literals or lengths
/* Size of match buffer for literals/lengths.
There are 4 reasons for limiting lit_bufsize to 64K:
- frequencies can be kept in 16 bit counters
- if compression is not successful for the first block, all input
data is still in the window so we can still emit a stored block even
when input comes from standard input. (This can also be done for
all blocks if lit_bufsize is not greater than 32K.)
- if compression is not successful for a file smaller than 64K, we can
even emit a stored file instead of a stored block (saving 5 bytes).
This is applicable only for zip (not gzip or zlib).
- creating new Huffman trees less frequently may not provide fast
adaptation to changes in the input data statistics. (Take for
example a binary file with poorly compressible code followed by
a highly compressible string table.) Smaller buffer sizes give
fast adaptation but have of course the overhead of transmitting
trees more frequently.
- I can't count above 4
*/
uInt lit_bufsize_;
uInt last_lit_; // running index in l_buf_
/* Buffer for distances. To simplify the code, d_buf_ and l_buf_
have the same number of elements. To use different lengths, an
extra flag array would be necessary.
*/
std::uint16_t* d_buf_;
std::uint32_t opt_len_; // bit length of current block with optimal trees
std::uint32_t static_len_; // bit length of current block with static trees
uInt matches_; // number of string matches in current block
uInt insert_; // bytes at end of window left to insert
/* Output buffer.
Bits are inserted starting at the bottom (least significant bits).
*/
std::uint16_t bi_buf_;
/* Number of valid bits in bi_buf._ All bits above the last valid
bit are always zero.
*/
int bi_valid_;
/* High water mark offset in window for initialized bytes -- bytes
above this are set to zero in order to avoid memory check warnings
when longest match routines access bytes past the input. This is
then updated to the new high water mark.
*/
std::uint32_t high_water_;
//--------------------------------------------------------------------------
deflate_stream()
: lut_(get_lut())
{
}
/* In order to simplify the code, particularly on 16 bit machines, match
distances are limited to MAX_DIST instead of WSIZE.
*/
std::size_t
max_dist() const
{
return w_size_ - kMinLookahead;
}
void
put_byte(std::uint8_t c)
{
pending_buf_[pending_++] = c;
}
void
put_short(std::uint16_t w)
{
put_byte(w & 0xff);
put_byte(w >> 8);
}
/* Send a value on a given number of bits.
IN assertion: length <= 16 and value fits in length bits.
*/
void
send_bits(int value, int length)
{
if(bi_valid_ > (int)Buf_size - length)
{
bi_buf_ |= (std::uint16_t)value << bi_valid_;
put_short(bi_buf_);
bi_buf_ = (std::uint16_t)value >> (Buf_size - bi_valid_);
bi_valid_ += length - Buf_size;
}
else
{
bi_buf_ |= (std::uint16_t)(value) << bi_valid_;
bi_valid_ += length;
}
}
// Send a code of the given tree
void
send_code(int value, ct_data const* tree)
{
send_bits(tree[value].fc, tree[value].dl);
}
/* Mapping from a distance to a distance code. dist is the
distance - 1 and must not have side effects. _dist_code[256]
and _dist_code[257] are never used.
*/
std::uint8_t
d_code(unsigned dist)
{
if(dist < 256)
return lut_.dist_code[dist];
return lut_.dist_code[256+(dist>>7)];
}
/* Update a hash value with the given input byte
IN assertion: all calls to to update_hash are made with
consecutive input characters, so that a running hash
key can be computed from the previous key instead of
complete recalculation each time.
*/
void
update_hash(uInt& h, std::uint8_t c)
{
h = ((h << hash_shift_) ^ c) & hash_mask_;
}
/* Initialize the hash table (avoiding 64K overflow for 16
bit systems). prev[] will be initialized on the fly.
*/
void
clear_hash()
{
head_[hash_size_-1] = 0;
std::memset((Byte *)head_, 0,
(unsigned)(hash_size_-1)*sizeof(*head_));
}
/* Compares two subtrees, using the tree depth as tie breaker
when the subtrees have equal frequency. This minimizes the
worst case length.
*/
bool
smaller(ct_data const* tree, int n, int m)
{
return tree[n].fc < tree[m].fc ||
(tree[n].fc == tree[m].fc &&
depth_[n] <= depth_[m]);
}
/* Insert string str in the dictionary and set match_head to the
previous head of the hash chain (the most recent string with
same hash key). Return the previous length of the hash chain.
If this file is compiled with -DFASTEST, the compression level
is forced to 1, and no hash chains are maintained.
IN assertion: all calls to to INSERT_STRING are made with
consecutive input characters and the first minMatch
bytes of str are valid (except for the last minMatch-1
bytes of the input file).
*/
void
insert_string(IPos& hash_head)
{
update_hash(ins_h_, window_[strstart_ + (minMatch-1)]);
hash_head = prev_[strstart_ & w_mask_] = head_[ins_h_];
head_[ins_h_] = (std::uint16_t)strstart_;
}
//--------------------------------------------------------------------------
/* Values for max_lazy_match, good_match and max_chain_length, depending on
* the desired pack level (0..9). The values given below have been tuned to
* exclude worst case performance for pathological files. Better values may be
* found for specific files.
*/
struct config
{
std::uint16_t good_length; /* reduce lazy search above this match length */
std::uint16_t max_lazy; /* do not perform lazy search above this match length */
std::uint16_t nice_length; /* quit search above this match length */
std::uint16_t max_chain;
compress_func func;
config(
std::uint16_t good_length_,
std::uint16_t max_lazy_,
std::uint16_t nice_length_,
std::uint16_t max_chain_,
compress_func func_)
: good_length(good_length_)
, max_lazy(max_lazy_)
, nice_length(nice_length_)
, max_chain(max_chain_)
, func(func_)
{
}
};
static
config
get_config(std::size_t level)
{
switch(level)
{
// good lazy nice chain
case 0: return { 0, 0, 0, 0, &self::deflate_stored}; // store only
case 1: return { 4, 4, 8, 4, &self::deflate_fast}; // max speed, no lazy matches
case 2: return { 4, 5, 16, 8, &self::deflate_fast};
case 3: return { 4, 6, 32, 32, &self::deflate_fast};
case 4: return { 4, 4, 16, 16, &self::deflate_slow}; // lazy matches
case 5: return { 8, 16, 32, 32, &self::deflate_slow};
case 6: return { 8, 16, 128, 128, &self::deflate_slow};
case 7: return { 8, 32, 128, 256, &self::deflate_slow};
case 8: return { 32, 128, 258, 1024, &self::deflate_slow};
default:
case 9: return { 32, 258, 258, 4096, &self::deflate_slow}; // max compression
}
}
void
maybe_init()
{
if(! inited_)
init();
}
template<class Unsigned>
static
Unsigned
bi_reverse(Unsigned code, unsigned len);
BOOST_BEAST_DECL
static
void
gen_codes(ct_data *tree, int max_code, std::uint16_t *bl_count);
BOOST_BEAST_DECL
static
lut_type const&
get_lut();
BOOST_BEAST_DECL void doReset (int level, int windowBits, int memLevel, Strategy strategy);
BOOST_BEAST_DECL void doReset ();
BOOST_BEAST_DECL void doClear ();
BOOST_BEAST_DECL std::size_t doUpperBound (std::size_t sourceLen) const;
BOOST_BEAST_DECL void doTune (int good_length, int max_lazy, int nice_length, int max_chain);
BOOST_BEAST_DECL void doParams (z_params& zs, int level, Strategy strategy, error_code& ec);
BOOST_BEAST_DECL void doWrite (z_params& zs, boost::optional<Flush> flush, error_code& ec);
BOOST_BEAST_DECL void doDictionary (Byte const* dict, uInt dictLength, error_code& ec);
BOOST_BEAST_DECL void doPrime (int bits, int value, error_code& ec);
BOOST_BEAST_DECL void doPending (unsigned* value, int* bits);
BOOST_BEAST_DECL void init ();
BOOST_BEAST_DECL void lm_init ();
BOOST_BEAST_DECL void init_block ();
BOOST_BEAST_DECL void pqdownheap (ct_data const* tree, int k);
BOOST_BEAST_DECL void pqremove (ct_data const* tree, int& top);
BOOST_BEAST_DECL void gen_bitlen (tree_desc *desc);
BOOST_BEAST_DECL void build_tree (tree_desc *desc);
BOOST_BEAST_DECL void scan_tree (ct_data *tree, int max_code);
BOOST_BEAST_DECL void send_tree (ct_data *tree, int max_code);
BOOST_BEAST_DECL int build_bl_tree ();
BOOST_BEAST_DECL void send_all_trees (int lcodes, int dcodes, int blcodes);
BOOST_BEAST_DECL void compress_block (ct_data const* ltree, ct_data const* dtree);
BOOST_BEAST_DECL int detect_data_type ();
BOOST_BEAST_DECL void bi_windup ();
BOOST_BEAST_DECL void bi_flush ();
BOOST_BEAST_DECL void copy_block (char *buf, unsigned len, int header);
BOOST_BEAST_DECL void tr_init ();
BOOST_BEAST_DECL void tr_align ();
BOOST_BEAST_DECL void tr_flush_bits ();
BOOST_BEAST_DECL void tr_stored_block (char *bu, std::uint32_t stored_len, int last);
BOOST_BEAST_DECL void tr_tally_dist (std::uint16_t dist, std::uint8_t len, bool& flush);
BOOST_BEAST_DECL void tr_tally_lit (std::uint8_t c, bool& flush);
BOOST_BEAST_DECL void tr_flush_block (z_params& zs, char *buf, std::uint32_t stored_len, int last);
BOOST_BEAST_DECL void fill_window (z_params& zs);
BOOST_BEAST_DECL void flush_pending (z_params& zs);
BOOST_BEAST_DECL void flush_block (z_params& zs, bool last);
BOOST_BEAST_DECL int read_buf (z_params& zs, Byte *buf, unsigned size);
BOOST_BEAST_DECL uInt longest_match (IPos cur_match);
BOOST_BEAST_DECL block_state f_stored (z_params& zs, Flush flush);
BOOST_BEAST_DECL block_state f_fast (z_params& zs, Flush flush);
BOOST_BEAST_DECL block_state f_slow (z_params& zs, Flush flush);
BOOST_BEAST_DECL block_state f_rle (z_params& zs, Flush flush);
BOOST_BEAST_DECL block_state f_huff (z_params& zs, Flush flush);
block_state
deflate_stored(z_params& zs, Flush flush)
{
return f_stored(zs, flush);
}
block_state
deflate_fast(z_params& zs, Flush flush)
{
return f_fast(zs, flush);
}
block_state
deflate_slow(z_params& zs, Flush flush)
{
return f_slow(zs, flush);
}
block_state
deflate_rle(z_params& zs, Flush flush)
{
return f_rle(zs, flush);
}
block_state
deflate_huff(z_params& zs, Flush flush)
{
return f_huff(zs, flush);
}
};
//--------------------------------------------------------------------------
// Reverse the first len bits of a code
template<class Unsigned>
Unsigned
deflate_stream::
bi_reverse(Unsigned code, unsigned len)
{
BOOST_STATIC_ASSERT(std::is_unsigned<Unsigned>::value);
BOOST_ASSERT(len <= 8 * sizeof(unsigned));
Unsigned res = 0;
do
{
res |= code & 1;
code >>= 1;
res <<= 1;
}
while(--len > 0);
return res >> 1;
}
} // detail
} // zlib
} // beast
} // boost
#ifdef BOOST_BEAST_HEADER_ONLY
#include <boost/beast/zlib/detail/deflate_stream.ipp>
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,251 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// This is a derivative work based on Zlib, copyright below:
/*
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef BOOST_BEAST_ZLIB_DETAIL_INFLATE_STREAM_HPP
#define BOOST_BEAST_ZLIB_DETAIL_INFLATE_STREAM_HPP
#include <boost/beast/zlib/error.hpp>
#include <boost/beast/zlib/zlib.hpp>
#include <boost/beast/zlib/detail/bitstream.hpp>
#include <boost/beast/zlib/detail/ranges.hpp>
#include <boost/beast/zlib/detail/window.hpp>
#if 0
#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/throw_exception.hpp>
#include <algorithm>
#include <array>
#include <cstdint>
#include <cstring>
#include <stdexcept>
#endif
namespace boost {
namespace beast {
namespace zlib {
namespace detail {
class inflate_stream
{
protected:
inflate_stream()
{
w_.reset(15);
}
BOOST_BEAST_DECL
void
doClear();
BOOST_BEAST_DECL
void
doReset(int windowBits);
BOOST_BEAST_DECL
void
doWrite(z_params& zs, Flush flush, error_code& ec);
void
doReset()
{
doReset(w_.bits());
}
private:
enum Mode
{
HEAD, // i: waiting for magic header
FLAGS, // i: waiting for method and flags (gzip)
TIME, // i: waiting for modification time (gzip)
OS, // i: waiting for extra flags and operating system (gzip)
EXLEN, // i: waiting for extra length (gzip)
EXTRA, // i: waiting for extra bytes (gzip)
NAME, // i: waiting for end of file name (gzip)
COMMENT, // i: waiting for end of comment (gzip)
HCRC, // i: waiting for header crc (gzip)
TYPE, // i: waiting for type bits, including last-flag bit
TYPEDO, // i: same, but skip check to exit inflate on new block
STORED, // i: waiting for stored size (length and complement)
COPY_, // i/o: same as COPY below, but only first time in
COPY, // i/o: waiting for input or output to copy stored block
TABLE, // i: waiting for dynamic block table lengths
LENLENS, // i: waiting for code length code lengths
CODELENS, // i: waiting for length/lit and distance code lengths
LEN_, // i: same as LEN below, but only first time in
LEN, // i: waiting for length/lit/eob code
LENEXT, // i: waiting for length extra bits
DIST, // i: waiting for distance code
DISTEXT,// i: waiting for distance extra bits
MATCH, // o: waiting for output space to copy string
LIT, // o: waiting for output space to write literal
CHECK, // i: waiting for 32-bit check value
LENGTH, // i: waiting for 32-bit length (gzip)
DONE, // finished check, done -- remain here until reset
BAD, // got a data error -- remain here until reset
SYNC // looking for synchronization bytes to restart inflate()
};
/* Structure for decoding tables. Each entry provides either the
information needed to do the operation requested by the code that
indexed that table entry, or it provides a pointer to another
table that indexes more bits of the code. op indicates whether
the entry is a pointer to another table, a literal, a length or
distance, an end-of-block, or an invalid code. For a table
pointer, the low four bits of op is the number of index bits of
that table. For a length or distance, the low four bits of op
is the number of extra bits to get after the code. bits is
the number of bits in this code or part of the code to drop off
of the bit buffer. val is the actual byte to output in the case
of a literal, the base length or distance, or the offset from
the current table to the next table. Each entry is four bytes.
op values as set by inflate_table():
00000000 - literal
0000tttt - table link, tttt != 0 is the number of table index bits
0001eeee - length or distance, eeee is the number of extra bits
01100000 - end of block
01000000 - invalid code
*/
struct code
{
std::uint8_t op; // operation, extra bits, table bits
std::uint8_t bits; // bits in this part of the code
std::uint16_t val; // offset in table or code value
};
/* Maximum size of the dynamic table. The maximum number of code
structures is 1444, which is the sum of 852 for literal/length codes
and 592 for distance codes. These values were found by exhaustive
searches using the program examples/enough.c found in the zlib
distribtution. The arguments to that program are the number of
symbols, the initial root table size, and the maximum bit length
of a code. "enough 286 9 15" for literal/length codes returns
returns 852, and "enough 30 6 15" for distance codes returns 592.
The initial root table size (9 or 6) is found in the fifth argument
of the inflate_table() calls in inflate.c and infback.c. If the
root table size is changed, then these maximum sizes would be need
to be recalculated and updated.
*/
static std::uint16_t constexpr kEnoughLens = 852;
static std::uint16_t constexpr kEnoughDists = 592;
static std::uint16_t constexpr kEnough = kEnoughLens + kEnoughDists;
struct codes
{
code const* lencode;
code const* distcode;
unsigned lenbits; // VFALCO use std::uint8_t
unsigned distbits;
};
// Type of code to build for inflate_table()
enum class build
{
codes,
lens,
dists
};
BOOST_BEAST_DECL
static
void
inflate_table(
build type,
std::uint16_t* lens,
std::size_t codes,
code** table,
unsigned *bits,
std::uint16_t* work,
error_code& ec);
BOOST_BEAST_DECL
static
codes const&
get_fixed_tables();
BOOST_BEAST_DECL
void
fixedTables();
BOOST_BEAST_DECL
void
inflate_fast(ranges& r, error_code& ec);
bitstream bi_;
Mode mode_ = HEAD; // current inflate mode
int last_ = 0; // true if processing last block
unsigned dmax_ = 32768U; // zlib header max distance (INFLATE_STRICT)
// sliding window
window w_;
// for string and stored block copying
unsigned length_; // literal or length of data to copy
unsigned offset_; // distance back to copy string from
// for table and code decoding
unsigned extra_; // extra bits needed
// dynamic table building
unsigned ncode_; // number of code length code lengths
unsigned nlen_; // number of length code lengths
unsigned ndist_; // number of distance code lengths
unsigned have_; // number of code lengths in lens[]
unsigned short lens_[320]; // temporary storage for code lengths
unsigned short work_[288]; // work area for code table building
code codes_[kEnough]; // space for code tables
code *next_ = codes_; // next available space in codes[]
int back_ = -1; // bits back of last unprocessed length/lit
unsigned was_; // initial length of match
// fixed and dynamic code tables
code const* lencode_ = codes_ ; // starting table for length/literal codes
code const* distcode_ = codes_; // starting table for distance codes
unsigned lenbits_; // index bits for lencode
unsigned distbits_; // index bits for distcode
};
} // detail
} // zlib
} // beast
} // boost
#ifdef BOOST_BEAST_HEADER_ONLY
#include <boost/beast/zlib/detail/inflate_stream.ipp>
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,102 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// This is a derivative work based on Zlib, copyright below:
/*
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef BOOST_BEAST_ZLIB_DETAIL_RANGES_HPP
#define BOOST_BEAST_ZLIB_DETAIL_RANGES_HPP
#include <cstdint>
#include <type_traits>
namespace boost {
namespace beast {
namespace zlib {
namespace detail {
struct ranges
{
template<bool isConst>
struct range
{
using iter_t =
typename std::conditional<isConst,
std::uint8_t const*,
std::uint8_t*>::type;
iter_t first;
iter_t last;
iter_t next;
// total bytes in range
std::size_t
size() const
{
return last - first;
}
// bytes consumed
std::size_t
used() const
{
return next - first;
}
// bytes remaining
std::size_t
avail() const
{
return last - next;
}
};
range<true> in;
range<false> out;
};
// Clamp u to v where u and v are different types
template<class U, class V>
U clamp(U u, V v)
{
if(u > v)
u = static_cast<U>(v);
return u;
}
} // detail
} // zlib
} // beast
} // boost
#endif

View File

@@ -0,0 +1,151 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// This is a derivative work based on Zlib, copyright below:
/*
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef BOOST_BEAST_ZLIB_DETAIL_WINDOW_HPP
#define BOOST_BEAST_ZLIB_DETAIL_WINDOW_HPP
#include <boost/assert.hpp>
#include <boost/make_unique.hpp>
#include <cstdint>
#include <cstring>
#include <memory>
namespace boost {
namespace beast {
namespace zlib {
namespace detail {
class window
{
std::unique_ptr<std::uint8_t[]> p_;
std::uint16_t i_ = 0;
std::uint16_t size_ = 0;
std::uint16_t capacity_ = 0;
std::uint8_t bits_ = 0;
public:
int
bits() const
{
return bits_;
}
unsigned
capacity() const
{
return capacity_;
}
unsigned
size() const
{
return size_;
}
void
reset(int bits)
{
if(bits_ != bits)
{
p_.reset();
bits_ = static_cast<std::uint8_t>(bits);
capacity_ = 1U << bits_;
}
i_ = 0;
size_ = 0;
}
void
read(std::uint8_t* out, std::size_t pos, std::size_t n)
{
if(i_ >= size_)
{
// window is contiguous
std::memcpy(out, &p_[i_ - pos], n);
return;
}
auto i = ((i_ - pos) + capacity_) % capacity_;
auto m = capacity_ - i;
if(n <= m)
{
std::memcpy(out, &p_[i], n);
return;
}
std::memcpy(out, &p_[i], m);
out += m;
std::memcpy(out, &p_[0], n - m);
}
void
write(std::uint8_t const* in, std::size_t n)
{
if(! p_)
p_ = boost::make_unique<
std::uint8_t[]>(capacity_);
if(n >= capacity_)
{
i_ = 0;
size_ = capacity_;
std::memcpy(&p_[0], in + (n - size_), size_);
return;
}
if(i_ + n <= capacity_)
{
std::memcpy(&p_[i_], in, n);
if(size_ >= capacity_ - n)
size_ = capacity_;
else
size_ = static_cast<std::uint16_t>(size_ + n);
i_ = static_cast<std::uint16_t>(
(i_ + n) % capacity_);
return;
}
auto m = capacity_ - i_;
std::memcpy(&p_[i_], in, m);
in += m;
i_ = static_cast<std::uint16_t>(n - m);
std::memcpy(&p_[0], in, i_);
size_ = capacity_;
}
};
} // detail
} // zlib
} // beast
} // boost
#endif

View File

@@ -0,0 +1,141 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// This is a derivative work based on Zlib, copyright below:
/*
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef BOOST_BEAST_ZLIB_ERROR_HPP
#define BOOST_BEAST_ZLIB_ERROR_HPP
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/error.hpp>
namespace boost {
namespace beast {
namespace zlib {
/** Error codes returned by the deflate codecs.
*/
enum class error
{
/** Additional buffers are required.
This error indicates that one or both of the buffers
provided buffers do not have sufficient available bytes
to make forward progress.
This does not always indicate a failure condition.
@note This is the same as `Z_BUF_ERROR` returned by ZLib.
*/
need_buffers = 1,
/** End of stream reached.
@note This is the same as `Z_STREAM_END` returned by ZLib.
*/
end_of_stream,
/** Invalid stream or parameters.
This error is returned when invalid parameters are passed,
or the operation being performed is not consistent with the
state of the stream. For example, attempting to write data
when the end of stream is already reached.
@note This is the same as `Z_STREAM_ERROR` returned by ZLib.
*/
stream_error,
//
// Errors generated by basic_deflate_stream
//
//
// Errors generated by basic_inflate_stream
//
/// Invalid block type
invalid_block_type,
/// Invalid stored block length
invalid_stored_length,
/// Too many length or distance symbols
too_many_symbols,
/// Invalid code lengths
invalid_code_lenths,
/// Invalid bit length repeat
invalid_bit_length_repeat,
/// Missing end of block code
missing_eob,
/// Invalid literal/length code
invalid_literal_length,
/// Invalid distance code
invalid_distance_code,
/// Invalid distance too far back
invalid_distance,
//
// Errors generated by inflate_table
//
/// Over-subscribed length code
over_subscribed_length,
/// Incomplete length set
incomplete_length_set,
/// general error
general
};
} // zlib
} // beast
} // boost
#include <boost/beast/zlib/impl/error.hpp>
#ifdef BOOST_BEAST_HEADER_ONLY
#include <boost/beast/zlib/impl/error.ipp>
#endif
#endif

View File

@@ -0,0 +1,63 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// This is a derivative work based on Zlib, copyright below:
/*
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef BOOST_BEAST_ZLIB_IMPL_ERROR_HPP
#define BOOST_BEAST_ZLIB_IMPL_ERROR_HPP
namespace boost {
namespace system {
template<>
struct is_error_code_enum<::boost::beast::zlib::error>
{
static bool const value = true;
};
} // system
} // boost
namespace boost {
namespace beast {
namespace zlib {
BOOST_BEAST_DECL
error_code
make_error_code(error ev);
} // zlib
} // beast
} // boost
#endif

View File

@@ -0,0 +1,123 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// This is a derivative work based on Zlib, copyright below:
/*
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef BOOST_BEAST_ZLIB_IMPL_ERROR_IPP
#define BOOST_BEAST_ZLIB_IMPL_ERROR_IPP
#include <boost/beast/zlib/error.hpp>
#include <type_traits>
namespace boost {
namespace beast {
namespace zlib {
namespace detail {
class error_codes : public error_category
{
public:
const char*
name() const noexcept override
{
return "boost.beast.zlib";
}
std::string
message(int ev) const override
{
switch(static_cast<error>(ev))
{
case error::need_buffers: return "need buffers";
case error::end_of_stream: return "unexpected end of deflate stream";
case error::stream_error: return "stream error";
case error::invalid_block_type: return "invalid block type";
case error::invalid_stored_length: return "invalid stored block length";
case error::too_many_symbols: return "too many symbols";
case error::invalid_code_lenths: return "invalid code lengths";
case error::invalid_bit_length_repeat: return "invalid bit length repeat";
case error::missing_eob: return "missing end of block code";
case error::invalid_literal_length: return "invalid literal/length code";
case error::invalid_distance_code: return "invalid distance code";
case error::invalid_distance: return "invalid distance";
case error::over_subscribed_length: return "over-subscribed length";
case error::incomplete_length_set: return "incomplete length set";
case error::general:
default:
return "beast.zlib error";
}
}
error_condition
default_error_condition(int ev) const noexcept override
{
return error_condition{ev, *this};
}
bool
equivalent(int ev,
error_condition const& condition
) const noexcept override
{
return condition.value() == ev &&
&condition.category() == this;
}
bool
equivalent(error_code const& error, int ev) const noexcept override
{
return error.value() == ev &&
&error.category() == this;
}
};
} // detail
error_code
make_error_code(error ev)
{
static detail::error_codes const cat{};
return error_code{static_cast<
std::underlying_type<error>::type>(ev), cat};
}
} // zlib
} // beast
} // boost
#endif

View File

@@ -0,0 +1,219 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// This is a derivative work based on Zlib, copyright below:
/*
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef BOOST_BEAST_ZLIB_INFLATE_STREAM_HPP
#define BOOST_BEAST_ZLIB_INFLATE_STREAM_HPP
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/zlib/detail/inflate_stream.hpp>
namespace boost {
namespace beast {
namespace zlib {
/** Raw deflate stream decompressor.
This implements a raw deflate stream decompressor. The deflate
protocol is a compression protocol described in
"DEFLATE Compressed Data Format Specification version 1.3"
located here: https://tools.ietf.org/html/rfc1951
The implementation is a refactored port to C++ of ZLib's "inflate".
A more detailed description of ZLib is at http://zlib.net/.
Compression can be done in a single step if the buffers are large
enough (for example if an input file is memory mapped), or can be done
by repeated calls of the compression function. In the latter case, the
application must provide more input and/or consume the output (providing
more output space) before each call.
*/
class inflate_stream
: private detail::inflate_stream
{
public:
/** Construct a raw deflate decompression stream.
The window size is set to the default of 15 bits.
*/
inflate_stream() = default;
/** Reset the stream.
This puts the stream in a newly constructed state with
the previously specified window size, but without de-allocating
any dynamically created structures.
*/
void
reset()
{
doReset();
}
/** Reset the stream.
This puts the stream in a newly constructed state with the
specified window size, but without de-allocating any dynamically
created structures.
*/
void
reset(int windowBits)
{
doReset(windowBits);
}
/** Put the stream in a newly constructed state.
All dynamically allocated memory is de-allocated.
*/
void
clear()
{
doClear();
}
/** Decompress input and produce output.
This function decompresses as much data as possible, and stops when
the input buffer becomes empty or the output buffer becomes full. It
may introduce some output latency (reading input without producing any
output) except when forced to flush.
One or both of the following actions are performed:
@li Decompress more input starting at `zs.next_in` and update `zs.next_in`
and `zs.avail_in` accordingly. If not all input can be processed (because
there is not enough room in the output buffer), `zs.next_in` is updated
and processing will resume at this point for the next call.
@li Provide more output starting at `zs.next_out` and update `zs.next_out`
and `zs.avail_out` accordingly. `write` provides as much output as
possible, until there is no more input data or no more space in the output
buffer (see below about the flush parameter).
Before the call, the application should ensure that at least one of the
actions is possible, by providing more input and/or consuming more output,
and updating the values in `zs` accordingly. The application can consume
the uncompressed output when it wants, for example when the output buffer
is full (`zs.avail_out == 0`), or after each call. If `write` returns no
error and with zero `zs.avail_out`, it must be called again after making
room in the output buffer because there might be more output pending.
The flush parameter may be `Flush::none`, `Flush::sync`, `Flush::finish`,
`Flush::block`, or `Flush::trees`. `Flush::sync` requests to flush as much
output as possible to the output buffer. `Flush::block` requests to stop if
and when it gets to the next deflate block boundary. When decoding the
zlib or gzip format, this will cause `write` to return immediately after
the header and before the first block. When doing a raw inflate, `write` will
go ahead and process the first block, and will return when it gets to the
end of that block, or when it runs out of data.
The `Flush::block` option assists in appending to or combining deflate
streams. Also to assist in this, on return `write` will set `zs.data_type`
to the number of unused bits in the last byte taken from `zs.next_in`, plus
64 if `write` is currently decoding the last block in the deflate stream,
plus 128 if `write` returned immediately after decoding an end-of-block code
or decoding the complete header up to just before the first byte of the
deflate stream. The end-of-block will not be indicated until all of the
uncompressed data from that block has been written to `zs.next_out`. The
number of unused bits may in general be greater than seven, except when
bit 7 of `zs.data_type` is set, in which case the number of unused bits
will be less than eight. `zs.data_type` is set as noted here every time
`write` returns for all flush options, and so can be used to determine the
amount of currently consumed input in bits.
The `Flush::trees` option behaves as `Flush::block` does, but it also returns
when the end of each deflate block header is reached, before any actual data
in that block is decoded. This allows the caller to determine the length of
the deflate block header for later use in random access within a deflate block.
256 is added to the value of `zs.data_type` when `write` returns immediately
after reaching the end of the deflate block header.
`write` should normally be called until it returns `error::end_of_stream` or
another error. However if all decompression is to be performed in a single
step (a single call of `write`), the parameter flush should be set to
`Flush::finish`. In this case all pending input is processed and all pending
output is flushed; `zs.avail_out` must be large enough to hold all of the
uncompressed data for the operation to complete. (The size of the uncompressed
data may have been saved by the compressor for this purpose.) The use of
`Flush::finish` is not required to perform an inflation in one step. However
it may be used to inform inflate that a faster approach can be used for the
single call. `Flush::finish` also informs inflate to not maintain a sliding
window if the stream completes, which reduces inflate's memory footprint.
If the stream does not complete, either because not all of the stream is
provided or not enough output space is provided, then a sliding window will be
allocated and `write` can be called again to continue the operation as if
`Flush::none` had been used.
In this implementation, `write` always flushes as much output as possible to
the output buffer, and always uses the faster approach on the first call. So
the effects of the flush parameter in this implementation are on the return value
of `write` as noted below, when `write` returns early when `Flush::block` or
`Flush::trees` is used, and when `write` avoids the allocation of memory for a
sliding window when `Flush::finsih` is used.
If a preset dictionary is needed after this call,
`write` sets `zs.adler` to the Adler-32 checksum of the dictionary chosen by
the compressor and returns `error::need_dictionary`; otherwise it sets
`zs.adler` to the Adler-32 checksum of all output produced so far (that is,
`zs.total_out bytes`) and returns no error, `error::end_of_stream`, or an
error code as described below. At the end of the stream, `write` checks that
its computed adler32 checksum is equal to that saved by the compressor and
returns `error::end_of_stream` only if the checksum is correct.
This function returns no error if some progress has been made (more input
processed or more output produced), `error::end_of_stream` if the end of the
compressed data has been reached and all uncompressed output has been produced,
`error::need_dictionary` if a preset dictionary is needed at this point,
`error::invalid_data` if the input data was corrupted (input stream not
conforming to the zlib format or incorrect check value), `error::stream_error`
if the stream structure was inconsistent (for example if `zs.next_in` or
`zs.next_out` was null), `error::need_buffers` if no progress is possible or
if there was not enough room in the output buffer when `Flush::finish` is
used. Note that `error::need_buffers` is not fatal, and `write` can be called
again with more input and more output space to continue decompressing.
*/
void
write(z_params& zs, Flush flush, error_code& ec)
{
doWrite(zs, flush, ec);
}
};
} // zlib
} // beast
} // boost
#endif

View File

@@ -0,0 +1,183 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
// This is a derivative work based on Zlib, copyright below:
/*
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef BOOST_BEAST_ZLIB_ZLIB_HPP
#define BOOST_BEAST_ZLIB_ZLIB_HPP
#include <boost/beast/core/detail/config.hpp>
#include <cstdint>
#include <cstdlib>
namespace boost {
namespace beast {
namespace zlib {
#if !defined(__MACTYPES__)
using Byte = unsigned char; // 8 bits
#endif
using uInt = unsigned int; // 16 bits or more
/* Possible values of the data_type field (though see inflate()) */
enum kind
{
binary = 0,
text = 1,
unknown = 2
};
/** Deflate codec parameters.
Objects of this type are filled in by callers and provided to the
deflate codec to define the input and output areas for the next
compress or decompress operation.
The application must update next_in and avail_in when avail_in has dropped
to zero. It must update next_out and avail_out when avail_out has dropped
to zero. The application must initialize zalloc, zfree and opaque before
calling the init function. All other fields are set by the compression
library and must not be updated by the application.
The fields total_in and total_out can be used for statistics or progress
reports. After compression, total_in holds the total size of the
uncompressed data and may be saved for use in the decompressor (particularly
if the decompressor wants to decompress everything in a single step).
*/
struct z_params
{
/** A pointer to the next input byte.
If there is no more input, this may be set to `nullptr`.
*/
void const* next_in;
/** The number of bytes of input available at `next_in`.
If there is no more input, this should be set to zero.
*/
std::size_t avail_in;
/** The total number of input bytes read so far.
*/
std::size_t total_in = 0;
/** A pointer to the next output byte.
*/
void* next_out;
/** The remaining bytes of space at `next_out`.
*/
std::size_t avail_out;
/** The total number of bytes output so far.
*/
std::size_t total_out = 0;
int data_type = unknown; // best guess about the data type: binary or text
};
/** Flush option.
*/
enum class Flush
{
// order matters
none,
block,
partial,
sync,
full,
finish,
trees
};
/* compression levels */
enum compression
{
none = 0,
best_speed = 1,
best_size = 9,
default_size = -1
};
/** Compression strategy.
These are used when compressing streams.
*/
enum class Strategy
{
/** Default strategy.
This is suitable for general purpose compression, and works
well in the majority of cases.
*/
normal,
/** Filtered strategy.
This strategy should be used when the data be compressed
is produced by a filter or predictor.
*/
filtered,
/** Huffman-only strategy.
This strategy only performs Huffman encoding, without doing
any string matching.
*/
huffman,
/** Run Length Encoding strategy.
This strategy limits match distances to one, making it
equivalent to run length encoding. This can give better
performance for things like PNG image data.
*/
rle,
/** Fixed table strategy.
This strategy prevents the use of dynamic Huffman codes,
allowing for a simpler decoder for special applications.
*/
fixed
};
} // zlib
} // beast
} // boost
#endif