本身这段代码也是从网络上找来的,但是网上的内容都没有针对gzip做特别说明,所以直接拿来用的时候出了些问题,现将我修改后的发在这里。
注意代码中的注释部分,这里设置是专门针对gzip的,缺少了就不行了,gzip压缩格式和其他格式的区别就在这里。
Bytef 就是 unsigned char,uLong就是 unsigned long,这些别名的设置都在zconf.h文件里面。
这里压缩和解压缩的数据都可以用java的GZIPInputStream和GZIPOutputStream来对应解压缩和压缩。
#include的头文件都是zlib自带的文件,可以在官网下载,具体的文件列表可以在这里看
- #ifndef GZIP_H
- #define GZIP_H
-
- #include "zlib/zlib.h"
-
-
-
- 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;
-
- 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;
- }
-
-
-
- int gzdecompress(Byte *zdata, uLong nzdata,
- Byte *data, uLong *ndata)
- {
- int err = 0;
- z_stream d_stream = {0};
- 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;
-
- if(inflateInit2(&d_stream, MAX_WBITS + 16) != Z_OK) return -1;
-
- while(d_stream.total_out < *ndata && d_stream.total_in < nzdata) {
- d_stream.avail_in = d_stream.avail_out = 1;
- 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
(antipro ) |