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

📄 xdelta3-merge.h

📁 Linux下一个可以比较二进制文件的工具xdelta3.0u的源码。
💻 H
字号:
/* xdelta 3 - delta compression tools and library * Copyright (C) 2007.  Joshua P. MacDonald * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#ifndef _XDELTA3_MERGE_H_#define _XDELTA3_MERGE_H_int xd3_merge_inputs (xd3_stream *stream, 		      xd3_whole_state *source,		      xd3_whole_state *input);static intxd3_whole_state_init (xd3_stream *stream){  XD3_ASSERT (stream->whole_target.adds == NULL);  XD3_ASSERT (stream->whole_target.inst == NULL);  XD3_ASSERT (stream->whole_target.wininfo == NULL);  XD3_ASSERT (stream->whole_target.length == 0);  stream->whole_target.adds_alloc = XD3_ALLOCSIZE;  stream->whole_target.inst_alloc = XD3_ALLOCSIZE;  stream->whole_target.wininfo_alloc = XD3_ALLOCSIZE;  if ((stream->whole_target.adds = (uint8_t*)        xd3_alloc (stream, stream->whole_target.adds_alloc, 1)) == NULL ||      (stream->whole_target.inst = (xd3_winst*)        xd3_alloc (stream, stream->whole_target.inst_alloc, 1)) == NULL ||      (stream->whole_target.wininfo = (xd3_wininfo*)        xd3_alloc (stream, stream->whole_target.wininfo_alloc, 1)) == NULL)    {      return ENOMEM;    }  return 0;}static voidxd3_swap_whole_state (xd3_whole_state *a, 		      xd3_whole_state *b){  xd3_whole_state tmp;  XD3_ASSERT (a->inst != NULL && a->adds != NULL);  XD3_ASSERT (b->inst != NULL && b->adds != NULL);  XD3_ASSERT (b->wininfo != NULL && b->wininfo != NULL);  memcpy (&tmp, a, sizeof (xd3_whole_state));  memcpy (a, b, sizeof (xd3_whole_state));  memcpy (b, &tmp, sizeof (xd3_whole_state));}static intxd3_realloc_buffer (xd3_stream *stream,                    usize_t current_units,                    usize_t unit_size,                    usize_t new_units,                    usize_t *alloc_size,                    void **alloc_ptr){  usize_t needed;  usize_t new_alloc;  usize_t cur_size;  uint8_t *new_buf;  needed = (current_units + new_units) * unit_size;  if (needed <= *alloc_size)    {      return 0;    }  cur_size = current_units * unit_size;  new_alloc = xd3_round_blksize (needed * 2, XD3_ALLOCSIZE);  if ((new_buf = (uint8_t*) xd3_alloc (stream, new_alloc, 1)) == NULL)    {      return ENOMEM;    }  if (cur_size != 0)    {      memcpy (new_buf, *alloc_ptr, cur_size);    }  if (*alloc_ptr != NULL)    {      xd3_free (stream, *alloc_ptr);    }  *alloc_size = new_alloc;  *alloc_ptr = new_buf;  return 0;}/* allocate one new output instruction */static intxd3_whole_alloc_winst (xd3_stream *stream,		       xd3_winst **winstp){  int ret;  if ((ret = xd3_realloc_buffer (stream, 				 stream->whole_target.instlen, 				 sizeof (xd3_winst), 				 1, 				 & stream->whole_target.inst_alloc, 				 (void**) & stream->whole_target.inst)))     {       return ret;     }  *winstp = &stream->whole_target.inst[stream->whole_target.instlen++];  return 0;}static intxd3_whole_alloc_adds (xd3_stream *stream,		      usize_t count){  return xd3_realloc_buffer (stream,			     stream->whole_target.addslen,			     1,			     count,			     & stream->whole_target.adds_alloc,			     (void**) & stream->whole_target.adds);}static intxd3_whole_alloc_wininfo (xd3_stream *stream,			 xd3_wininfo **wininfop){  int ret;  if ((ret = xd3_realloc_buffer (stream, 				 stream->whole_target.wininfolen, 				 sizeof (xd3_wininfo),				 1,				 & stream->whole_target.wininfo_alloc, 				 (void**) & stream->whole_target.wininfo)))     {       return ret;     }  *wininfop = &stream->whole_target.wininfo[stream->whole_target.wininfolen++];  return 0;}static intxd3_whole_append_inst (xd3_stream *stream,                       xd3_hinst *inst){  int ret;  xd3_winst *winst;  if ((ret = xd3_whole_alloc_winst (stream, &winst)))    {      return ret;    }  winst->type = inst->type;  winst->mode = 0;  winst->size = inst->size;  winst->position = stream->whole_target.length;  stream->whole_target.length += inst->size;  if (((inst->type == XD3_ADD) || (inst->type == XD3_RUN)) &&      (ret = xd3_whole_alloc_adds (stream, 				   (inst->type == XD3_RUN ? 1 : inst->size))))    {      return ret;    }  switch (inst->type)    {    case XD3_RUN:      winst->addr = stream->whole_target.addslen;      stream->whole_target.adds[stream->whole_target.addslen++] =        *stream->data_sect.buf++;      break;    case XD3_ADD:      winst->addr = stream->whole_target.addslen;      memcpy (stream->whole_target.adds + stream->whole_target.addslen,              stream->data_sect.buf,              inst->size);      stream->data_sect.buf += inst->size;      stream->whole_target.addslen += inst->size;      break;    default:      if (inst->addr < stream->dec_cpylen)	{	  winst->mode = SRCORTGT (stream->dec_win_ind);	  winst->addr = stream->dec_cpyoff + inst->addr;	}      else	{	  winst->addr = (stream->dec_winstart + 			 inst->addr - 			 stream->dec_cpylen);	}      break;    }  return 0;}intxd3_whole_append_window (xd3_stream *stream){  int ret;  xd3_wininfo *wininfo;  if ((ret = xd3_whole_alloc_wininfo (stream, &wininfo))) { return ret; }  wininfo->length = stream->dec_tgtlen;  wininfo->offset = stream->dec_winstart;  wininfo->adler32 = stream->dec_adler32;  while (stream->inst_sect.buf < stream->inst_sect.buf_max)    {      if ((ret = xd3_decode_instruction (stream)))	{	  return ret;	}      if ((stream->dec_current1.type != XD3_NOOP) &&          (ret = xd3_whole_append_inst (stream,					& stream->dec_current1)))	{	  return ret;	}      if ((stream->dec_current2.type != XD3_NOOP) &&	  (ret = xd3_whole_append_inst (stream,					& stream->dec_current2)))	{	  return ret;	}    }  return 0;}/* xd3_merge_input_output applies *source to *stream, returns the * result in stream. */int xd3_merge_input_output (xd3_stream *stream,			    xd3_whole_state *source){  int ret;  xd3_stream tmp_stream;  memset (& tmp_stream, 0, sizeof (tmp_stream));  if ((ret = xd3_config_stream (& tmp_stream, NULL)) ||      (ret = xd3_whole_state_init (& tmp_stream)) ||      (ret = xd3_merge_inputs (& tmp_stream, 			       source,			       & stream->whole_target)))    {      XPR(NT XD3_LIB_ERRMSG (&tmp_stream, ret));      return ret;    }  /* the output is in tmp_stream.whole_state, swap into input */  xd3_swap_whole_state (& stream->whole_target,			& tmp_stream.whole_target);  /* total allocation counts are preserved */  xd3_free_stream (& tmp_stream);  return 0;}static intxd3_merge_run (xd3_stream *stream,	       xd3_whole_state *target,	       xd3_winst *iinst){  int ret;  xd3_winst *oinst;  if ((ret = xd3_whole_alloc_winst (stream, &oinst)) ||      (ret = xd3_whole_alloc_adds (stream, 1)))    {      return ret;    }  oinst->type = iinst->type;  oinst->mode = iinst->mode;  oinst->size = iinst->size;  oinst->addr = stream->whole_target.addslen;  XD3_ASSERT (stream->whole_target.length == iinst->position);  oinst->position = stream->whole_target.length;  stream->whole_target.length += iinst->size;  stream->whole_target.adds[stream->whole_target.addslen++] =     target->adds[iinst->addr];  return 0;}static intxd3_merge_add (xd3_stream *stream,	       xd3_whole_state *target,	       xd3_winst *iinst){  int ret;  xd3_winst *oinst;  if ((ret = xd3_whole_alloc_winst (stream, &oinst)) ||      (ret = xd3_whole_alloc_adds (stream, iinst->size)))    {      return ret;    }  oinst->type = iinst->type;  oinst->mode = iinst->mode;  oinst->size = iinst->size;  oinst->addr = stream->whole_target.addslen;  XD3_ASSERT (stream->whole_target.length == iinst->position);  oinst->position = stream->whole_target.length;  stream->whole_target.length += iinst->size;  memcpy(stream->whole_target.adds + stream->whole_target.addslen,	 target->adds + iinst->addr,	 iinst->size);  stream->whole_target.addslen += iinst->size;  return 0;}static intxd3_merge_target_copy (xd3_stream *stream,		       xd3_winst *iinst){  int ret;  xd3_winst *oinst;  if ((ret = xd3_whole_alloc_winst (stream, &oinst)))    {      return ret;    }  XD3_ASSERT (stream->whole_target.length == iinst->position);  memcpy (oinst, iinst, sizeof (*oinst));  return 0;}static intxd3_merge_find_position (xd3_stream *stream,			 xd3_whole_state *source,			 xoff_t address,			 usize_t *inst_num){  usize_t low;  usize_t high;  if (address >= source->length)    {      stream->msg = "Invalid copy offset in merge";      return XD3_INVALID_INPUT;    }  low = 0;  high = source->instlen;  while (low != high)    {      xoff_t mid_lpos;      xoff_t mid_hpos;      usize_t mid = low + (high - low) / 2;      mid_lpos = source->inst[mid].position;      if (address < mid_lpos)	{	  high = mid;	  continue;	}            mid_hpos = mid_lpos + source->inst[mid].size;      if (address >= mid_hpos)	{	  low = mid + 1;	  continue;	}      *inst_num = mid;      return 0;    }  stream->msg = "Internal error in merge";  return XD3_INTERNAL;}static intxd3_merge_source_copy (xd3_stream *stream,		       xd3_whole_state *source,		       const xd3_winst *iinst_orig){  int ret;  xd3_winst iinst;  usize_t sinst_num;  memcpy (& iinst, iinst_orig, sizeof (iinst));  XD3_ASSERT (iinst.mode == VCD_SOURCE);  if ((ret = xd3_merge_find_position (stream, source, 				      iinst.addr, &sinst_num)))    {      return ret;    }  while (iinst.size > 0)    {      xd3_winst *sinst;      xd3_winst *minst;      usize_t sinst_offset;      usize_t sinst_left;      usize_t this_take;      XD3_ASSERT (sinst_num < source->instlen);      sinst = &source->inst[sinst_num];      XD3_ASSERT (iinst.addr >= sinst->position);      sinst_offset = iinst.addr - sinst->position;      XD3_ASSERT (sinst->size > sinst_offset);      sinst_left = sinst->size - sinst_offset;      this_take = min (iinst.size, sinst_left);      XD3_ASSERT (this_take > 0);      if ((ret = xd3_whole_alloc_winst (stream, &minst)))	{	  return ret;	}      minst->size = this_take;      minst->type = sinst->type;      minst->position = iinst.position;      minst->mode = 0;      switch (sinst->type)	{	case XD3_RUN:	  if ((ret = xd3_whole_alloc_adds (stream, 1)))	    {	      return ret;	    }	  minst->addr = stream->whole_target.addslen;	  stream->whole_target.adds[stream->whole_target.addslen++] = 	    source->adds[sinst->addr];	  break;	case XD3_ADD:	  if ((ret = xd3_whole_alloc_adds (stream, this_take)))	    {	      return ret;	    }	  minst->addr = stream->whole_target.addslen;	  memcpy(stream->whole_target.adds + stream->whole_target.addslen,		 source->adds + sinst->addr + sinst_offset,		 this_take);	  stream->whole_target.addslen += this_take;	  break;	default:	  if (sinst->mode != 0)	    {	      minst->mode = sinst->mode;	      minst->addr = sinst->addr + sinst_offset;	    }	  else	    {	      // TODO: this is slow because of the recursion, which	      // could reach a depth equal to the number of target	      // copies, and this is compression-inefficient because	      // it can produce duplicate adds.	      xd3_winst tinst;	      tinst.type = XD3_CPY;	      tinst.mode = iinst.mode;	      tinst.addr = sinst->addr + sinst_offset;	      tinst.size = this_take;	      tinst.position = iinst.position;	      // The instruction allocated in this frame will not be used.	      stream->whole_target.instlen -= 1;	      if ((ret = xd3_merge_source_copy (stream, source, &tinst)))		{ 		  return ret;		}	    }	  break;	}      iinst.position += this_take;      iinst.addr += this_take;      iinst.size -= this_take;      sinst_num += 1;    }  return 0;}/* xd3_merge_inputs() applies *input to *source, returns its result in * stream. */int xd3_merge_inputs (xd3_stream *stream, 		      xd3_whole_state *source,		      xd3_whole_state *input){  int ret = 0;  usize_t i;  size_t input_i;  for (i = 0; i < input->wininfolen; ++i) {    xd3_wininfo *copyinfo;    if ((ret = xd3_whole_alloc_wininfo (stream, &copyinfo))) { return ret; }    *copyinfo = input->wininfo[i];  }  /* iterate over each instruction. */  for (input_i = 0; ret == 0 && input_i < input->instlen; ++input_i)    {      xd3_winst *iinst = &input->inst[input_i];      switch (iinst->type)	{	case XD3_RUN:	  ret = xd3_merge_run (stream, input, iinst);	  break;	case XD3_ADD:	  ret = xd3_merge_add (stream, input, iinst);	  break;	default:	  /* TODO: VCD_TARGET support is completely untested all	   * throughout. */	  if (iinst->mode == 0 || iinst->mode == VCD_TARGET)	    {	      ret = xd3_merge_target_copy (stream, iinst);	    }	  else	    {	      ret = xd3_merge_source_copy (stream, source, iinst);	    }	  /* The whole_target.length is not updated in the xd3_merge*copy	   * routine because of recursion in xd3_merge_source_copy. */	  stream->whole_target.length += iinst->size;	  break;	}    }    return ret;}#endif

⌨️ 快捷键说明

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