gunzip.cpp.svn-base
来自「wince c++ 下 开发的 rss 阅读器源代码」· SVN-BASE 代码 · 共 626 行 · 第 1/2 页
SVN-BASE
626 行
}
/* set previous code for next iteration */
prev = temp;
/* write output in forward order */
while (stack > SIZE - outcnt) {
while (outcnt < SIZE)
outbuf[outcnt++] = match[--stack];
if (out(&outd, outbuf, outcnt)) {
strm->next_in = outbuf; /* signal write error */
return Z_BUF_ERROR;
}
outcnt = 0;
}
do {
outbuf[outcnt++] = match[--stack];
} while (stack);
/* loop for next code with final and prev as the last match, rem and
left provide the first 0..7 bits of the next code, end is the last
valid table entry */
}
}
/* Decompress a gzip file from infile to outfile. strm is assumed to have been
successfully initialized with inflateBackInit(). The input file may consist
of a series of gzip streams, in which case all of them will be decompressed
to the output file. If outfile is -1, then the gzip stream(s) integrity is
checked and nothing is written.
The return value is a zlib error code: Z_MEM_ERROR if out of memory,
Z_DATA_ERROR if the header or the compressed data is invalid, or if the
trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends
prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip
stream) follows a valid gzip stream.
*/
local int gunpipe(z_stream *strm, HANDLE inFile, HANDLE outFile)
{
int ret, first, last;
unsigned have, flags, len;
unsigned char *next;
struct ind ind, *indp;
struct outd outd;
/* setup input buffer */
ind.inFile = inFile;
ind.inBuf = inbuf;
indp = &ind;
/* decompress concatenated gzip streams */
have = 0; /* no input data read in yet */
first = 1; /* looking for first gzip header */
strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */
for (;;) {
/* look for the two magic header bytes for a gzip stream */
if (NEXT() == -1) {
ret = Z_OK;
break; /* empty gzip stream is ok */
}
if (last != 31 || (NEXT() != 139 && last != 157)) {
strm->msg = (char *)"incorrect header check";
ret = first ? Z_DATA_ERROR : Z_ERRNO;
break; /* not a gzip or compress header */
}
first = 0; /* next non-header is junk */
/* process a compress (LZW) file -- can't be concatenated after this */
if (last == 157) {
ret = lunpipe(have, next, indp, outFile, strm);
break;
}
/* process remainder of gzip header */
ret = Z_BUF_ERROR;
if (NEXT() != 8) { /* only deflate method allowed */
if (last == -1) break;
strm->msg = (char *)"unknown compression method";
ret = Z_DATA_ERROR;
break;
}
flags = NEXT(); /* header flags */
NEXT(); /* discard mod time, xflgs, os */
NEXT();
NEXT();
NEXT();
NEXT();
NEXT();
if (last == -1) break;
if (flags & 0xe0) {
strm->msg = (char *)"unknown header flags set";
ret = Z_DATA_ERROR;
break;
}
if (flags & 4) { /* extra field */
len = NEXT();
len += (unsigned)(NEXT()) << 8;
if (last == -1) break;
while (len > have) {
len -= have;
have = 0;
if (NEXT() == -1) break;
len--;
}
if (last == -1) break;
have -= len;
next += len;
}
if (flags & 8) /* file name */
while (NEXT() != 0 && last != -1)
;
if (flags & 16) /* comment */
while (NEXT() != 0 && last != -1)
;
if (flags & 2) { /* header crc */
NEXT();
NEXT();
}
if (last == -1) break;
/* set up output */
outd.outFile = outFile;
outd.check = 1;
outd.crc = crc32(0L, Z_NULL, 0);
outd.total = 0;
/* decompress data to output */
strm->next_in = next;
strm->avail_in = have;
ret = inflateBack(strm, in, indp, out, &outd);
if (ret != Z_STREAM_END) break;
next = strm->next_in;
have = strm->avail_in;
strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */
/* check trailer */
ret = Z_BUF_ERROR;
if (NEXT() != (signed) (outd.crc & 0xff) ||
NEXT() != (signed) ((outd.crc >> 8) & 0xff) ||
NEXT() != (signed) ((outd.crc >> 16) & 0xff) ||
NEXT() != (signed) ((outd.crc >> 24) & 0xff)) {
/* crc error */
if (last != -1) {
strm->msg = (char *)"incorrect data check";
ret = Z_DATA_ERROR;
}
break;
}
if (NEXT() != (signed) (outd.total & 0xff) ||
NEXT() != (signed) ((outd.total >> 8) & 0xff) ||
NEXT() != (signed) ((outd.total >> 16) & 0xff) ||
NEXT() != (signed) ((outd.total >> 24) & 0xff)) {
/* length error */
if (last != -1) {
strm->msg = (char *)"incorrect length check";
ret = Z_DATA_ERROR;
}
break;
}
/* go back and look for another gzip stream */
}
/* clean up and return */
return ret;
}
BOOL GunzipFile(LPCTSTR inFileName, LPCTSTR outFileName) {
BOOL ret = FALSE;
unsigned char *window;
z_stream strm;
/* initialize inflateBack state for repeated use */
window = match; /* reuse LZW match buffer */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = inflateBackInit(&strm, 15, window);
//
HANDLE inFile = CreateFile(inFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (inFile != INVALID_HANDLE_VALUE) {
HANDLE outFile = CreateFile(outFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (outFile != INVALID_HANDLE_VALUE) {
// decompress
ret = gunpipe(&strm, inFile, outFile);
CloseHandle(outFile);
}
CloseHandle(inFile);
}
/* clean up */
inflateBackEnd(&strm);
return ret;
}
#define CHUNK 8192
int inf(HANDLE source, HANDLE dest) {
BOOL mDummyStreamInitialised = FALSE;
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
// allocate inflate state
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
DWORD read;
// decompress until deflate stream ends or end of file
do {
if (strm.avail_in == 0) {
if (!ReadFile(source, in, CHUNK, &read, NULL)) {
(void) inflateEnd(&strm);
return Z_ERRNO;
}
strm.avail_in = read;
if (strm.avail_in == 0)
break;
strm.next_in = in;
}
// run inflate() on input until output buffer not full
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret == Z_DATA_ERROR) {
// this is taken form firefox source code
//
// some servers (notably Apache with mod_deflate) don't generate zlib headers
// insert a dummy header and try again
static char dummy_head[2] = {
0x8 + 0x7 * 0x10,
(((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
};
inflateReset(&strm);
strm.next_in = (Bytef*) dummy_head;
strm.avail_in = sizeof(dummy_head);
ret = inflate(&strm, Z_NO_FLUSH);
if (ret != Z_OK)
return Z_ERRNO;
// stop an endless loop caused by non-deflate data being labelled as deflate
if (mDummyStreamInitialised) {
// endless loop detected
return Z_ERRNO;
}
mDummyStreamInitialised = TRUE;
// reset stream pointers to our original data
strm.next_in = in;
strm.avail_in = (uInt) read;
}
else if (ret == Z_MEM_ERROR) {
(void) inflateEnd(&strm);
return ret;
}
else if (ret == Z_OK) {
have = CHUNK - strm.avail_out;
DWORD written;
if (!WriteFile(dest, out, have, &written, NULL) || written != have) {
(void) inflateEnd(&strm);
return Z_ERRNO;
}
}
} while (strm.avail_out == 0);
// done when inflate() says it's done
} while (ret != Z_STREAM_END);
// clean up and return
(void) inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
BOOL InflateFile(LPCTSTR inFileName, LPCTSTR outFileName) {
BOOL ret = FALSE;
//
HANDLE inFile = CreateFile(inFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (inFile != INVALID_HANDLE_VALUE) {
HANDLE outFile = CreateFile(outFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (outFile != INVALID_HANDLE_VALUE) {
// decompress
ret = inf(inFile, outFile);
CloseHandle(outFile);
}
CloseHandle(inFile);
}
return ret;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?