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

📄 xdelta3-decode.h

📁 Linux下一个可以比较二进制文件的工具xdelta3.0u的源码。
💻 H
📖 第 1 页 / 共 2 页
字号:
  /* The window may be entirely processed. */  XD3_ASSERT (stream->dec_winbytes <= need);  /* Compute how much more input is needed. */  more = (need - stream->dec_winbytes);  /* How much to consume. */  take = min (more, stream->avail_in);  /* See if the input is completely available, to avoid copy. */  copy = (take != more);  /* If the window is skipped... */  if ((stream->flags & XD3_SKIP_WINDOW) != 0)    {      /* Skip the available input. */      DECODE_INPUT (take);      stream->dec_winbytes += take;      if (copy)	{	  stream->msg = "further input required";	  return XD3_INPUT;	}      return xd3_decode_finish_window (stream);    }  /* Process all but the DATA section. */  switch (stream->dec_state)    {    default:      stream->msg = "internal error";      return XD3_INVALID_INPUT;    case DEC_DATA:      if ((ret = xd3_decode_section (stream, & stream->data_sect,				     DEC_INST, copy))) { return ret; }    case DEC_INST:      if ((ret = xd3_decode_section (stream, & stream->inst_sect,				     DEC_ADDR, copy))) { return ret; }    case DEC_ADDR:      if ((ret = xd3_decode_section (stream, & stream->addr_sect,				     DEC_EMIT, copy))) { return ret; }    }  XD3_ASSERT (stream->dec_winbytes == need);  if ((ret = xd3_decode_secondary_sections (stream))) { return ret; }  if (stream->flags & XD3_SKIP_EMIT)    {      return xd3_decode_finish_window (stream);    }  /* OPT: A possible optimization is to avoid allocating memory in   * decode_setup_buffers and to avoid a large memcpy when the window   * consists of a single VCD_SOURCE copy instruction.  The only   * potential problem is if the following window is a VCD_TARGET,   * then you need to remember... */  if ((ret = xd3_decode_setup_buffers (stream))) { return ret; }  return 0;}static intxd3_decode_emit (xd3_stream *stream){  int ret;  /* Produce output: originally structured to allow reentrant code   * that fills as much of the output buffer as possible, but VCDIFF   * semantics allows to copy from anywhere from the target window, so   * instead allocate a sufficiently sized buffer after the target   * window length is decoded.   *   * This code still needs to be reentrant to allow XD3_GETSRCBLK to   * return control.  This is handled by setting the   * stream->dec_currentN instruction types to XD3_NOOP after they   * have been processed. */  XD3_ASSERT (! (stream->flags & XD3_SKIP_EMIT));  XD3_ASSERT (stream->dec_tgtlen <= stream->space_out);  while (stream->inst_sect.buf != stream->inst_sect.buf_max ||	 stream->dec_current1.type != XD3_NOOP ||	 stream->dec_current2.type != XD3_NOOP)    {      /* Decode next instruction pair. */      if ((stream->dec_current1.type == XD3_NOOP) &&	  (stream->dec_current2.type == XD3_NOOP) &&	  (ret = xd3_decode_instruction (stream))) { return ret; }      /* Output for each instruction. */      if ((stream->dec_current1.type != XD3_NOOP) &&	  (ret = xd3_decode_output_halfinst (stream, & stream->dec_current1)))	{	  return ret;	}      if ((stream->dec_current2.type != XD3_NOOP) &&	  (ret = xd3_decode_output_halfinst (stream, & stream->dec_current2)))	{	  return ret;	}    }  if (stream->avail_out != stream->dec_tgtlen)    {      IF_DEBUG1 (DP(RINT "AVAIL_OUT(%d) != DEC_TGTLEN(%d)\n",		    stream->avail_out, stream->dec_tgtlen));      stream->msg = "wrong window length";      return XD3_INVALID_INPUT;    }  if (stream->data_sect.buf != stream->data_sect.buf_max)    {      stream->msg = "extra data section";      return XD3_INVALID_INPUT;    }  if (stream->addr_sect.buf != stream->addr_sect.buf_max)    {      stream->msg = "extra address section";      return XD3_INVALID_INPUT;    }  /* OPT: Should cksum computation be combined with the above loop? */  if ((stream->dec_win_ind & VCD_ADLER32) != 0 &&      (stream->flags & XD3_ADLER32_NOVER) == 0)    {      uint32_t a32 = adler32 (1L, stream->next_out, stream->avail_out);      if (a32 != stream->dec_adler32)	{	  stream->msg = "target window checksum mismatch";	  return XD3_INVALID_INPUT;	}    }  /* Finished with a window. */  return xd3_decode_finish_window (stream);}intxd3_decode_input (xd3_stream *stream){  int ret;  if (stream->enc_state != 0)    {      stream->msg = "encoder/decoder transition";      return XD3_INVALID_INPUT;    }#define BYTE_CASE(expr,x,nstate) \      do { \      if ( (expr) && \           ((ret = xd3_decode_byte (stream, & (x))) != 0) ) { return ret; } \      stream->dec_state = (nstate); \      } while (0)#define OFFSET_CASE(expr,x,nstate) \      do { \      if ( (expr) && \           ((ret = xd3_decode_offset (stream, & (x))) != 0) ) { return ret; } \      stream->dec_state = (nstate); \      } while (0)#define SIZE_CASE(expr,x,nstate) \      do { \      if ( (expr) && \           ((ret = xd3_decode_size (stream, & (x))) != 0) ) { return ret; } \      stream->dec_state = (nstate); \      } while (0)  switch (stream->dec_state)    {    case DEC_VCHEAD:      {	if ((ret = xd3_decode_bytes (stream, stream->dec_magic,				     & stream->dec_magicbytes, 4)))	  {	    return ret;	  }	if (stream->dec_magic[0] != VCDIFF_MAGIC1 ||	    stream->dec_magic[1] != VCDIFF_MAGIC2 ||	    stream->dec_magic[2] != VCDIFF_MAGIC3)	  {	    stream->msg = "not a VCDIFF input";	    return XD3_INVALID_INPUT;	  }	if (stream->dec_magic[3] != 0)	  {	    stream->msg = "VCDIFF input version > 0 is not supported";	    return XD3_INVALID_INPUT;	  }	stream->dec_state = DEC_HDRIND;      }    case DEC_HDRIND:      {	if ((ret = xd3_decode_byte (stream, & stream->dec_hdr_ind)))	  {	    return ret;	  }	if ((stream->dec_hdr_ind & VCD_INVHDR) != 0)	  {	    stream->msg = "unrecognized header indicator bits set";	    return XD3_INVALID_INPUT;	  }	stream->dec_state = DEC_SECONDID;      }    case DEC_SECONDID:      /* Secondary compressor ID: only if VCD_SECONDARY is set */      if ((stream->dec_hdr_ind & VCD_SECONDARY) != 0)	{	  BYTE_CASE (1, stream->dec_secondid, DEC_TABLEN);	  switch (stream->dec_secondid)	    {	    case VCD_FGK_ID:	      FGK_CASE (stream);	    case VCD_DJW_ID:	      DJW_CASE (stream);	    default:	      stream->msg = "unknown secondary compressor ID";	      return XD3_INVALID_INPUT;	    }	}    case DEC_TABLEN:      /* Length of code table data: only if VCD_CODETABLE is set */      SIZE_CASE ((stream->dec_hdr_ind & VCD_CODETABLE) != 0,		 stream->dec_codetblsz, DEC_NEAR);      /* The codetblsz counts the two NEAR/SAME bytes */      if ((stream->dec_hdr_ind & VCD_CODETABLE) != 0) {	if (stream->dec_codetblsz <= 2) {	  stream->msg = "invalid code table size";	  return ENOMEM;	}	stream->dec_codetblsz -= 2;      }    case DEC_NEAR:      /* Near modes: only if VCD_CODETABLE is set */      BYTE_CASE((stream->dec_hdr_ind & VCD_CODETABLE) != 0,		stream->acache.s_near, DEC_SAME);    case DEC_SAME:      /* Same modes: only if VCD_CODETABLE is set */      BYTE_CASE((stream->dec_hdr_ind & VCD_CODETABLE) != 0,		stream->acache.s_same, DEC_TABDAT);    case DEC_TABDAT:      /* Compressed code table data */      if ((stream->dec_hdr_ind & VCD_CODETABLE) != 0)	{	  /* Get the code table data. */	  if ((stream->dec_codetbl == NULL) &&	      (stream->dec_codetbl =	       (uint8_t*) xd3_alloc (stream,				     stream->dec_codetblsz, 1)) == NULL)	    {	      return ENOMEM;	    }	  if ((ret = xd3_decode_bytes (stream, stream->dec_codetbl,				       & stream->dec_codetblbytes,				       stream->dec_codetblsz)))	    {	      return ret;	    }	  if ((ret = xd3_apply_table_encoding (stream, stream->dec_codetbl,					       stream->dec_codetblbytes)))	    {	      return ret;	    }	}      else	{	  /* Use the default table. */	  stream->acache.s_near = __rfc3284_code_table_desc.near_modes;	  stream->acache.s_same = __rfc3284_code_table_desc.same_modes;	  stream->code_table    = xd3_rfc3284_code_table ();	}      if ((ret = xd3_alloc_cache (stream))) { return ret; }      stream->dec_state = DEC_APPLEN;    case DEC_APPLEN:      /* Length of application data */      SIZE_CASE((stream->dec_hdr_ind & VCD_APPHEADER) != 0,		stream->dec_appheadsz, DEC_APPDAT);    case DEC_APPDAT:      /* Application data */      if (stream->dec_hdr_ind & VCD_APPHEADER)	{	  /* Note: we add an additional byte for padding, to allow	     0-termination. */	  if ((stream->dec_appheader == NULL) &&	      (stream->dec_appheader =	       (uint8_t*) xd3_alloc (stream,				     stream->dec_appheadsz+1, 1)) == NULL)	    {	      return ENOMEM;	    }	  stream->dec_appheader[stream->dec_appheadsz] = 0;	  if ((ret = xd3_decode_bytes (stream, stream->dec_appheader,				       & stream->dec_appheadbytes,				       stream->dec_appheadsz)))	    {	      return ret;	    }	}      stream->dec_hdrsize = stream->total_in;      stream->dec_state = DEC_WININD;    case DEC_WININD:      {	/* Start of a window: the window indicator */	if ((ret = xd3_decode_byte (stream, & stream->dec_win_ind)))	  {	    return ret;	  }	stream->current_window = stream->dec_window_count;	if (XOFF_T_OVERFLOW (stream->dec_winstart, stream->dec_tgtlen))	  {	    stream->msg = "decoder file offset overflow";	    return XD3_INVALID_INPUT;	  }	stream->dec_winstart += stream->dec_tgtlen;	if ((stream->dec_win_ind & VCD_INVWIN) != 0)	  {	    stream->msg = "unrecognized window indicator bits set";	    return XD3_INVALID_INPUT;	  }	if ((ret = xd3_decode_init_window (stream))) { return ret; }	stream->dec_state = DEC_CPYLEN;	IF_DEBUG1 (DP(RINT "--------- TARGET WINDOW %"Q"u -----------\n",		      stream->current_window));      }    case DEC_CPYLEN:      /* Copy window length: only if VCD_SOURCE or VCD_TARGET is set */      SIZE_CASE(SRCORTGT (stream->dec_win_ind), stream->dec_cpylen,		DEC_CPYOFF);      /* Set the initial, logical decoder position (HERE address) in       * dec_position.  This is set to just after the source/copy       * window, as we are just about to output the first byte of       * target window. */      stream->dec_position = stream->dec_cpylen;    case DEC_CPYOFF:      /* Copy window offset: only if VCD_SOURCE or VCD_TARGET is set */      OFFSET_CASE(SRCORTGT (stream->dec_win_ind), stream->dec_cpyoff,		  DEC_ENCLEN);      /* Copy offset and copy length may not overflow. */      if (XOFF_T_OVERFLOW (stream->dec_cpyoff, stream->dec_cpylen))	{	  stream->msg = "decoder copy window overflows a file offset";	  return XD3_INVALID_INPUT;	}      /* Check copy window bounds: VCD_TARGET window may not exceed	 current position. */      if ((stream->dec_win_ind & VCD_TARGET) &&	  (stream->dec_cpyoff + (xoff_t) stream->dec_cpylen >	   stream->dec_winstart))	{	  stream->msg = "VCD_TARGET window out of bounds";	  return XD3_INVALID_INPUT;	}    case DEC_ENCLEN:      /* Length of the delta encoding */      SIZE_CASE(1, stream->dec_enclen, DEC_TGTLEN);    case DEC_TGTLEN:      /* Length of target window */      SIZE_CASE(1, stream->dec_tgtlen, DEC_DELIND);      /* Set the maximum decoder position, beyond which we should not       * decode any data.  This is the maximum value for dec_position.       * This may not exceed the size of a usize_t. */      if (USIZE_T_OVERFLOW (stream->dec_cpylen, stream->dec_tgtlen))	{	  stream->msg = "decoder target window overflows a usize_t";	  return XD3_INVALID_INPUT;	}      /* Check for malicious files. */      if (stream->dec_tgtlen > XD3_HARDMAXWINSIZE)	{	  stream->msg = "hard window size exceeded";	  return XD3_INVALID_INPUT;	}      stream->dec_maxpos = stream->dec_cpylen + stream->dec_tgtlen;    case DEC_DELIND:      /* Delta indicator */      BYTE_CASE(1, stream->dec_del_ind, DEC_DATALEN);      if ((stream->dec_del_ind & VCD_INVDEL) != 0)	{	  stream->msg = "unrecognized delta indicator bits set";	  return XD3_INVALID_INPUT;	}      /* Delta indicator is only used with secondary compression. */      if ((stream->dec_del_ind != 0) && (stream->sec_type == NULL))	{	  stream->msg = "invalid delta indicator bits set";	  return XD3_INVALID_INPUT;	}      /* Section lengths */    case DEC_DATALEN:      SIZE_CASE(1, stream->data_sect.size, DEC_INSTLEN);    case DEC_INSTLEN:      SIZE_CASE(1, stream->inst_sect.size, DEC_ADDRLEN);    case DEC_ADDRLEN:      SIZE_CASE(1, stream->addr_sect.size, DEC_CKSUM);    case DEC_CKSUM:      /* Window checksum. */      if ((stream->dec_win_ind & VCD_ADLER32) != 0)	{	  int i;	  if ((ret = xd3_decode_bytes (stream, stream->dec_cksum,				       & stream->dec_cksumbytes, 4)))	    {	      return ret;	    }	  for (i = 0; i < 4; i += 1)	    {	      stream->dec_adler32 =		(stream->dec_adler32 << 8) | stream->dec_cksum[i];	    }	}      stream->dec_state = DEC_DATA;      /* Check dec_enclen for redundency, otherwise it is not really used. */      {	usize_t enclen_check =	  (1 + (xd3_sizeof_size (stream->dec_tgtlen) +		xd3_sizeof_size (stream->data_sect.size) +		xd3_sizeof_size (stream->inst_sect.size) +		xd3_sizeof_size (stream->addr_sect.size)) +	   stream->data_sect.size +	   stream->inst_sect.size +	   stream->addr_sect.size +	   ((stream->dec_win_ind & VCD_ADLER32) ? 4 : 0));	if (stream->dec_enclen != enclen_check)	  {	    stream->msg = "incorrect encoding length (redundent)";	    return XD3_INVALID_INPUT;	  }      }      /* Returning here gives the application a chance to inspect the       * header, skip the window, etc. */      if (stream->current_window == 0) { return XD3_GOTHEADER; }      else                             { return XD3_WINSTART; }    case DEC_DATA:    case DEC_INST:    case DEC_ADDR:      /* Next read the three sections. */     if ((ret = xd3_decode_sections (stream))) { return ret; }    case DEC_EMIT:      /* To speed VCD_SOURCE block-address calculations, the source       * cpyoff_blocks and cpyoff_blkoff are pre-computed. */      if (stream->dec_win_ind & VCD_SOURCE)	{	  xd3_source *src = stream->src;	  if (src == NULL)	    {	      stream->msg = "source input required";	      return XD3_INVALID_INPUT;	    }	  xd3_blksize_div(stream->dec_cpyoff, src,			  &src->cpyoff_blocks,			  &src->cpyoff_blkoff);	}      /* xd3_decode_emit returns XD3_OUTPUT on every success. */      if ((ret = xd3_decode_emit (stream)) == XD3_OUTPUT)	{	  stream->total_out += (xoff_t) stream->avail_out;	}      return ret;    case DEC_FINISH:      {	if (stream->dec_win_ind & VCD_TARGET)	  {	    if (stream->dec_lastwin == NULL)	      {		stream->dec_lastwin   = stream->next_out;		stream->dec_lastspace = stream->space_out;	      }	    else	      {		xd3_swap_uint8p (& stream->dec_lastwin,				 & stream->next_out);		xd3_swap_usize_t (& stream->dec_lastspace,				  & stream->space_out);	      }	  }	stream->dec_lastlen   = stream->dec_tgtlen;	stream->dec_laststart = stream->dec_winstart;	stream->dec_window_count += 1;	/* Note: the updates to dec_winstart & current_window are	 * deferred until after the next DEC_WININD byte is read. */	stream->dec_state = DEC_WININD;	return XD3_WINFINISH;      }    default:      stream->msg = "invalid state";      return XD3_INVALID_INPUT;    }}#endif // _XDELTA3_DECODE_H_

⌨️ 快捷键说明

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