acl  3.5.3.0
zlib_stream.hpp
浏览该文件的文档.
1 #pragma once
2 #include "../acl_cpp_define.hpp"
3 #include "pipe_stream.hpp"
4 
5 typedef struct z_stream_s z_stream;
6 
7 namespace acl {
8 
9 /**
10  * 压缩级别类型定义,该集合定义了压缩速度及压缩比的一个可选方式
11  * 所选的压缩值越高,则压缩比会更大,但压缩速度会越低
12  */
13 typedef enum
14 {
15  zlib_default = -1, // 缺省的压缩比
16  zlib_level0 = 0, // 最低的压缩比,其实就是不压缩
17  zlib_best_speed = 1, // 压缩速度最快的压缩比
26  zlib_best_compress = 9, // 最高的压缩比,最低的压缩速度
28 } zlib_level_t;
29 
30 /**
31  * 压缩过程中的压缩窗口参数类型,值越大则压缩效果越好且占用内存越多,
32  * 针对 HTTP 压缩传输,需要设置这些值的负值:-zlib_wbits_t
33  */
34 enum
35 {
44 };
45 
46 /**
47  * 压缩过程中的内存分配策略,值越大使用内存越多
48  */
49 typedef enum
50 {
61 
62 /**
63  * 压缩或解压过程中的缓存模式,即在压缩或解压过程中是否立刻刷新
64  * 到缓冲区为了获得比较高的压缩比,应该选择 zlib_flush_off 方式
65  */
66 typedef enum
67 {
68  zlib_flush_off = 0, // 不立即刷新至用户缓存
69  zlib_flush_partial = 1, // 刷新部分至用户缓存
70  zlib_flush_sync = 2, // 同步刷新
71  zlib_flush_full = 3, // 完全刷新
72  zlib_flush_finish = 4 // 完全刷新并停止压缩或解压过程
73 } zlib_flush_t;
74 
75 class string;
76 
78 {
79 public:
80  zlib_stream(void);
81  ~zlib_stream(void);
82 
83  /**
84  * 非流式压缩
85  * @param in {const char*} 源数据
86  * @param len {int} 源数据长度
87  * @param out {string*} 存储压缩结果的用户缓冲区
88  * @param level {zlib_level_t} 压缩级别,级别越高则压缩比越高,
89  * 但压缩速度越低
90  * @return {bool} 压缩过程是否成功
91  */
92  bool zlib_compress(const char* in, int len, string* out,
93  zlib_level_t level = zlib_default);
94 
95  /**
96  * 非流式解压缩
97  * @param in {const char*} 源压缩数据
98  * @param len {int} 源数据长度
99  * @param out {string*} 存储解压缩结果的用户缓冲区
100  * @param have_zlib_header {bool} 是否有 zlib_header 头,对
101  * HTTP 传输协议而言应该将此值设为 false
102  * @param wsize {int} 解压过程中的滑动窗口大小
103  * @return {bool} 解压缩过程是否成功
104  */
105  bool zlib_uncompress(const char* in, int len, string* out,
106  bool have_zlib_header = true, int wsize = 15);
107 
108  ///////////////////////////////////////////////////////////////
109  //
110  // 以下为流式压缩和流式解压缩过程
111  //
112  ///////////////////////////////////////////////////////////////
113 
114  /**
115  * 开始压缩过程,如果采用流式压缩方式,则调用顺序必须是:
116  * zip_begin->zip_update->zip_finish,如果中间任何一个
117  * 过程失败,则应该调用 zip_reset
118  * @param level {zlib_level_t} 压缩级别,级别越高,则压缩比
119  * 越高,但压缩速度越低
120  * @param wbits {zlib_wbits_t} 压缩过程中的滑动窗口级别,值越大,则
121  * 压缩效率越高且使用内存越多,针对 HTTP 数据压缩传输,应该采用该
122  * 值的负值,如:-zlib_wbits_15
123  * @param mlevel {zlib_mlevel_t} 压缩过程中的内存分配策略,值越大,
124  * 则压缩效率越高且内存使用越多
125  * @return {bool} 压缩初始化过程是否成功,失败的原因一般
126  * 应该是输入的参数非法
127  */
128  bool zip_begin(zlib_level_t level = zlib_default,
129  int wbits = zlib_wbits_15,
130  zlib_mlevel_t mlevel = zlib_mlevel_9);
131 
132  /**
133  * 循环调用此函数对源数据进行压缩
134  * @param in {const char*} 源数据
135  * @param len {int} 源数据长度
136  * @param out {string*} 用户缓冲区,该函数以添加方式往用户
137  * 提供的缓冲区中添加压缩的结果,用户应该自行判断调用本函数
138  * 前后的缓冲区长度,以确定由该函数添加的数据长度,由于所
139  * 选择的 zlib_flush_t 的不同,该缓冲区中数据可能未必存取
140  * 所有的结果
141  * @param flag {zlib_flush_t} 压缩过程中的数据缓冲方式
142  * zlib_flush_off: 数据结果可能不会立即刷新至用户缓冲区,
143  * zlib 库本身决定刷新的方式,从而可能会获得较高的压缩比
144  * zlib_flush_partial: 数据结果可能会部分刷新至用户缓冲区
145  * zlib_flush_sync: 数据数据同步刷新至用户缓冲区
146  * zlib_flush_full: 将 zlib 库缓冲数据结果全部刷新至用户缓冲区
147  * zlib_flush_finish: 调用本参数后表明压缩过程结束,同时会将
148  * 所有结果数据刷新至用户缓冲区,一般该参数不需要调用,因为在
149  * 调用 zip_finish 后,会自动将所有的缓冲数据刷新至用户缓冲区
150  * @return {bool} 压缩过程是否失败
151  */
152  bool zip_update(const char* in, int len, string* out,
154 
155  /**
156  * 调用本函数表示压缩过程结束
157  * @param out {string} 用户缓冲区,该函数会将 zlib 库缓冲区中
158  * 的数据以添加的方式都刷新至用户缓冲区
159  * @return {bool} 是否成功
160  */
161  bool zip_finish(string* out);
162 
163  /**
164  * 重置压缩器状态,一般只有当压缩过程出错时才会调用本函数
165  * @return {bool} 是否成功
166  */
167  bool zip_reset(void);
168 
169  /**
170  * 在压缩过程中可使用此函数计算数据的 crc32 校验值
171  * @param n {unsigned} 上次计算的校验和值,第一次时可写 0
172  * @param buf {const void*} 需要校验的数据地址,第一次使用时写 NULL
173  * @param dlen {size_t} buf 数据的长度,第一次使用时写 0
174  * @return {unsinged} 本次计算的校验和值
175  */
176  unsigned crc32_update(unsigned n, const void* buf, size_t dlen);
177 
178  /**
179  * 开始解压缩过程,如果采用流式解压缩方式,则调用顺序必须是:
180  * unzip_begin->unzip_update->unzip_finish,如果中间任何一个
181  * 过程失败,则应该调用 unzip_reset
182  * @param have_zlib_header {bool} 是否有 zlib_header 头,对
183  * HTTP 传输协议而言应该将此值设为 false
184  * @param wsize {int} 解压过程中的滑动窗口大小
185  * @return {bool} 解压缩初始化过程是否成功,失败的原因一般
186  * 应该是输入的参数非法
187  */
188  bool unzip_begin(bool have_zlib_header = true, int wsize = 15);
189 
190  /**
191  * 循环调用此函数对源数据进行解压缩
192  * @param in {const char*} 压缩的源数据
193  * @param len {int} 源数据长度
194  * @param out {string*} 用户缓冲区,该函数以添加方式往用户
195  * 提供的缓冲区中添加解压的结果,用户应该自行判断调用本函数
196  * 前后的缓冲区长度,以确定由该函数添加的数据长度,由于所
197  * 选择的 zlib_flush_t 的不同,该缓冲区中数据可能未必存取
198  * 所有的结果
199  * @param flag {zlib_flush_t} 解压缩过程中的数据缓冲方式
200  * zlib_flush_off: 数据结果可能不会立即刷新至用户缓冲区,
201  * zlib 库本身决定刷新的方式
202  * zlib_flush_partial: 数据结果可能会部分刷新至用户缓冲区
203  * zlib_flush_sync: 数据数据同步刷新至用户缓冲区
204  * zlib_flush_full: 将 zlib 库缓冲数据结果全部刷新至用户缓冲区
205  * zlib_flush_finish: 调用本参数后表明解压缩过程结束,同时会将
206  * 所有结果数据刷新至用户缓冲区,一般该参数不需要调用,因为在
207  * 调用 zip_finish 后,会自动将所有的缓冲数据刷新至用户缓冲区
208  * @return {bool} 解压缩过程是否失败
209  */
210  bool unzip_update(const char* in, int len, string* out,
212 
213  /**
214  * 调用本函数表示解压缩过程结束
215  * @param out {string} 用户缓冲区,该函数会将 zlib 库缓冲区中
216  * 的数据以添加的方式都刷新至用户缓冲区
217  * @return {bool} 是否成功
218  */
219  bool unzip_finish(string* out);
220 
221  /**
222  * 重置解压缩器状态,一般只有当解压缩过程出错时才会调用本函数
223  * @return {bool} 是否成功
224  */
225  bool unzip_reset(void);
226 
227  /**
228  * 获得当前的 zstream 对象
229  * @return {z_stream*}
230  */
231  z_stream* get_zstream(void) const
232  {
233  return zstream_;
234  }
235 
236  /**
237  * 当采用动态加载方式加载动态库时,可以使用此函数设置动态库的加载全路径
238  */
239  static void set_loadpath(const char* path);
240 
241  /**
242  * 当设置了动态库的动态加载全路径时,可以通过本函数获得动态库加载全路径
243  * @return {const char*} 当未设置时则返回 NULL
244  */
245  static const char* get_loadpath(void);
246 
247  /**
248  * 手动调用动态加载 zlib 库方法,如果为静态链接,则无需调用本方法,
249  * 此外,如果 zlib 动态库不在程序运行目录下时,需要先调用上面的
250  * set_loadpath() 方法设置 zlib 动态库的全路径;
251  * 该方法内部通过 pthread_once() 保证互斥调用,所以即使同时被多个
252  * 线程调用也是安全的
253  * @return {bool} 加载是否成功
254  */
255  static bool zlib_load_once(void);
256 
257  ///////////////////////////////////////////////////////////////
258 
259  bool pipe_zip_begin(zlib_level_t level = zlib_default,
261  bool pipe_unzip_begin(zlib_flush_t flag = zlib_flush_off);
262 
263  // pipe_stream 虚函数重载
264 
265  virtual int push_pop(const char* in, size_t len,
266  string* out, size_t max = 0);
267  virtual int pop_end(string* out, size_t max = 0);
268  virtual void clear(void);
269 
270 private:
271  z_stream* zstream_;
272  bool finished_;
273  bool is_compress_;
274  zlib_flush_t flush_;
275 
276  bool update(int (*func)(z_stream*, int), zlib_flush_t flag,
277  const char* in, int len, string* out);
278  bool flush_out(int (*func)(z_stream*, int),
279  zlib_flush_t flag, string* out);
280 };
281 
282 } // namespace acl
zlib_level_t
Definition: zlib_stream.hpp:13
z_stream * get_zstream(void) const
struct z_stream_s z_stream
Definition: zlib_stream.hpp:5
zlib_mlevel_t
Definition: zlib_stream.hpp:49
zlib_flush_t
Definition: zlib_stream.hpp:66
#define ACL_CPP_API