34#ifndef QB_IO_COMPRESSION_H
35#define QB_IO_COMPRESSION_H
37#ifndef QB_IO_WITH_ZLIB
38#error "missing Z Library"
45namespace compression {
111 virtual std::size_t
compress(
const uint8_t *input, std::size_t input_size,
112 uint8_t *output, std::size_t output_size,
159 virtual std::size_t
decompress(
const uint8_t *input, std::size_t input_size,
160 uint8_t *output, std::size_t output_size,
162 std::size_t &input_bytes_processed,
bool &done) = 0;
271constexpr const char *
const GZIP =
"gzip";
276constexpr const char *
const DEFLATE =
"deflate";
338 int strategy,
int memLevel);
349std::unique_ptr<compress_provider>
363 std::function<std::unique_ptr<compress_provider>()> make_compressor);
374 const std::string &
algorithm, uint16_t weight,
375 std::function<std::unique_ptr<decompress_provider>()> make_decompressor);
393template <
typename Output>
395compress(Output &output,
const char *data, std::size_t size,
int level,
399 if (size > std::numeric_limits<unsigned int>::max()) {
400 throw std::runtime_error(
"size arg is too large to fit into unsigned int type");
405 deflate_s.zalloc = Z_NULL;
406 deflate_s.zfree = Z_NULL;
407 deflate_s.opaque = Z_NULL;
408 deflate_s.avail_in = 0;
409 deflate_s.next_in = Z_NULL;
419 constexpr int mem_level = 8;
426 DISABLE_WARNING_OLD_STYLE_CAST
427 if (deflateInit2(&deflate_s, level, Z_DEFLATED, window_bits, mem_level,
428 Z_DEFAULT_STRATEGY) != Z_OK) {
429 throw std::runtime_error(
"deflate init failed");
433 deflate_s.next_in =
const_cast<Bytef *
>(
reinterpret_cast<const Bytef *
>(data));
434 deflate_s.avail_in =
static_cast<unsigned int>(size);
436 std::size_t size_compressed = 0;
438 size_t increase = size / 2 + 1024;
439 if (output.size() < (size_compressed + increase)) {
440 output.resize(size_compressed + increase);
444 deflate_s.avail_out =
static_cast<unsigned int>(increase);
445 deflate_s.next_out =
reinterpret_cast<Bytef *
>((&output[0] + size_compressed));
450 ::deflate(&deflate_s, Z_FINISH);
451 size_compressed += (increase - deflate_s.avail_out);
452 }
while (deflate_s.avail_out == 0);
454 deflateEnd(&deflate_s);
455 output.resize(size_compressed);
456 return size_compressed;
471 int level,
int window_bits);
490template <
typename Output>
492uncompress(Output &output,
const char *data, std::size_t size, std::size_t max,
496 inflate_s.zalloc = Z_NULL;
497 inflate_s.zfree = Z_NULL;
498 inflate_s.opaque = Z_NULL;
499 inflate_s.avail_in = 0;
500 inflate_s.next_in = Z_NULL;
512 DISABLE_WARNING_OLD_STYLE_CAST
513 if (inflateInit2(&inflate_s, window_bits) != Z_OK) {
514 throw std::runtime_error(
"inflate init failed");
517 inflate_s.next_in =
const_cast<Bytef *
>(
reinterpret_cast<const Bytef *
>(data));
522 std::uint64_t size_64 = size * 2;
523 if (size_64 > std::numeric_limits<unsigned int>::max()) {
524 inflateEnd(&inflate_s);
525 throw std::runtime_error(
526 "size arg is too large to fit into unsigned int type x2");
529 if (max && (size > max || (size * 2) > max)) {
530 inflateEnd(&inflate_s);
531 throw std::runtime_error(
532 "size may use more memory than intended when decompressing");
534 inflate_s.avail_in =
static_cast<unsigned int>(size);
535 std::size_t size_uncompressed = 0;
537 std::size_t resize_to = size_uncompressed + 2 * size;
538 if (max && resize_to > max) {
539 inflateEnd(&inflate_s);
540 throw std::runtime_error(
"size of output string will use more memory then "
541 "intended when decompressing");
543 output.resize(resize_to);
544 inflate_s.avail_out =
static_cast<unsigned int>(2 * size);
545 inflate_s.next_out =
reinterpret_cast<Bytef *
>(&output[0] + size_uncompressed);
546 int ret = inflate(&inflate_s, Z_FINISH);
547 if (ret != Z_STREAM_END && ret != Z_OK && ret != Z_BUF_ERROR) {
548 std::string error_msg = inflate_s.msg;
549 inflateEnd(&inflate_s);
550 throw std::runtime_error(error_msg);
553 size_uncompressed += (2 * size - inflate_s.avail_out);
554 }
while (inflate_s.avail_out == 0);
555 inflateEnd(&inflate_s);
556 output.resize(size_uncompressed);
557 return size_uncompressed;
572 std::size_t max,
int window_bits);
594template <
typename Output>
596compress(Output &output,
const char *data, std::size_t size,
597 int level = Z_DEFAULT_COMPRESSION) {
598 constexpr int window_bits = 15;
638template <
typename Output>
653std::string
compress(
const char *data, std::size_t size,
654 int level = Z_DEFAULT_COMPRESSION);
666template <
typename Output>
668uncompress(Output &output,
const char *data, std::size_t size, std::size_t max = 0) {
669 constexpr int window_bits = 0;
710template <
typename Output>
750 (
static_cast<uint8_t
>(data[0]) == 0x78 &&
751 (
static_cast<uint8_t
>(data[1]) == 0x9C ||
752 static_cast<uint8_t
>(data[1]) == 0x01 ||
753 static_cast<uint8_t
>(data[1]) == 0xDA ||
754 static_cast<uint8_t
>(data[1]) == 0x5E)) ||
756 (
static_cast<uint8_t
>(data[0]) == 0x1F &&
757 static_cast<uint8_t
>(data[1]) == 0x8B));
770template <
typename Output>
772compress(Output &output,
const char *data, std::size_t size,
773 int level = Z_DEFAULT_COMPRESSION) {
774 constexpr int window_bits = 15 + 16;
814template <
typename Output>
829std::string
compress(
const char *data, std::size_t size,
830 int level = Z_DEFAULT_COMPRESSION);
842template <
typename Output>
844uncompress(Output &output,
const char *data, std::size_t size, std::size_t max = 0) {
845 constexpr int window_bits = 15 + 32;
886template <
typename Output>
906namespace qb::allocator {
967using namespace qb::compression::gzip;
978using namespace qb::compression::deflate;
Extensible buffer optimized for performance.
Definition pipe.h:552
Factory interface for creating compression providers.
Definition compression.h:187
virtual std::unique_ptr< compress_provider > make_compressor() const =0
Create a new compressor instance.
virtual const std::string & algorithm() const =0
Get the name of the compression algorithm.
virtual ~compress_factory()=default
Virtual destructor.
Abstract interface for compression algorithm providers.
Definition compression.h:91
virtual ~compress_provider()=default
Virtual destructor.
virtual std::size_t compress(const uint8_t *input, std::size_t input_size, uint8_t *output, std::size_t output_size, operation_hint hint, std::size_t &input_bytes_processed, bool &done)=0
Compress a block of data.
virtual const std::string & algorithm() const =0
Get the name of the compression algorithm.
virtual void reset()=0
Reset the compressor to its initial state.
Factory interface for creating decompression providers.
Definition compression.h:216
virtual ~decompress_factory()=default
Virtual destructor.
virtual uint16_t weight() const =0
Get the weight of this decompression algorithm.
virtual std::unique_ptr< decompress_provider > make_decompressor() const =0
Create a new decompressor instance.
virtual const std::string & algorithm() const =0
Get the name of the decompression algorithm.
Abstract interface for decompression algorithm providers.
Definition compression.h:139
virtual ~decompress_provider()=default
Virtual destructor.
virtual const std::string & algorithm() const =0
Get the name of the decompression algorithm.
virtual void reset()=0
Reset the decompressor to its initial state.
virtual std::size_t decompress(const uint8_t *input, std::size_t input_size, uint8_t *output, std::size_t output_size, operation_hint hint, std::size_t &input_bytes_processed, bool &done)=0
Decompress a block of data.
std::unique_ptr< compress_provider > make_compressor(const std::string &algorithm)
Create a compressor for the specified algorithm.
std::shared_ptr< decompress_factory > make_decompress_factory(const std::string &algorithm, uint16_t weight, std::function< std::unique_ptr< decompress_provider >()> make_decompressor)
Create a custom decompression factory.
size_t compress(Output &output, const char *data, std::size_t size, int level=Z_DEFAULT_COMPRESSION)
Compress data using deflate algorithm with a generic output container.
Definition compression.h:596
std::size_t uncompress(Output &output, const char *data, std::size_t size, std::size_t max, int window_bits)
Uncompress data using a generic output container.
Definition compression.h:492
std::unique_ptr< compress_provider > make_gzip_compressor(int compressionLevel, int method, int strategy, int memLevel)
Create a gzip compressor with custom parameters.
std::unique_ptr< decompress_provider > make_decompressor(const std::string &algorithm)
Create a decompressor for the specified algorithm.
std::shared_ptr< compress_factory > make_compress_factory(const std::string &algorithm, std::function< std::unique_ptr< compress_provider >()> make_compressor)
Create a custom compression factory.
constexpr const char *const DEFLATE
Identifier for the deflate compression algorithm.
Definition compression.h:276
std::size_t uncompress(Output &output, const char *data, std::size_t size, std::size_t max=0)
Uncompress data using deflate algorithm with a generic output container.
Definition compression.h:668
size_t compress(Output &output, const char *data, std::size_t size, int level, int window_bits)
Compress data using a generic output container.
Definition compression.h:395
std::shared_ptr< compress_factory > get_compress_factory(const std::string &algorithm)
Get a specific compression factory by algorithm name.
bool supported(const std::string &algorithm)
Check if a specific compression algorithm is supported.
std::unique_ptr< compress_provider > make_deflate_compressor(int compressionLevel, int method, int strategy, int memLevel)
Create a deflate compressor with custom parameters.
size_t compress(Output &output, const char *data, std::size_t size, int level=Z_DEFAULT_COMPRESSION)
Compress data using gzip algorithm with a generic output container.
Definition compression.h:772
bool supported()
Check if compression support is available.
constexpr const char *const GZIP
Identifier for the gzip compression algorithm.
Definition compression.h:271
const std::vector< std::shared_ptr< decompress_factory > > get_decompress_factories()
Get all available decompression factories.
const std::vector< std::shared_ptr< compress_factory > > get_compress_factories()
Get all available compression factories.
std::size_t uncompress(Output &output, const char *data, std::size_t size, std::size_t max=0)
Uncompress data using gzip algorithm with a generic output container.
Definition compression.h:844
std::shared_ptr< decompress_factory > get_decompress_factory(const std::string &algorithm)
Get a specific decompression factory by algorithm name.
@ is_last
Used for the expected last compress() call, or for an expected single decompress() call.
Definition compression.h:57
@ has_more
Used when further compress() calls will be made, or when multiple decompress() calls may be required.
Definition compression.h:59
bool is_compressed(const char *data, std::size_t size)
Check if data is compressed using gzip or zlib format.
Definition compression.h:747
operation_hint
Hints for compression/decompression operations.
Definition compression.h:56
Namespace containing algorithm constants and utilities.
Namespace containing built-in compression implementations.
Namespace containing deflate compression utilities.
Namespace containing gzip compression utilities.
Namespace alias for deflate compression utilities.
Namespace alias for gzip compression utilities.
Structure for passing compression parameters for deflate.
Definition compression.h:623
size_t size_compressed
[out] Size of the compressed data
Definition compression.h:627
const char * data
Pointer to the data to compress.
Definition compression.h:624
int level
Compression level.
Definition compression.h:626
std::size_t size
Size of the data in bytes.
Definition compression.h:625
Structure for passing decompression parameters for deflate.
Definition compression.h:695
std::size_t size
Size of the compressed data in bytes.
Definition compression.h:697
std::size_t size_uncompressed
[out] Size of the uncompressed data
Definition compression.h:699
std::size_t max
Maximum allowed output size (0 for unlimited)
Definition compression.h:698
const char * data
Pointer to the compressed data.
Definition compression.h:696
Structure for passing gzip compression parameters.
Definition compression.h:799
int level
Compression level.
Definition compression.h:802
const char * data
Pointer to the data to compress.
Definition compression.h:800
std::size_t size
Size of the data in bytes.
Definition compression.h:801
size_t size_compressed
[out] Size of the compressed data
Definition compression.h:803
Structure for passing gzip decompression parameters.
Definition compression.h:871
const char * data
Pointer to the compressed data.
Definition compression.h:872
std::size_t max
Maximum allowed output size (0 for unlimited)
Definition compression.h:874
std::size_t size_uncompressed
[out] Size of the uncompressed data
Definition compression.h:875
std::size_t size
Size of the compressed data in bytes.
Definition compression.h:873
Result of a compression/decompression operation.
Definition compression.h:72
std::size_t output_bytes_produced
Number of bytes written to the output buffer.
Definition compression.h:76
std::size_t input_bytes_processed
Number of bytes processed from the input buffer.
Definition compression.h:74
bool done
For compress, set when 'last' is true and there was enough space to complete compression; for decompr...
Definition compression.h:77
Implementation of a dynamic extensible buffer.