MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
zlib_compress.hpp
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"
7#include <zlib.h>
9
10MSTL_ERROR_BUILD_FINAL_CLASS(zlib_exception, system_exception, "Zlib Operation Failed.")
11
12
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
18};
19
20enum class COMPRESS_STRATEGY {
21 default_strategy = Z_DEFAULT_STRATEGY,
22 filtered = Z_FILTERED,
23 huffman_only = Z_HUFFMAN_ONLY,
24 rle = Z_RLE,
25 fixed = Z_FIXED
26};
27
28
29class MSTL_API zlib_compressor {
30private:
31 MSTL_NODISCARD static bvector compress_data(
32 const byte_t* data, size_t size,
33 COMPRESS_LEVEL level, COMPRESS_STRATEGY strategy);
34
35 MSTL_NODISCARD static bvector decompress_data(
36 const byte_t* data, size_t size,
37 size_t estimated_original_size);
38
39 static void check_zlib_error(int ret_code);
40
41public:
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) {
46
47 static_assert(sizeof(*begin) == 1, "Iterator must point to byte-sized elements");
48
49 const auto* data = reinterpret_cast<const byte_t*>(&*begin);
50 const size_t data_size = _MSTL distance(begin, end);
51 return compress_data(data, data_size, level, strategy);
52 }
53
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) {
57
58 return compress_data(
59 reinterpret_cast<const byte_t*>(data.data()),
60 data.size(),
61 level,
62 strategy
63 );
64 }
65
66 template <typename T>
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) {
71
72 static_assert(sizeof(T) == 1, "Vector must contain byte-sized elements");
73
74 return compress_data(
75 reinterpret_cast<const byte_t*>(data.data()),
76 data.size() * sizeof(T),
77 level,
78 strategy
79 );
80 }
81
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) {
85
86 static_assert(sizeof(*begin) == 1, "Iterator must point to byte-sized elements");
87
88 const auto* data = reinterpret_cast<const byte_t*>(&*begin);
89 const size_t data_size = distance(begin, end);
90
91 return decompress_data(data, data_size, estimated_original_size);
92 }
93
94 MSTL_NODISCARD static bvector decompress(
95 const span<const byte_t>& data,
96 const size_t estimated_original_size = 0) {
97
98 return decompress_data(data.data(), data.size(), estimated_original_size);
99 }
100
101 class MSTL_API stream_compressor {
102 public:
103 explicit stream_compressor(
104 COMPRESS_LEVEL level = COMPRESS_LEVEL::default_level,
105 COMPRESS_STRATEGY strategy = COMPRESS_STRATEGY::default_strategy);
106
107 ~stream_compressor();
108
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;
113
114 bvector compress(const span<const byte_t>& data, bool finish = false);
115 bvector compress(string_view data, bool finish = false);
116
117 bvector finish();
118
119 void reset(COMPRESS_LEVEL level = COMPRESS_LEVEL::default_level,
120 COMPRESS_STRATEGY strategy = COMPRESS_STRATEGY::default_strategy);
121
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;
126 }
127
128 private:
129 ::z_stream stream_{};
130 bool initialized_ = false;
131 size_t bytes_input_ = 0;
132 size_t bytes_output_ = 0;
133 };
134
135 class MSTL_API stream_decompressor {
136 public:
137 stream_decompressor();
138 ~stream_decompressor();
139
140 stream_decompressor(const stream_decompressor&) = delete;
141 stream_decompressor& operator =(const stream_decompressor&) = delete;
142
143 stream_decompressor(stream_decompressor&& other) noexcept;
144 stream_decompressor& operator =(stream_decompressor&& other) noexcept;
145
146 bvector decompress(const span<const byte_t>& data, bool finish = false);
147
148 bvector finish();
149
150 void reset();
151
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;
156 }
157
158 private:
159 ::z_stream stream_{};
160 bool initialized_ = false;
161 size_t bytes_input_ = 0;
162 size_t bytes_output_ = 0;
163 };
164};
165
166using compressor = zlib_compressor::stream_compressor;
167using decompressor = zlib_compressor::stream_decompressor;
168
170#endif
171#endif // MSTL_COMPRESS_ZLIB_COMPRESS_HPP__
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()))
获取容器的起始迭代器
系统访问异常