⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unzip.cpp

📁 zip解压源码.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -