📄 unzip.cpp
字号:
#include "stdafx.h"
#include <sys/stat.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include "zipsha.h"
#include "tailor.h"
#include "revision.h"
#include "UnZip.h"
#include "UnZipDate.h"
static unsigned border[] = { /* Order of the bit length code lengths */
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
static ush cplens[] = { /* Copy lengths for literal codes 257..285 */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
/* note: see note #13 above about the 258 in this list. */
static ush cplext[] = { /* Extra bits for literal codes 257..285 */
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */
static ush cpdist[] = { /* Copy offsets for distance codes 0..29 */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577};
static ush cpdext[] = { /* Extra bits for distance codes */
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13};
ush mask_bits[] = {
0x0000,
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
};
extern ulg __crc_32_tab[];
//part1-------------------------------------------
#define source1 unzipdate->source1
#define dest1 unzipdate->dest1
#define sourceLen1 unzipdate->sourceLen1
#define destLen1 unzipdate->destLen1
#define inSize unzipdate->inSize
#define outSize unzipdate->outSize
#define errorNumber unzipdate->errorNumber
#define header_bytes unzipdate->header_bytes
#define method unzipdate->method
#define verbose unzipdate->verbose
#define bytes_in unzipdate->bytes_in
#define bytes_out unzipdate->bytes_out
#define insize unzipdate->insize
#define inptr unzipdate->inptr
#define outcnt unzipdate->outcnt
#define static_crc unzipdate->static_crc
//part2--------------------------------
#define bb unzipdate->bb
#define bk unzipdate->bk
#define lbits unzipdate->lbits
#define dbits unzipdate->dbits
#define hufts unzipdate->hufts
//part3-------------------------------
#define inbuf unzipdate->inbuf
#define outbuf unzipdate->outbuf
#define d_buf unzipdate->d_buf
#define window unzipdate->window
#ifndef MAXSEG_64K
// #define tab_prefix unzipdate->tab_prefix
#define prev unzipdate->prev
#else
#define tab_prefix0 unzipdate->tab_prefix0
#define prev unzipdate->prev
#define tab_prefix1 unzipdate->tab_prefix1
#define head unzipdate->tab_prefix1
#endif
///////////////////////////
extern DWORD UnZipMain(UnZipDate* unzipdate);
extern int unzip(UnZipDate* unzipdate);
extern UINT Read(UnZipDate* unzipdate,char *buf,UINT size);
extern UINT Write(UnZipDate* unzipdate,char *buf,UINT size);
extern ulg updcrc(UnZipDate* unzipdate,uch *s, unsigned n);
extern int fill_inbuf(UnZipDate* unzipdate,int eof_ok);
extern void flush_window(UnZipDate* unzipdate);
extern void write_buf(UnZipDate* unzipdate,voidp buf, unsigned cnt);
extern int huft_build(UnZipDate* unzipdate,unsigned *, unsigned, unsigned, ush *, ush *,struct huft **, int *);
extern int huft_free(UnZipDate* unzipdate,struct huft *);
extern int inflate_codes(UnZipDate* unzipdate,struct huft *, struct huft *, int, int);
extern int inflate_stored(UnZipDate* unzipdate);
extern int inflate_fixed(UnZipDate* unzipdate);
extern int inflate_dynamic(UnZipDate* unzipdate);
extern int inflate_block(UnZipDate* unzipdate,int *);
extern int inflate(UnZipDate* unzipdate);
/* ======================================================================== */
DWORD UnZipMain(UnZipDate* unzipdate)
{
inSize=outSize=0;
errorNumber=0;
static_crc = (ulg)0xffffffffL; /* shift register contents */
verbose = 0; /* be verbose (-v) */
lbits = 9; /* bits in base literal/length lookup table */
dbits = 6; /* bits in base distance lookup table */
outcnt = 0;
insize = inptr = 0;
bytes_in = bytes_out = 0L;
header_bytes = 0;
char magic[2]; /* magic header */
magic[0] = (char)get_byte();
magic[1] = (char)get_byte();
method = (int)get_byte();
if(errorNumber!=0) return -2;
if(memcmp(magic, GZIP_MAGIC, 2) == 0 && method == DEFLATED)
{ header_bytes = inptr + 2*sizeof(long); /* include crc and size */
}else
{return -2;
}
//预先检验解压长度
if(sourceLen1<7)return -2;
BYTE *sizelong,c1,c2,c3,c4;
sizelong=source1+sourceLen1-4;
c1=*sizelong++;
c2=*sizelong++;
c3=*sizelong++;
c4=*sizelong;
outSize=c1 | c2<<8 | c3<<16 | c4<<32;
if(destLen1<outSize)return 0;
outSize=0;
if (unzip(unzipdate) != OK){return -2;}
if (inptr != insize){return -2;}
if(destLen1<outSize)return -2;
return method;
}
//unzip
#define EXTHDR 16 /* size of extended local header, inc sig */
int unzip(UnZipDate* unzipdate)
{
ulg orig_crc = 0; /* original crc */
ulg orig_len = 0; /* original uncompressed length */
int n;
uch buf[EXTHDR]; /* extended local header */
updcrc(unzipdate,NULL, 0); /* initialize crc */
/* Decompress */
if (method == DEFLATED)
{ int res = inflate(unzipdate);
if (res == 3) {
return -2; //error("out of memory");
} else if (res != 0) {
return -2; //error("invalid compressed data--format violated");
}
}
for (n = 0; n < 8; n++)
{ buf[n] = (uch)get_byte();} /* may cause an error if EOF */
if(errorNumber!=0)return -2;
orig_crc = LG(buf);
orig_len = LG(buf+4);
/* Validate decompression */
if (orig_crc != updcrc(unzipdate,outbuf, 0)) {
return -2; //error("invalid compressed data--crc error");
}
if (orig_len != (ulg)bytes_out) {
return -2; //error("invalid compressed data--length error");
}
return OK;
}
//============================================
UINT Read(UnZipDate* unzipdate,char *buf,UINT size)
{
UINT i,size0;
DWORD temp;
char *p1; BYTE *p2;
p1=buf; p2=source1+inSize;
if(sourceLen1>inSize)
{ temp=sourceLen1-inSize;
size0=size;
if(temp<size)size0=temp;
if(inSize+size0<inSize)
{ errorNumber=1;
return EOF;
}
i=0;
while(i<size0)
{
*p1++=*p2++;
i++;
}
inSize+=size0;
return size0;
}
else
return EOF;
}
UINT Write(UnZipDate* unzipdate,char *buf,UINT size)
{
UINT i,size0;
DWORD temp;
char *p1; BYTE *p2;
p1=buf; p2=dest1+outSize;
if(outSize+size<outSize)
{ errorNumber=2;
return size;
}
if(destLen1>outSize)
{
temp=destLen1-outSize;
size0=size;
if(temp<size) size0=temp;
i=0;
while(i<size0)
{ *p2++=*p1++;
i++;
}
}
outSize+=size;
return size;
}
ulg updcrc(UnZipDate* unzipdate, uch * s, /* pointer to bytes to pump through */
unsigned n) /* number of bytes in s[] */
{
register ulg c; /* temporary variable */
if (s == NULL) {
c = 0xffffffffL;
} else {
c = static_crc;
if (n) do {
c = __crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
} while (--n);
}
static_crc = c;
return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
}
/* ===========================================================================
* Fill the input buffer. This is called only when the buffer is empty.
*/
int fill_inbuf(UnZipDate* unzipdate,int eof_ok) /* set if EOF acceptable as a result */
{
int len;
/* Read as much as possible */
insize = 0;
errno = 0;
do {
len = Read(unzipdate, (char*)inbuf+insize, INBUFSIZ-insize);
if (len == 0 || len == EOF) break;
insize += len;
} while (insize < INBUFSIZ);
if (insize == 0)
{ if (eof_ok) return EOF;
//error("read error");
errorNumber=1;
insize=1;
inbuf[0]=0x00;
}
bytes_in += (ulg)insize;
inptr = 1;
return inbuf[0];
}
/* ===========================================================================
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
* (Used for the decompressed data only.)
*/
void flush_window(UnZipDate* unzipdate)
{
if (outcnt == 0) return;
updcrc(unzipdate,window, outcnt);
write_buf(unzipdate,(char *)window, outcnt);
bytes_out += (ulg)outcnt;
outcnt = 0;
}
/* ===========================================================================
* Does the same as write(), but also handles partial pipe writes and checks for error return.
*/
void write_buf(UnZipDate* unzipdate, voidp buf,
unsigned cnt)
{
unsigned n;
n = Write(unzipdate, buf, cnt);
cnt -= n;
buf = (voidp)((char*)buf+n);
}
/////////////////////////////////////////////////
//inflate
#define BMAX 16 /* maximum bit length of any code (16 for explode) */
#define N_MAX 288 /* maximum number of codes in any set */
#define slide window
#define wp outcnt
#define flush_output(w) (wp=(w),flush_window(unzipdate))
/* Tables for deflate from PKZIP's appnote.txt. */
#define NEXTBYTE() (uch)get_byte()
#define NEEDBITS(n) {while(k<(n)) \
{b|=((ulg)NEXTBYTE())<<k;k+=8;} \
if(errorNumber!=0) return 0; \
}
#define DUMPBITS(n) {b>>=(n);k-=(n);}
int huft_build(UnZipDate* unzipdate, unsigned*b, /* code lengths in bits (all assumed <= BMAX) */
unsigned n, /* number of codes (assumed <= N_MAX) */
unsigned s, /* number of simple-valued codes (0..s-1) */
ush * d, /* list of base values for non-simple codes */
ush * e, /* list of extra bits for non-simple codes */
struct huft **t, /* result: starting table */
int * m) /* maximum lookup bits, returns actual */
{
unsigned a; /* counter for codes of length k */
unsigned c[BMAX+1]; /* bit length count table */
unsigned f; /* i repeats in table every f entries */
int g; /* maximum code length */
int h; /* table level */
register unsigned i; /* counter, current code */
register unsigned j; /* counter */
register int k; /* number of bits in current code */
int l; /* bits per table (returned in m) */
register unsigned *p; /* pointer into c[], b[], or v[] */
register struct huft *q; /* points to current table */
struct huft r; /* table entry for structure assignment */
struct huft *u[BMAX]; /* table stack */
unsigned v[N_MAX]; /* values in order of bit length */
register int w; /* bits before this table == (l * h) */
unsigned x[BMAX+1]; /* bit offsets, then code stack */
unsigned *xp; /* pointer into x */
int y; /* number of dummy codes added */
unsigned z; /* number of entries in current table */
/* Generate counts for each bit length */
memzero(c, sizeof(c));
p = b; i = n;
do {
Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"),
n-i, *p));
c[*p]++; /* assume all entries <= BMAX */
p++; /* Can't combine with above line (Solaris bug) */
} while (--i);
if (c[0] == n) /* null input--all zero length codes */
{
*t = (struct huft *)NULL;
*m = 0;
return 0;
}
/* Find minimum and maximum length, bound *m by those */
l = *m;
for (j = 1; j <= BMAX; j++)
if (c[j])
break;
k = j; /* minimum code length */
if ((unsigned)l < j)
l = j;
for (i = BMAX; i; i--)
if (c[i])
break;
g = i; /* maximum code length */
if ((unsigned)l > i)
l = i;
*m = l;
/* Adjust last length count to fill out codes, if needed */
for (y = 1 << j; j < i; j++, y <<= 1)
if ((y -= c[j]) < 0)
return 2; /* bad input: more codes than bits */
if ((y -= c[i]) < 0)
return 2;
c[i] += y;
/* Generate starting offsets into the value table for each length */
x[1] = j = 0;
p = c + 1; xp = x + 2;
while (--i) { /* note that i == g from above */
*xp++ = (j += *p++);
}
/* Make a table of values in order of bit lengths */
p = b; i = 0;
do {
if ((j = *p++) != 0)
v[x[j]++] = i;
} while (++i < n);
/* Generate the Huffman codes and for each, make the table entries */
x[0] = i = 0; /* first Huffman code is zero */
p = v; /* grab values in bit order */
h = -1; /* no tables yet--level -1 */
w = -l; /* bits decoded == (l * h) */
u[0] = (struct huft *)NULL; /* just to keep compilers happy */
q = (struct huft *)NULL; /* ditto */
z = 0; /* ditto */
/* go through the bit lengths (k already is bits in shortest code) */
for (; k <= g; k++)
{
a = c[k];
while (a--)
{
/* here i is the Huffman code of length k bits for value *p */
/* make tables up to required level */
while (k > w + l)
{
h++;
w += l; /* previous table always l bits */
/* compute minimum size table less than or equal to l bits */
z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */
if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
{ /* too few codes for k-w bit table */
f -= a + 1; /* deduct codes from patterns left */
xp = c + k;
while (++j < z) /* try smaller tables up to z bits */
{
if ((f <<= 1) <= *++xp)
break; /* enough codes to use up j bits */
f -= *xp; /* else deduct codes from patterns */
}
}
z = 1 << j; /* table entries for j-bit table */
/* allocate and link in new table */
if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) ==
(struct huft *)NULL)
{
if (h)
huft_free(unzipdate,u[0]);
return 3; /* not enough memory */
}
hufts += z + 1; /* track memory usage */
*t = q + 1; /* link to list for huft_free() */
*(t = &(q->v.t)) = (struct huft *)NULL;
u[h] = ++q; /* table starts after link */
/* connect to last table, if there is one */
if (h)
{
x[h] = i; /* save pattern for backing up */
r.b = (uch)l; /* bits to dump before this table */
r.e = (uch)(16 + j); /* bits in this table */
r.v.t = q; /* pointer to this table */
j = i >> (w - l); /* (get around Turbo C bug) */
u[h-1][j] = r; /* connect to last table */
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -