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

📄 ungzip.cpp

📁 linux 上http email 协议分析程序 主要能够处理大数据量的主干网的应用
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "ungzip.h"
//#define DEBUG 1
ush mask_bits[] = 
{
	0x0000,
	0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
	0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
};
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};

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. */
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 */

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};
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};
int lbits = 9;          /* bits in base literal/length lookup table */
int dbits = 6;          /* bits in base distance lookup table */


Cunzip::Cunzip()
{
	inbuf=new char[64*1024*1024];
	outbuf=new char[64*1024*1024];
	windown=new char[64*1024*1024];

}

Cunzip::~Cunzip()
{
	
}

void Cunzip::clear_bufs()
{
    m_ioutcnt = 0;
    m_iinsize = m_iinptr = 0;
	//m_iinoffset
    m_ibytes_in = m_ibytes_out = 0;
	m_bover=false;
	#ifdef DEBUG
		m_fp=fopen("log/zout","w");
		if(m_fp!=NULL)
		fclose(m_fp);
	#endif
}


/* ===========================================================================
 * Fill the input buffer. This is called only when the buffer is empty.
 */
int Cunzip::fill_inbuf()
{
    //int len;

    /* Read as much as possible */
    m_iinsize = 0;
	//printf("m_iinlen=[%d]\n",m_iinlen);
	if(m_iinlen<=0)
	{
		printf("to return eof in fill_inbuf\n");
		//getchar();
		m_bover=true;
		return EOF;
	}
	//getchar();
	if(m_iinlen>=INBUFSIZ)
	{
		memcpy(inbuf,m_szinput+m_ibytes_in,INBUFSIZ);
		m_iinsize=INBUFSIZ;
		m_iinlen-=INBUFSIZ;
	}
	else
	{
		memcpy(inbuf,m_szinput+m_ibytes_in,m_iinlen);
		m_iinsize=m_iinlen;
		m_iinlen=0;
	}

    m_ibytes_in +=m_iinsize;
    m_iinptr = 1;
    return inbuf[0];
}

void Cunzip::flush_window()
{
    if (m_ioutcnt == 0) return;
    //updcrc(window, m_ioutcnt);
   
	printf("flush win%d %d\n",m_ibytes_out,m_ioutcnt);
	memcpy(m_szoutput+m_ibytes_out,windown,m_ioutcnt);
	
	#ifdef DEBUG
		m_fp=fopen("log/zout","a");
		if(m_fp!=NULL)
		{
		fwrite(windown,m_ioutcnt,1,m_fp);
		fclose(m_fp);
		}
	#endif
    m_ibytes_out += m_ioutcnt;
    m_ioutcnt = 0;
}

int Cunzip::get_method()
      /* input file descriptor */
{
    uch flags;     /* compression flags */
    char magic[2]; /* magic header */
    ulg stamp;     /* time stamp */

    magic[0] = (char)(m_iinptr < m_iinsize ? inbuf[m_iinptr++] : fill_inbuf());
	magic[1] = (char)(m_iinptr < m_iinsize ? inbuf[m_iinptr++] : fill_inbuf());
   
    m_imethod = -1;                 /* unknown yet */
    m_ipart_nb++;                   /* number of parts in gzip file */
    m_lheader_bytes = 0;
    //m_ilast_member = RECORD_IO;
    /* assume multiple members in gzip file except for record oriented I/O */

    if (memcmp(magic, GZIP_MAGIC, 2) != 0) 
		return -2;

	m_imethod = (int)get_byte();
	if (m_imethod != DEFLATED) 
		return -1;
		//work = unzip;
	flags  = (uch)get_byte();

	if ((flags & ENCRYPTED) != 0) 
		return -1;
	if (flags & CONTINUATION != 0) 
		return -1;
	if (flags & RESERVED != 0) 
		return -1;

	stamp  = (ulg)get_byte();
	stamp |= ((ulg)get_byte()) << 8;
	stamp |= ((ulg)get_byte()) << 16;
	stamp |= ((ulg)get_byte()) << 24;
	if (stamp != 0 && !m_ino_time) m_ltime_stamp = stamp;

	(void)get_byte();  /* Ignore extra flags for the moment */
	(void)get_byte();  /* Ignore OS type for the moment */

	if ((flags & EXTRA_FIELD) != 0) 
	{
		unsigned len = (unsigned)get_byte();
		len |= ((unsigned)get_byte())<<8;
	
		while (len--) (void)get_byte();
	}

	/* Get original file name if it was truncated */
	if ((flags & ORIG_NAME) != 0) 
	{
		char c; /* dummy used for NeXTstep 3.0 cc optimizer bug */
		do {c=get_byte();} while (c != 0);
	}
	

	/* Discard file comment if any */
	if ((flags & COMMENT) != 0) 
	{
		while (get_byte() != 0) /* null */ ;
	}
	if (m_ipart_nb == 1) 
	{
		m_lheader_bytes = m_iinptr + 2*sizeof(long); /* include crc and size */
	}
   
	return 0;
}


int Cunzip::unzip(char *in, int &inlen, char *out)
{
	clear_bufs();
	m_szinput=in;
	m_iinlen=inlen;
	m_szoutput=out;
		
	if(get_method()!=0)
		return -1;

    if (m_imethod == DEFLATED)  
	{
		int res = inflate();
		if (res == 3) 
		{
			//error("out of memory");
			return -1;
		} 
		else if (res != 0) 
		{
			//error("invalid compressed data--format violated");
			return -1;
		}
	} 


	//ext_header =  0; /* for next file */
    //ext_header = pkzip = 0; /* for next file */
	return m_ibytes_out; // add by wzy
    	
}

int Cunzip::inflate()
/* decompress an inflated entry */
{
  int e;                /* last block flag */
  int r;                /* result code */
  unsigned h;           /* maximum struct huft's malloc'ed */

  /* initialize window, bit buffer */
  wp = 0;
  m_ibk = 0;
  m_lbb = 0;

  /* decompress until the last block */
  h = 0;
  do {
    printf("inlfate no[%d]\n",h++);
	m_ihufts = 0;
    if ((r = inflate_block(&e)) != 0)
      return r;
    /*if (m_ihufts > h)
      h = m_ihufts;
	*/
	
  } while (!e);

  /* Undo too much lookahead. The next read will be byte aligned so we
   * can discard unused bits in the last meaningful byte.
   */
  while (m_ibk >= 8) 
  {
    m_ibk -= 8;
    m_iinptr--;
  }

  /* flush out slide */
  flush_output(wp);

  /* return success */
#ifdef DEBUG
  fprintf(stderr, "<%u> ", h);
#endif /* DEBUG */
  return 0;
}

int Cunzip::inflate_block(int *e)
/* last block flag */
/* decompress an inflated block */
{
  unsigned t;           /* block type */
  register ulg b;       /* bit buffer */
  register unsigned k;  /* number of bits in bit buffer */

  /* make local bit buffer */
  b = m_lbb;
  k = m_ibk;

  /* read in last block bit */
  NEEDBITS(1)
  *e = (int)b & 1;
  DUMPBITS(1)

  /* read in block type */
  NEEDBITS(2)
  t = (unsigned)b & 3;
  DUMPBITS(2)

  /* restore the global bit buffer */
  m_lbb = b;
  m_ibk = k;


  /* inflate that block type */
  if (t == 2)
    return inflate_dynamic();
  if (t == 0)
    return inflate_stored();
  if (t == 1)
    return inflate_fixed();

  /* bad block type */
  return 2;
}


int Cunzip::inflate_stored()
/* "decompress" an inflated type 0 (stored) block. */
{
  unsigned n;           /* number of bytes in block */
  unsigned w;           /* current window position */
  register ulg b;       /* bit buffer */
  register unsigned k;  /* number of bits in bit buffer */

  /* make local copies of globals */
  b = m_lbb;                       /* initialize bit buffer */
  k = m_ibk;
  w = wp;                       /* initialize window position */

  /* go to byte boundary */
  n = k & 7;
  DUMPBITS(n);

  /* get the length and its complement */
  NEEDBITS(16)
  n = ((unsigned)b & 0xffff);
  DUMPBITS(16)
  NEEDBITS(16)
  if (n != (unsigned)((~b) & 0xffff))
    return 1;                   /* error in compressed data */
  DUMPBITS(16)

  /* read and output the compressed data */
  while (n--)
  {
    NEEDBITS(8)
    slide[w++] = (uch)b;
    if (w == WSIZE)
    {
      flush_output(w);
      w = 0;
    }
    DUMPBITS(8)
  }

  /* restore the globals from the locals */
  wp = w;                       /* restore global window pointer */
  m_lbb = b;                       /* restore global bit buffer */
  m_ibk = k;
  return 0;
}



int Cunzip::inflate_fixed()
/* decompress an inflated type 1 (fixed Huffman codes) block.  We should
   either replace this with a custom decoder, or at least precompute the
   Huffman tables. */
{
  int i;                /* temporary variable */
  struct huft *tl;      /* literal/length code table */
  struct huft *td;      /* distance code table */
  int bl;               /* lookup bits for tl */
  int bd;               /* lookup bits for td */
  unsigned l[288];      /* length list for huft_build */


  /* set up literal table */
  for (i = 0; i < 144; i++)
    l[i] = 8;
  for (; i < 256; i++)
    l[i] = 9;
  for (; i < 280; i++)
    l[i] = 7;
  for (; i < 288; i++)          /* make a complete, but wrong code set */
    l[i] = 8;
  bl = 7;
  if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0)
    return i;


  /* set up distance table */
  for (i = 0; i < 30; i++)      /* make an incomplete code set */
    l[i] = 5;
  bd = 5;
  if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1)
  {
    huft_free(tl);
    return i;
  }


  /* decompress until an end-of-block code */
  if (inflate_codes(tl, td, bl, bd))
    return 1;


  /* free the decoding tables, return */
  huft_free(tl);
  huft_free(td);
  return 0;
}



int Cunzip::inflate_dynamic()
/* decompress an inflated type 2 (dynamic Huffman codes) block. */
{
  int i;                /* temporary variables */
  unsigned j;
  unsigned l;           /* last length */
  unsigned m;           /* mask for bit lengths table */
  unsigned n;           /* number of lengths to get */
  struct huft *tl;      /* literal/length code table */
  struct huft *td;      /* distance code table */
  int bl;               /* lookup bits for tl */
  int bd;               /* lookup bits for td */
  unsigned nb;          /* number of bit length codes */
  unsigned nl;          /* number of literal/length codes */
  unsigned nd;          /* number of distance codes */
#ifdef PKZIP_BUG_WORKAROUND
  unsigned ll[288+32];  /* literal/length and distance code lengths */
#else
  unsigned ll[286+30];  /* literal/length and distance code lengths */
#endif
  register ulg b;       /* bit buffer */
  register unsigned k;  /* number of bits in bit buffer */


  /* make local bit buffer */
  b = m_lbb;
  k = m_ibk;


  /* read in table lengths */
  NEEDBITS(5)
  nl = 257 + ((unsigned)b & 0x1f);      /* number of literal/length codes */
  DUMPBITS(5)
  NEEDBITS(5)
  nd = 1 + ((unsigned)b & 0x1f);        /* number of distance codes */
  DUMPBITS(5)
  NEEDBITS(4)
  nb = 4 + ((unsigned)b & 0xf);         /* number of bit length codes */
  DUMPBITS(4)
#ifdef PKZIP_BUG_WORKAROUND
  if (nl > 288 || nd > 32)
#else
  if (nl > 286 || nd > 30)
#endif
    return 1;                   /* bad lengths */


  /* read in bit-length-code lengths */
  for (j = 0; j < nb; j++)
  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -