1#ifndef MSTL_COMPRESS_ZLIB_COMPRESS_HPP__
2#define MSTL_COMPRESS_ZLIB_COMPRESS_HPP__
3#ifdef MSTL_SUPPORT_ZLIB__
4#include "MSTL/core/container/vector.hpp"
5#include "MSTL/core/memory/memory_view.hpp"
6#include "MSTL/core/string/string.hpp"
13enum class COMPRESS_LEVEL {
14 none = Z_NO_COMPRESSION,
15 best_speed = Z_BEST_SPEED,
16 default_level = Z_DEFAULT_COMPRESSION,
17 best_compression = Z_BEST_COMPRESSION
20enum class COMPRESS_STRATEGY {
21 default_strategy = Z_DEFAULT_STRATEGY,
22 filtered = Z_FILTERED,
23 huffman_only = Z_HUFFMAN_ONLY,
29class MSTL_API zlib_compressor {
31 MSTL_NODISCARD
static bvector compress_data(
33 COMPRESS_LEVEL level, COMPRESS_STRATEGY strategy);
35 MSTL_NODISCARD
static bvector decompress_data(
37 size_t estimated_original_size);
39 static void check_zlib_error(
int ret_code);
42 template <
typename Iter, enable_if_t<is_ranges_cot_iter_v<Iter>,
int> = 0>
43 MSTL_NODISCARD
static bvector compress(Iter
begin, Iter
end,
44 const COMPRESS_LEVEL level = COMPRESS_LEVEL::default_level,
45 const COMPRESS_STRATEGY strategy = COMPRESS_STRATEGY::default_strategy) {
47 static_assert(
sizeof(*begin) == 1,
"Iterator must point to byte-sized elements");
51 return compress_data(
data, data_size, level, strategy);
54 MSTL_NODISCARD
static bvector compress(
const string_view
data,
55 const COMPRESS_LEVEL level = COMPRESS_LEVEL::default_level,
56 const COMPRESS_STRATEGY strategy = COMPRESS_STRATEGY::default_strategy) {
67 MSTL_NODISCARD
static bvector compress(
68 const vector<T>&
data,
69 const COMPRESS_LEVEL level = COMPRESS_LEVEL::default_level,
70 const COMPRESS_STRATEGY strategy = COMPRESS_STRATEGY::default_strategy) {
72 static_assert(
sizeof(T) == 1,
"Vector must contain byte-sized elements");
76 data.size() *
sizeof(T),
82 template <
typename Iter, enable_if_t<is_ranges_cot_iter_v<Iter>,
int> = 0>
83 MSTL_NODISCARD
static bvector decompress(Iter
begin, Iter
end,
84 const size_t estimated_original_size = 0) {
86 static_assert(
sizeof(*begin) == 1,
"Iterator must point to byte-sized elements");
91 return decompress_data(
data, data_size, estimated_original_size);
94 MSTL_NODISCARD
static bvector decompress(
95 const span<const byte_t>&
data,
96 const size_t estimated_original_size = 0) {
98 return decompress_data(
data.data(),
data.size(), estimated_original_size);
101 class MSTL_API stream_compressor {
103 explicit stream_compressor(
104 COMPRESS_LEVEL level = COMPRESS_LEVEL::default_level,
105 COMPRESS_STRATEGY strategy = COMPRESS_STRATEGY::default_strategy);
107 ~stream_compressor();
109 stream_compressor(
const stream_compressor&) =
delete;
110 stream_compressor& operator =(
const stream_compressor&) =
delete;
111 stream_compressor(stream_compressor&& other)
noexcept;
112 stream_compressor& operator =(stream_compressor&& other)
noexcept;
114 bvector compress(
const span<const byte_t>&
data,
bool finish =
false);
115 bvector compress(string_view
data,
bool finish =
false);
119 void reset(COMPRESS_LEVEL level = COMPRESS_LEVEL::default_level,
120 COMPRESS_STRATEGY strategy = COMPRESS_STRATEGY::default_strategy);
122 MSTL_NODISCARD
size_t bytes_input() const noexcept {
return bytes_input_; }
123 MSTL_NODISCARD
size_t bytes_output() const noexcept {
return bytes_output_; }
124 MSTL_NODISCARD
double compression_ratio() const noexcept {
125 return bytes_input_ > 0 ?
static_cast<double>(bytes_output_) / bytes_input_ : 0.0;
129 ::z_stream stream_{};
130 bool initialized_ =
false;
131 size_t bytes_input_ = 0;
132 size_t bytes_output_ = 0;
135 class MSTL_API stream_decompressor {
137 stream_decompressor();
138 ~stream_decompressor();
140 stream_decompressor(
const stream_decompressor&) =
delete;
141 stream_decompressor& operator =(
const stream_decompressor&) =
delete;
143 stream_decompressor(stream_decompressor&& other)
noexcept;
144 stream_decompressor& operator =(stream_decompressor&& other)
noexcept;
146 bvector decompress(
const span<const byte_t>&
data,
bool finish =
false);
152 MSTL_NODISCARD
size_t bytes_input() const noexcept {
return bytes_input_; }
153 MSTL_NODISCARD
size_t bytes_output() const noexcept {
return bytes_output_; }
154 MSTL_NODISCARD
double expansion_ratio() const noexcept {
155 return bytes_input_ > 0 ?
static_cast<double>(bytes_output_) / bytes_input_ : 0.0;
159 ::z_stream stream_{};
160 bool initialized_ =
false;
161 size_t bytes_input_ = 0;
162 size_t bytes_output_ = 0;
166using compressor = zlib_compressor::stream_compressor;
167using decompressor = zlib_compressor::stream_decompressor;
unsigned char byte_t
字节类型,定义为无符号字符
#define MSTL_ERROR_BUILD_FINAL_CLASS(THIS, BASE, INFO)
构建最终异常类宏
constexpr iter_difference_t< Iterator > distance(Iterator first, Iterator last)
计算两个迭代器之间的距离
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
MSTL_INLINE17 constexpr none_t none
默认空表示
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) begin(Container &cont) noexcept(noexcept(cont.begin()))
获取容器的起始迭代器