王骏的博客
编程、网络技术点滴...

公告

逐渐将VC知识库的博客迁移到这里!

随笔分类

随笔档案

相册

最新评论

阅读排行榜

评论排行榜

程序员博客   首页  新随笔  订阅  管理  登录 
 
王骏的博客 阅读(1930) 评论(1)

为了节省带宽许多网站都采用GZip压缩页面,Apache,PHP都能提供GZip支持,经GZip压缩的HTTP页面的HTTP头有如下标记:Content-Encoding = gzip
GZip数据以0x1f,0x8B开头,文件头长度通常为10。
用zlib的uncompress无法解成功,测试了网上许多版本都失败,最后总结了可行的代码:

int GZipUncompress(Byte *dest, uLong *destLen, Byte *src, uLong srcLen)  
{  
 // 本文来源 http://www.okbase.net
 int err;  
 z_stream d_stream;  
 memset(&d_stream, 0, sizeof(z_stream));  
   
 d_stream.next_in = src;
 d_stream.avail_in = srcLen; 
 d_stream.next_out = dest; 
 d_stream.avail_out = *destLen;
   
 err = inflateInit2(&d_stream, -MAX_WBITS);
 if(err != Z_OK)
  return(err);

 d_stream.next_in += 10L; // 跳过GZip文件头,这里没有仔细处理,长度可以通过文件头数据取得

 err = inflate(&d_stream, Z_FINISH);
 if (err != Z_STREAM_END) {
        inflateEnd(&d_stream);
        return err == Z_OK ? Z_BUF_ERROR : err;
    }

 *destLen = d_stream.total_out;

 err = inflateEnd(&d_stream); 
 return(err);  
}  

// 测试代码
char *pMem = ... // 数据源
int MemSize; // 数据源长度

unsigned long BufferSize = MemSize * 6;
char *pBuffer = new char[BufferSize];  // BufferSize要足够大
   memset(pBuffer, 0, BufferSize);

   int result = GZipUncompress((unsigned char *)pBuffer, &BufferSize, (unsigned char *)pMem, MemSize);
   if(result == Z_OK)
   { 
    // 成功
   }

// 需要改进的几点问题
(1)没有处理目标缓冲区大小不够的情况
(2)跳过GZip文件头的长度没有从文件头中读取
时间不够,需要的朋友请自行修改,改好了记得贴一下自己的代码哦!


评论列表
Kunwar
The accident of finding this post has brithgened my day

发表评论
切换编辑模式