【C/C++】C实现gzip格式的压缩与解压Demo

2052人阅读 评论(3) 收藏 举报
分类:

参考链接: 

http://www.codeproject.com/Questions/341319/C-Decompress-Gzipped-http-response

http://www.cppblog.com/woaidongmao/archive/2011/06/05/148089.html

http://stackoverflow.com/questions/13762918/setup-zlib-to-generate-gzipped-data


基于原有的代码整理后, 实现基础的gzip格式字节流压缩与解压, 代码如下:

#include <stdio.h>
#include<stdlib.h>
#include <string.h>
#include <zlib.h>

// gzCompress: do the compressing
int gzCompress(const char *src, int srcLen, char *dest, int destLen)
{
	z_stream c_stream;
	int err = 0;
	int windowBits = 15;
	int GZIP_ENCODING = 16;

	if(src && srcLen > 0)
	{
		c_stream.zalloc = (alloc_func)0;
		c_stream.zfree = (free_func)0;
		c_stream.opaque = (voidpf)0;
		if(deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 
                    windowBits | GZIP_ENCODING, 8, Z_DEFAULT_STRATEGY) != Z_OK) return -1;
		c_stream.next_in  = (Bytef *)src;
		c_stream.avail_in  = srcLen;
		c_stream.next_out = (Bytef *)dest;
		c_stream.avail_out  = destLen;
		while (c_stream.avail_in != 0 && c_stream.total_out < destLen) 
		{
			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;
		return c_stream.total_out;
	}
	return -1;
}

// gzDecompress: do the decompressing
int gzDecompress(const char *src, int srcLen, const char *dst, int dstLen){
	z_stream strm;
	strm.zalloc=NULL;
	strm.zfree=NULL;
	strm.opaque=NULL;
	 
	strm.avail_in = srcLen;
	strm.avail_out = dstLen;
	strm.next_in = (Bytef *)src;
	strm.next_out = (Bytef *)dst;
	 
	int err=-1, ret=-1;
	err = inflateInit2(&strm, MAX_WBITS+16);
	if (err == Z_OK){
	    err = inflate(&strm, Z_FINISH);
	    if (err == Z_STREAM_END){
	        ret = strm.total_out;
	    }
	    else{
	        inflateEnd(&strm);
	        return err;
	    }
	}
	else{
	    inflateEnd(&strm);
	    return err;
	}
	inflateEnd(&strm);
	return err;
}

int main()
{
	char* src = "just for test, dd, dd, dd";
	int size_src = strlen(src);
	char* compressed = malloc(size_src*2);
	memset(compressed, 0, size_src*2);
	printf("to compress src: %s\n", src);
	printf("to compress src size: %d\n", size_src);

	int gzSize = gzCompress(src, size_src, compressed, size_src*2);
	if (gzSize <= 0)
	{
		printf("compress error.\n");
		return -1;
	}
	printf("compressed: ");
	int i = 0;
	for (; i<gzSize; ++i)
	{
		printf("%02x ", compressed[i]);
	}
	printf("\ncompressed size: %d\n", gzSize);

	char* uncompressed = malloc(size_src*2);
	memset(uncompressed, 0, size_src*2);
	int ret = gzDecompress(compressed, gzSize, uncompressed, size_src*2);
	printf("uncompressed: %s\n", uncompressed);
	printf("uncompressed size: %d\n", strlen(uncompressed));

	free(compressed);
	free(uncompressed);
	return 0;
}
运行效果:

root@xiaomo:/data/apps/# ./zlib_test 
to compress src: just for test, dd, dd, dd
to compress src size: 25
compressed: 1f 8b 08 00 00 00 00 00 00 03 cb 2a 2d 2e 51 48 cb 2f 52 28 49 2d 2e d1 51 48 49 81 61 00 33 c3 e2 f3 19 00 00 00 
compressed size: 38
uncompressed: just for test, dd, dd, dd
uncompressed size: 25



1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1815580次
    • 积分:19135
    • 等级:
    • 排名:第518名
    • 原创:306篇
    • 转载:83篇
    • 译文:20篇
    • 评论:274条
    学习交流
    Email: moxiaomomo@gmail.com
    QQ:    809444138
    博客专栏
    最新评论