怎么用zlib解压gzip数据

tdjdyq 2009-03-20 04:52:32
怎么用zib库去解压gzip
int ZEXPORT uncompress (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
{
z_stream stream;
int err;

stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen;
/* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;

stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;

stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;

err = inflateInit2(&stream,15);
if (err != Z_OK) return err;

err = inflate(&stream, Z_NO_FLUSH);
if (err != Z_STREAM_END) {
inflateEnd(&stream);
if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
return Z_DATA_ERROR;
return err;
}
*destLen = stream.total_out;

err = inflateEnd(&stream);
return err;
}
这个解压zlib的,解压gzib怎么写呢
...全文
649 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
RLib 2012-04-03
  • 打赏
  • 举报
回复

class CGZIP
{
public:
LPGZIP pgzip;
int Length;
public:
CGZIP(char* lpsz, Memory *pool, int len = -1):pgzip(0),Length(0)
{
this->m_pool = pool;
Init(lpsz,len);
}
~CGZIP()
{
if(pgzip!=m_buffer) TRYFREE(pgzip);
}
void Init(char *lpsz,int len=-1)
{
if(lpsz==0)
{
pgzip=0;
Length=0;
return ;
}
if(len==-1)
{
len=(int)strlen(lpsz);
}
m_CurrentBufferSize=BufLength;
pgzip=m_buffer;
m_zstream.zalloc = (alloc_func)0;
m_zstream.zfree = (free_func)0;
m_zstream.opaque = (voidpf)0;
m_zstream.next_in = Z_NULL;
m_zstream.next_out = Z_NULL;
m_zstream.avail_in = 0;
m_zstream.avail_out = 0;
m_z_err = Z_OK;
m_crc = crc32(0L, Z_NULL, 0);
int err = deflateInit2(&(m_zstream), t_nLevel,Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, t_nStrategy);
m_outbuf = (Byte*)ALLOC(Z_BUFSIZE);
m_zstream.next_out = m_outbuf;
if (err != Z_OK || m_outbuf == Z_NULL)
{
destroy();
return ;
}
m_zstream.avail_out = Z_BUFSIZE;
GZIP header[10]={0x1f,0x8b,Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE};
write(header,10);

m_zstream.next_in = (Bytef*)lpsz;
m_zstream.avail_in = len;
while (m_zstream.avail_in != 0)
{
if (m_zstream.avail_out == 0)
{
m_zstream.next_out = m_outbuf;
this->write(m_outbuf,Z_BUFSIZE);
m_zstream.avail_out = Z_BUFSIZE;
}
m_z_err = deflate(&m_zstream,Z_NO_FLUSH);
if (m_z_err != Z_OK) break;
}
m_crc = crc32(m_crc, (const Bytef *)lpsz, len);
if (finish() != Z_OK) { destroy(); return ;}
putLong(m_crc);
putLong (m_zstream.total_in);
destroy();
}
private:
GZIP m_buffer[BufLength];
int m_CurrentBufferSize;
Memory *m_pool;
z_stream m_zstream;
int m_z_err; /* error code for last stream operation */
Byte *m_outbuf; /* output buffer */
uLong m_crc; /* crc32 of uncompressed data */

int write(LPGZIP buf,int count)
{
if(buf==0) return 0;
if(Length+count>m_CurrentBufferSize)
{
int nTimes=(Length+count)/BufLength +1;
LPGZIP pTemp=pgzip;
pgzip=static_cast<LPGZIP>( malloc(nTimes*BufLength));
m_CurrentBufferSize=nTimes*BufLength;
System::IO::Memory::memcpy(pgzip,pTemp,Length);
if(pTemp!=m_buffer) free(pTemp);
}
System::IO::Memory::memcpy(pgzip+Length,buf,count);
Length+=count;
return count;
}
int finish()
{
uInt len;
int done = 0;
m_zstream.avail_in = 0;
for (;;)
{
len = Z_BUFSIZE - m_zstream.avail_out;
if (len != 0)
{
write(m_outbuf,len);
m_zstream.next_out = m_outbuf;
m_zstream.avail_out = Z_BUFSIZE;
}
if (done) break;
m_z_err = deflate(&(m_zstream), Z_FINISH);
if (len == 0 && m_z_err == Z_BUF_ERROR) m_z_err = Z_OK;

done = (m_zstream.avail_out != 0 || m_z_err == Z_STREAM_END);
if (m_z_err != Z_OK && m_z_err != Z_STREAM_END) break;
}
return m_z_err == Z_STREAM_END ? Z_OK : m_z_err;
}
int destroy()
{
int err = Z_OK;
if (m_zstream.state != NULL) {
err = deflateEnd(&(m_zstream));
}
if (m_z_err < 0) err = m_z_err;
TRYFREE(m_outbuf);
return err;
}
void putLong (uLong x)
{
for(int n = 0; n < 4; n++) {
unsigned char c=(unsigned char)(x & 0xff);
write(&c,1);
x >>= 8;
}
}
};
class UNGZIP
{
public:
char *psz;
int Length;
UNGZIP(LPGZIP pgzip, int len, Memory *pool):m_gzip(pgzip),m_gziplen(len),psz(0),Length(0),m_pos(0)
{
this->m_pool = pool;
Init();
}
~UNGZIP()
{
if(psz!=m_buffer) TRYFREE(psz);
}
void Init()
{
if(m_gzip==0)
{
psz=0;
Length=0;
return ;
}
m_CurrentBufferSize=BufLength;
psz=m_buffer;
System::IO::Memory::memset(psz,0,m_CurrentBufferSize+1);

m_zstream.zalloc = (alloc_func)0;
m_zstream.zfree = (free_func)0;
m_zstream.opaque = (voidpf)0;
m_zstream.next_in = m_inbuf = Z_NULL;
m_zstream.next_out = Z_NULL;
m_zstream.avail_in = m_zstream.avail_out = 0;
m_z_err = Z_OK;
m_z_eof = 0;
m_transparent = 0;
m_crc = crc32(0L, Z_NULL, 0);

m_zstream.next_in =m_inbuf = (Byte*)ALLOC(Z_BUFSIZE);
int err = inflateInit2(&(m_zstream), -MAX_WBITS);
if (err != Z_OK || m_inbuf == Z_NULL)
{
destroy();
return;
}
m_zstream.avail_out = Z_BUFSIZE;
check_header();
char outbuf[Z_BUFSIZE];
int nRead;
while((nRead = gzread(outbuf,Z_BUFSIZE)) > 0)
{
write(outbuf,nRead);
}
destroy();
}
private:
char m_buffer[BufLength+1];
int m_CurrentBufferSize;
Memory *m_pool;
z_stream m_zstream;
int m_z_err; /* error code for last stream operation */
Byte *m_inbuf; /* output buffer */
uLong m_crc; /* crc32 of uncompressed data */
int m_z_eof;
int m_transparent;
int m_pos;
LPGZIP m_gzip;
int m_gziplen;

void check_header()
{
int method; /* method byte */
int flags; /* flags byte */
uInt len;
int c;

/* Check the gzip magic header */
for (len = 0; len < 2; len++) {
c = get_byte();
if (c != gz_magic[len]) {
if (len != 0) m_zstream.avail_in++, m_zstream.next_in--;
if (c != EOF) {
m_zstream.avail_in++, m_zstream.next_in--;
m_transparent = 1;
}
m_z_err =m_zstream.avail_in != 0 ? Z_OK : Z_STREAM_END;
return;
}
}
method = get_byte();
flags = get_byte();
if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
m_z_err = Z_DATA_ERROR;
return;
}
/* Discard time, xflags and OS code: */
for (len = 0; len < 6; len++) (void)get_byte();

if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
len = (uInt)get_byte();
len += ((uInt)get_byte())<<8;
/* len is garbage if EOF but the loop below will quit anyway */
while (len-- != 0 && get_byte() != EOF) ;
}
if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
while ((c = get_byte()) != 0 && c != EOF) ;
}
if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
while ((c = get_byte()) != 0 && c != EOF) ;
}
if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
for (len = 0; len < 2; len++) (void)get_byte();
}
m_z_err = m_z_eof ? Z_DATA_ERROR : Z_OK;
}
int get_byte()
{
if (m_z_eof) return EOF;
if (m_zstream.avail_in == 0)
{
errno = 0;
m_zstream.avail_in =read(m_inbuf,Z_BUFSIZE);
if(m_zstream.avail_in == 0)
{
m_z_eof = 1;
return EOF;
}
m_zstream.next_in = m_inbuf;
}
m_zstream.avail_in--;
return *(m_zstream.next_in)++;
}
int read(LPGZIP buf,int size)
{
int nRead=size;
if(m_pos+size>=m_gziplen)
{
nRead=m_gziplen-m_pos;
}
if(nRead<=0) return 0;
System::IO::Memory::memcpy(buf,m_gzip+m_pos,nRead);
m_pos+=nRead;
return nRead;
}
int gzread(char* buf,int len)
{
Bytef *start = (Bytef*)buf; /* starting point for crc computation */
Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */


if (m_z_err == Z_DATA_ERROR || m_z_err == Z_ERRNO) return -1;
if (m_z_err == Z_STREAM_END) return 0; /* EOF */

next_out = (Byte*)buf;
m_zstream.next_out = (Bytef*)buf;
m_zstream.avail_out = len;
while (m_zstream.avail_out != 0) {
if (m_transparent)
{
/* Copy first the lookahead bytes: */
uInt n = m_zstream.avail_in;
if (n > m_zstream.avail_out) n = m_zstream.avail_out;
if (n > 0)
{
zmemcpy(m_zstream.next_out,m_zstream.next_in, n);
next_out += n;
m_zstream.next_out = next_out;
m_zstream.next_in += n;
m_zstream.avail_out -= n;
m_zstream.avail_in -= n;
}
if (m_zstream.avail_out > 0) {
m_zstream.avail_out -=read(next_out,m_zstream.avail_out);
}
len -= m_zstream.avail_out;
m_zstream.total_in += (uLong)len;
m_zstream.total_out += (uLong)len;
if (len == 0) m_z_eof = 1;
return (int)len;
}
if (m_zstream.avail_in == 0 && !m_z_eof)
{
errno = 0;
m_zstream.avail_in = read(m_inbuf,Z_BUFSIZE);
if (m_zstream.avail_in == 0)
{
m_z_eof = 1;
}
m_zstream.next_in = m_inbuf;
}
m_z_err = inflate(&(m_zstream), Z_NO_FLUSH);
if (m_z_err == Z_STREAM_END)
{
/* Check CRC and original size */
m_crc = crc32(m_crc, start, (uInt)(m_zstream.next_out - start));
start = m_zstream.next_out;
if (getLong() != m_crc) {
m_z_err = Z_DATA_ERROR;
}else
{
(void)getLong();
check_header();
if (m_z_err == Z_OK)
{
uLong total_in = m_zstream.total_in;
uLong total_out = m_zstream.total_out;
inflateReset(&(m_zstream));
m_zstream.total_in = total_in;
m_zstream.total_out = total_out;
m_crc = crc32(0L, Z_NULL, 0);
}
}
}
if (m_z_err != Z_OK || m_z_eof) break;
}
m_crc = crc32(m_crc, start, (uInt)(m_zstream.next_out - start));
return (int)(len - m_zstream.avail_out);
}
uLong getLong()
{
uLong x = (uLong)get_byte();
int c;
x += ((uLong)get_byte())<<8;
x += ((uLong)get_byte())<<16;
c = get_byte();
if (c == EOF) m_z_err = Z_DATA_ERROR;
x += ((uLong)c)<<24;
return x;
}
int write(char* buf,int count)
{
if(buf==0) return 0;
if(Length+count>m_CurrentBufferSize)
{
int nTimes=(Length+count)/BufLength +1;
char *pTemp=psz;
psz=static_cast<char*>( malloc(nTimes*BufLength+1));
m_CurrentBufferSize=nTimes*BufLength;
Memory::memset(psz,0,m_CurrentBufferSize+1);
Memory::memcpy(psz,pTemp,Length);
if(pTemp!=m_buffer) free(pTemp);
}
Memory::memcpy(psz+Length,buf,count);
Length+=count;
return count;
}
int destroy()
{
int err = Z_OK;
if (m_zstream.state != NULL) {
err = inflateEnd(&(m_zstream));
}
if (m_z_err < 0) err = m_z_err;
TRYFREE(m_inbuf);
return err;
}
};
tdjdyq 2009-03-23
  • 打赏
  • 举报
回复
我英文不好,不明白呢
帅得不敢出门 2009-03-22
  • 打赏
  • 举报
回复
你没仔细看文档吧
http://www.zlib.net/manual.html

int uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the uncompressed buffer.
This function can be used to decompress a whole file at once if the input file is mmap'ed.

uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted.



int gzread (gzFile file, voidp buf, unsigned len);
Reads the given number of uncompressed bytes from the compressed file. If the input file was not in gzip format, gzread copies the given number of bytes into the buffer.
gzread returns the number of uncompressed bytes actually read (0 for end of file, -1 for error).

............

  • 打赏
  • 举报
回复
自己写?学习。。

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧