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

📄 xdelta3-main.h

📁 Linux下一个可以比较二进制文件的工具xdelta3.0u的源码。
💻 H
📖 第 1 页 / 共 5 页
字号:
// Re-encode one windowstatic intmain_recode_func (xd3_stream* stream, main_file *ofile){  int ret;  xd3_source decode_source;  XD3_ASSERT(stream->dec_state == DEC_FINISH);  XD3_ASSERT(recode_stream->enc_state == ENC_INIT ||	     recode_stream->enc_state == ENC_INPUT);  // Copy partial decoder output to partial encoder inputs  if ((ret = main_recode_copy (recode_stream,			       DATA_HEAD(recode_stream),			       &stream->data_sect)) ||      (ret = main_recode_copy (recode_stream,			       INST_HEAD(recode_stream),			       &stream->inst_sect)) ||      (ret = main_recode_copy (recode_stream,			       ADDR_HEAD(recode_stream),			       &stream->addr_sect)))    {      return ret;    }  // This jumps to xd3_emit_hdr()  recode_stream->enc_state = ENC_FLUSH;  recode_stream->avail_in = stream->dec_tgtlen;  if (SRCORTGT (stream->dec_win_ind))    {      recode_stream->src = & decode_source;      decode_source.srclen = stream->dec_cpylen;      decode_source.srcbase = stream->dec_cpyoff;    }  if (option_use_checksum &&      (stream->dec_win_ind & VCD_ADLER32) != 0)    {      recode_stream->flags |= XD3_ADLER32_RECODE;      recode_stream->recode_adler32 = stream->dec_adler32;    }  if (option_use_appheader != 0 &&      option_appheader != NULL)    {      xd3_set_appheader (recode_stream, option_appheader,			 strlen ((char*) option_appheader));    }  else if (option_use_appheader != 0 &&	   option_appheader == NULL)    {      if (stream->dec_appheader != NULL)	{	  xd3_set_appheader (recode_stream,			     stream->dec_appheader, stream->dec_appheadsz);	}    }  // Output loop  for (;;)    {      switch((ret = xd3_encode_input (recode_stream)))	{	case XD3_INPUT: {	  /* finished recoding one window */	  stream->total_out = recode_stream->total_out;	  return 0;	}	case XD3_OUTPUT: {	  /* main_file_write below */	  break;	}	case XD3_GOTHEADER:	case XD3_WINSTART:	case XD3_WINFINISH: {	  /* ignore */	  continue;	}	case XD3_GETSRCBLK:	case 0: {	    return XD3_INTERNAL;	  }	default:	  return ret;	}      if ((ret = main_write_output (recode_stream, ofile)))	{	  return ret;	}      xd3_consume_output (recode_stream);    }}#endif /* VCDIFF_TOOLS *//******************************************************************* VCDIFF merging ******************************************************************/#if VCDIFF_TOOLS/* Modifies static state. */static intmain_init_recode_stream (void){  int ret;  int stream_flags = XD3_ADLER32_NOVER | XD3_SKIP_EMIT;  int recode_flags;  xd3_config recode_config;  XD3_ASSERT (recode_stream == NULL);  if ((recode_stream = (xd3_stream*) main_malloc(sizeof(xd3_stream))) == NULL)    {      return ENOMEM;    }  recode_flags = (stream_flags & XD3_SEC_TYPE);  recode_config.alloc = main_alloc;  recode_config.freef = main_free1;  xd3_init_config(&recode_config, recode_flags);  if ((ret = main_set_secondary_flags (&recode_config)) ||      (ret = xd3_config_stream (recode_stream, &recode_config)) ||      (ret = xd3_encode_init_partial (recode_stream)) ||      (ret = xd3_whole_state_init (recode_stream)))    {      XPR(NT XD3_LIB_ERRMSG (recode_stream, ret));      xd3_free_stream (recode_stream);      recode_stream = NULL;      return ret;    }  return 0;}/* This processes the sequence of -m arguments.  The final input * is processed as part of the ordinary main_input() loop. */static intmain_merge_arguments (main_merge_list* merges){  int ret = 0;  int count = 0;  main_merge *merge = NULL;  xd3_stream merge_input;  if (main_merge_list_empty (merges))    {      return 0;    }  if ((ret = xd3_config_stream (& merge_input, NULL)) ||      (ret = xd3_whole_state_init (& merge_input)))     {      XPR(NT XD3_LIB_ERRMSG (& merge_input, ret));      return ret;    }  merge = main_merge_list_front (merges);  while (!main_merge_list_end (merges, merge))    {      main_file mfile;      main_file_init (& mfile);      mfile.filename = merge->filename;      mfile.flags = RD_NONEXTERNAL;      if ((ret = main_file_open (& mfile, merge->filename, XO_READ)))        {          goto error;        }      ret = main_input (CMD_MERGE_ARG, & mfile, NULL, NULL);      if (ret == 0)	{	  if (count++ == 0)	    {	      /* The first merge source is the next merge input. */	      xd3_swap_whole_state (& recode_stream->whole_target, 				    & merge_input.whole_target);	    }	  else	    {	      /* Merge the recode_stream with merge_input. */	      ret = xd3_merge_input_output (recode_stream,					    & merge_input.whole_target);	      /* Save the next merge source in merge_input. */	      xd3_swap_whole_state (& recode_stream->whole_target,				    & merge_input.whole_target);	    }	}      main_file_cleanup (& mfile);      if (recode_stream != NULL)        {          xd3_free_stream (recode_stream);          main_free (recode_stream);          recode_stream = NULL;        }      if (main_bdata != NULL)        {          main_free (main_bdata);          main_bdata = NULL;	  main_bsize = 0;        }      if (ret != 0)        {	  goto error;        }      merge = main_merge_list_next (merge);    }  XD3_ASSERT (merge_stream == NULL);  if ((merge_stream = (xd3_stream*) main_malloc (sizeof(xd3_stream))) == NULL)    {      ret = ENOMEM;      goto error;    }  if ((ret = xd3_config_stream (merge_stream, NULL)) ||      (ret = xd3_whole_state_init (merge_stream)))    {      XPR(NT XD3_LIB_ERRMSG (& merge_input, ret));      goto error;    }  xd3_swap_whole_state (& merge_stream->whole_target, 			& merge_input.whole_target);  ret = 0; error:  xd3_free_stream (& merge_input);  return ret;}/* This processes each window of the final merge input.  This routine * does not output, it buffers the entire delta into memory. */static intmain_merge_func (xd3_stream* stream, main_file *no_write){  int ret;  if ((ret = xd3_whole_append_window (stream)))    {      return ret;    }  return 0;}/* This is called after all windows have been read, as a final step in * main_input().  This is only called for the final merge step. */static intmain_merge_output (xd3_stream *stream, main_file *ofile){  int ret;  usize_t inst_pos = 0;  xoff_t output_pos = 0;  xd3_source recode_source;  usize_t window_num = 0;  int at_least_once = 0;  /* merge_stream is set if there were arguments.  this stream's input   * needs to be applied to the merge_stream source. */  if ((merge_stream != NULL) &&      (ret = xd3_merge_input_output (stream, 				     & merge_stream->whole_target)))    {      XPR(NT XD3_LIB_ERRMSG (stream, ret));      return ret;    }  if (option_use_appheader != 0 &&      option_appheader != NULL)    {      xd3_set_appheader (recode_stream, option_appheader,			 strlen ((char*) option_appheader));    }  /* Enter the ENC_INPUT state and bypass the next_in == NULL test   * and (leftover) input buffering logic. */  XD3_ASSERT(recode_stream->enc_state == ENC_INIT);  recode_stream->enc_state = ENC_INPUT;  recode_stream->next_in = main_bdata;  recode_stream->flags |= XD3_FLUSH;  /* This encodes the entire target. */  while (inst_pos < stream->whole_target.instlen || !at_least_once)    {      xoff_t window_start = output_pos;      int window_srcset = 0;      xoff_t window_srcmin = 0;      xoff_t window_srcmax = 0;      usize_t window_pos = 0;      usize_t window_size;      /* at_least_once ensures that we encode at least one window,       * which handles the 0-byte case. */      at_least_once = 1;      XD3_ASSERT (recode_stream->enc_state == ENC_INPUT);      if ((ret = xd3_encode_input (recode_stream)) != XD3_WINSTART)	{	  XPR(NT "invalid merge state: %s\n", xd3_mainerror (ret));	  return XD3_INVALID;	}      /* Window sizes must match from the input to the output, so that       * target copies are in-range (and so that checksums carry       * over). */      XD3_ASSERT (window_num < stream->whole_target.wininfolen);      window_size = stream->whole_target.wininfo[window_num].length;      /* Output position should also match. */      if (output_pos != stream->whole_target.wininfo[window_num].offset)	{	  XPR(NT "internal merge error: offset mismatch\n");	  return XD3_INVALID;	}      if (option_use_checksum &&	  (stream->dec_win_ind & VCD_ADLER32) != 0) 	{	  recode_stream->flags |= XD3_ADLER32_RECODE;	  recode_stream->recode_adler32 = stream->whole_target.wininfo[window_num].adler32;	}      window_num++;      if (main_bsize < window_size)	{	  main_free (main_bdata);	  main_bdata = NULL;	  main_bsize = 0;	  if ((main_bdata = (uint8_t*) 	       main_malloc (window_size)) == NULL)	    {	      return ENOMEM;	    }	  main_bsize = window_size;	}      /* This encodes a single target window. */      while (window_pos < window_size &&	     inst_pos < stream->whole_target.instlen)	{	  xd3_winst *inst = &stream->whole_target.inst[inst_pos];	  usize_t take = min(inst->size, window_size - window_pos);	  xoff_t addr;	  switch (inst->type)	    {	    case XD3_RUN:	      if ((ret = xd3_emit_run (recode_stream, window_pos, take,				       stream->whole_target.adds[inst->addr])))		{		  return ret;		}	      break;	    case XD3_ADD:	      /* Adds are implicit, put them into the input buffer. */	      memcpy (main_bdata + window_pos, 		      stream->whole_target.adds + inst->addr, take);	      break;	    default: /* XD3_COPY + copy mode */	      if (inst->mode != 0)		{		  if (window_srcset) {		    window_srcmin = min(window_srcmin, inst->addr);		    window_srcmax = max(window_srcmax, inst->addr + take);		  } else {		    window_srcset = 1;		    window_srcmin = inst->addr;		    window_srcmax = inst->addr + take;		  }		  addr = inst->addr;		}	      else 		{		  XD3_ASSERT (inst->addr >= window_start);		  addr = inst->addr - window_start;		}	      IF_DEBUG1 (DP(RINT "[merge copy] winpos %u take %u addr %"Q"u mode %u\n",			    window_pos, take, addr, inst->mode));	      if ((ret = xd3_found_match (recode_stream, window_pos, take, 					  addr, inst->mode != 0)))		{		  return ret;		}	      break;	    }	  window_pos += take;	  output_pos += take;	  if (take == inst->size)	    {	      inst_pos += 1;	    }	  else	    {	      /* Modify the instruction for the next pass. */	      if (inst->type != XD3_RUN)		{		  inst->addr += take;		}	      inst->size -= take;	    }	}      xd3_avail_input (recode_stream, main_bdata, window_pos);      recode_stream->enc_state = ENC_INSTR;      if (window_srcset) {	recode_stream->srcwin_decided = 1;	recode_stream->src = &recode_source;	recode_source.srclen = window_srcmax - window_srcmin;	recode_source.srcbase = window_srcmin;	recode_stream->taroff = recode_source.srclen;      } else {	recode_stream->srcwin_decided = 0;	recode_stream->src = NULL;	recode_stream->taroff = 0;      }      for (;;)	{	  switch ((ret = xd3_encode_input (recode_stream)))	    {	    case XD3_INPUT: {	      goto done_window;	    }	    case XD3_OUTPUT: {	      /* main_file_write below */	      break;	    }	    case XD3_GOTHEADER:	    case XD3_WINSTART:	    case XD3_WINFINISH: {	      /* ignore */	      continue;	    }	    case XD3_GETSRCBLK:	    case 0: {	      return XD3_INTERNAL;	    }	    default:	      return ret;	    }	  if ((ret = main_write_output(recode_stream, ofile)))	    {	      return ret;	    }	  xd3_consume_output (recode_stream);	}    done_window:      (void) 0;    }  return 0;}#endif/******************************************************************* Input decompression, output recompression ******************************************************************/#if EXTERNAL_COMPRESSION/* This is tricky POSIX-specific code with lots of fork(), pipe(), * dup(), waitpid(), and exec() business.  Most of this code * originated in PRCS1, which did automatic package-file * decompression.  It works with both XD3_POSIX and XD3_STDIO file * disciplines. * * To automatically detect compressed inputs requires a child process * to reconstruct the input stream, which was advanced in order to * detect compression, because it may not be seekable.  In other * words, the main program reads part of the input stream, and if it * detects a compressed input it then forks a pipe copier process, * which copies the first-read block out of the main-program's memory, * then streams the remaining compressed input into the * input-decompression pipe. */#include <unistd.h>#include <sys/stat.h>#include <sys/wait.h>/* Remember which pipe FD is which. */#define PIPE_READ_FD  0#define PIPE_WRITE_FD 1static pid_t ext_subprocs[2];

⌨️ 快捷键说明

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