使用zlib实现gzip格式数据的压缩和解压
2024-09-29 10:30:11
注意代码中的注释部分,这里设置是专门针对gzip的,缺少了就不行了,gzip压缩格式和其他格式的区别就在这里。
Bytef 就是 unsigned char,uLong就是 unsigned long,这些别名的设置都在zconf.h文件里面。
这里压缩和解压缩的数据都可以用java的GZIPInputStream和GZIPOutputStream来对应解压缩和压缩。
代码片
#ifndef GZIP_H
#define GZIP_H
#include "zlib/zlib.h"
/* Compress gzip data */
/* data 原数据 ndata 原数据长度 zdata 压缩后数据 nzdata 压缩后长度 */
int gzcompress(Bytef *data, uLong ndata,
Bytef *zdata, uLong *nzdata)
{
z_stream c_stream;
int err = 0;
if(data && ndata > 0) {
c_stream.zalloc = NULL;
c_stream.zfree = NULL;
c_stream.opaque = NULL;
//只有设置为MAX_WBITS + 16才能在在压缩文本中带header和trailer
if(deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY) != Z_OK) return -1;
c_stream.next_in = data;
c_stream.avail_in = ndata;
c_stream.next_out = zdata;
c_stream.avail_out = *nzdata;
while(c_stream.avail_in != 0 && c_stream.total_out < *nzdata) {
if(deflate(&c_stream, Z_NO_FLUSH) != Z_OK) return -1;
}
if(c_stream.avail_in != 0) return c_stream.avail_in;
for(;;) {
if((err = deflate(&c_stream, Z_FINISH)) == Z_STREAM_END) break;
if(err != Z_OK) return -1;
}
if(deflateEnd(&c_stream) != Z_OK) return -1;
*nzdata = c_stream.total_out;
return 0;
}
return -1;
}
/* Uncompress gzip data */
/* zdata 数据 nzdata 原数据长度 data 解压后数据 ndata 解压后长度 */
int gzdecompress(Byte *zdata, uLong nzdata,
Byte *data, uLong *ndata)
{
int err = 0;
z_stream d_stream = {0}; /* decompression stream */
static char dummy_head[2] = {
0x8 + 0x7 * 0x10,
(((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
};
d_stream.zalloc = NULL;
d_stream.zfree = NULL;
d_stream.opaque = NULL;
d_stream.next_in = zdata;
d_stream.avail_in = 0;
d_stream.next_out = data;
//只有设置为MAX_WBITS + 16才能在解压带header和trailer的文本
if(inflateInit2(&d_stream, MAX_WBITS + 16) != Z_OK) return -1;
//if(inflateInit2(&d_stream, 47) != Z_OK) return -1;
while(d_stream.total_out < *ndata && d_stream.total_in < nzdata) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break;
if(err != Z_OK) {
if(err == Z_DATA_ERROR) {
d_stream.next_in = (Bytef*) dummy_head;
d_stream.avail_in = sizeof(dummy_head);
if((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK) {
return -1;
}
} else return -1;
}
}
if(inflateEnd(&d_stream) != Z_OK) return -1;
*ndata = d_stream.total_out;
return 0;
}
#endif // GZIP_H
最新文章
- Python for Informatics 第11章 正则表达式四(译)
- SeleniumIDE从0到1 (Selenium IDE 安装)
- ShowDoc部署手册
- HTML学习总结
- 命令行登陆Oracle(包括远程登陆)
- CF 2B.The least round way
- 修改oracle内存占用
- Zabbix报告无交换内存主机 Lack of free swap space on xxxxx
- 用c++处理文件流
- swift 同步加载图片
- C# 线程--第一单线程基础
- android开发中如何结束所有的activity
- Python脚本控制的WebDriver 常用操作 <;二十二>; 处理alert / confirm / prompt
- MFC对话框
- url解析
- 【转】 iOS 原生二维码扫描(可限制扫描区域)
- 《Programming WPF》翻译 第9章 5.默认可视化
- 使用scipy进行聚类
- 连锁反应confirm
- Http2改造实践:statusText丢失问题
热门文章
- Java 线程第三版 第五章 极简同步技巧 读书笔记
- Orcad CIS怎么批量修改字体大小
- cartographer Ubuntu16.04 ros环境配置
- windows平台下为Nginx反向代理(负载均衡)使用openssl增加HTTPS/SSL功能。
- Linux相互排斥与同步应用(三):posix线程实现单个生产者和单个消费者模型
- mac环境下清理系统垃圾clearMyMac 3.9 破解版
- python升级或者其他原因把yum搞坏了
- 使用mysqld_multi 实现Mysql 5.6.36 + 5.7.18 单机多实例多版本安装
- linux history 命令 禁用history
- JavaWeb学习总结第三篇--走进JSP页面元素