📄 xdelta3-main.h
字号:
if (size != nwrite) { XPR(NT "Incorrect write count"); ret = XD3_INTERNAL; } }#endif if (ret) { XPR(NT "%s: %s: %s\n", msg, ofile->filename, xd3_mainerror (ret)); } else { if (option_verbose > 3) { XPR(NT "main write: %s: %u\n", ofile->filename, size); } ofile->nwrite += size; } return ret;}static intmain_file_seek (main_file *xfile, xoff_t pos){ int ret = 0;#if XD3_STDIO if (fseek (xfile->file, pos, SEEK_SET) != 0) { ret = get_errno (); }#elif XD3_POSIX if ((xoff_t) lseek (xfile->file, pos, SEEK_SET) != pos) { ret = get_errno (); }#elif XD3_WIN32# if (_WIN32_WINNT >= 0x0500) LARGE_INTEGER move, out; move.QuadPart = pos; if (SetFilePointerEx(xfile->file, move, &out, FILE_BEGIN) == 0) { ret = get_errno (); }# else if (SetFilePointer(xfile->file, (LONG)pos, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { ret = get_errno (); }# endif#endif if (ret) { XPR(NT "seek failed: %s: %s\n", xfile->filename, xd3_mainerror (ret)); } return ret;}/* This function simply writes the stream output buffer, if there is * any, for encode, decode and recode commands. (The VCDIFF tools use * main_print_func()). */static intmain_write_output (xd3_stream* stream, main_file *ofile){ int ret; if (option_no_output) { return 0; } if (stream->avail_out > 0 && (ret = main_file_write (ofile, stream->next_out, stream->avail_out, "write failed"))) { return ret; } return 0;}static intmain_set_secondary_flags (xd3_config *config){ int ret; if (option_use_secondary) { /* The default secondary compressor is DJW, if it's compiled. */ if (option_secondary == NULL) { if (SECONDARY_DJW) { config->flags |= XD3_SEC_DJW; } } else { if (strcmp (option_secondary, "fgk") == 0 && SECONDARY_FGK) { config->flags |= XD3_SEC_FGK; } else if (strncmp (option_secondary, "djw", 3) == 0 && SECONDARY_DJW) { usize_t level = XD3_DEFAULT_SECONDARY_LEVEL; config->flags |= XD3_SEC_DJW; if (strlen (option_secondary) > 3 && (ret = main_atou (option_secondary + 3, &level, 0, 9, 'S')) != 0 && !option_quiet) { return XD3_INVALID; } /* XD3_SEC_NOXXXX flags disable secondary compression on * a per-section basis. For djw, ngroups=1 indicates * minimum work, ngroups=0 uses default settings, which * is > 1 groups by default. */ if (level < 1) { config->flags |= XD3_SEC_NODATA; } if (level < 7) { config->sec_data.ngroups = 1; } else { config->sec_data.ngroups = 0; } if (level < 3) { config->flags |= XD3_SEC_NOINST; } if (level < 8) { config->sec_inst.ngroups = 1; } else { config->sec_inst.ngroups = 0; } if (level < 5) { config->flags |= XD3_SEC_NOADDR; } if (level < 9) { config->sec_addr.ngroups = 1; } else { config->sec_addr.ngroups = 0; } } else if (strcmp (option_secondary, "none") == 0 && SECONDARY_DJW) { /* No secondary */ } else { if (!option_quiet) { XPR(NT "unrecognized secondary compressor type: %s\n", option_secondary); return XD3_INVALID; } } } } return 0;}/****************************************************************** VCDIFF TOOLS *****************************************************************/#if VCDIFF_TOOLS#include "xdelta3-merge.h"#if defined(_WIN32) || defined(__DJGPP__)/* According to the internet, Windows vsnprintf() differs from most * Unix implementations regarding the terminating 0 when the boundary * condition is met. It doesn't matter here, we don't rely on the * trailing 0. Besides, both Windows and DJGPP vsnprintf return -1 * upon truncation, which isn't C99 compliant. To overcome this, * recent MinGW runtimes provided their own vsnprintf (notice the * absence of the '_' prefix) but they were initially buggy. So, * always use the native '_'-prefixed version with Win32. */#include <stdarg.h>#ifdef _WIN32#define vsnprintf_func _vsnprintf#else#define vsnprintf_func vsnprintf#endifintsnprintf_func (char *str, int n, char *fmt, ...){ va_list a; int ret; va_start (a, fmt); ret = vsnprintf_func (str, n, fmt, a); va_end (a); if (ret < 0) ret = n; return ret;}#else#define snprintf_func snprintf#endif/* The following macros let VCDIFF printing something printf-like with * main_file_write(), e.g.,: * * VC(UT "trying to be portable: %d\n", x)VE; */#define SNPRINTF_BUFSIZE 1024#define VC do { if (((ret = snprintf_func#define UT (char*)xfile->snprintf_buf, SNPRINTF_BUFSIZE,#define VE ) >= SNPRINTF_BUFSIZE \ && (ret = main_print_overflow(ret)) != 0) \ || (ret = main_file_write(xfile, xfile->snprintf_buf, \ ret, "print")) != 0) \ { return ret; } } while (0)static intmain_print_overflow (int x){ XPR(NT "internal print buffer overflow: %d bytes\n", x); return XD3_INTERNAL;}/* This function prints a single VCDIFF window. */static intmain_print_window (xd3_stream* stream, main_file *xfile){ int ret; usize_t size = 0; VC(UT " Offset Code Type1 Size1 @Addr1 + Type2 Size2 @Addr2\n")VE; while (stream->inst_sect.buf < stream->inst_sect.buf_max) { usize_t code = stream->inst_sect.buf[0]; const uint8_t *addr_before = stream->addr_sect.buf; const uint8_t *inst_before = stream->inst_sect.buf; usize_t addr_bytes; usize_t inst_bytes; usize_t size_before = size; if ((ret = xd3_decode_instruction (stream))) { XPR(NT "instruction decode error at %"Q"u: %s\n", stream->dec_winstart + size, stream->msg); return ret; } addr_bytes = stream->addr_sect.buf - addr_before; inst_bytes = stream->inst_sect.buf - inst_before; VC(UT " %06"Q"u %03u %s %6u", stream->dec_winstart + size, option_print_cpymode ? code : 0, xd3_rtype_to_string ((xd3_rtype) stream->dec_current1.type, option_print_cpymode), (usize_t) stream->dec_current1.size)VE; if (stream->dec_current1.type != XD3_NOOP) { if (stream->dec_current1.type >= XD3_CPY) { if (stream->dec_current1.addr >= stream->dec_cpylen) { VC(UT " T@%-6u", stream->dec_current1.addr - stream->dec_cpylen)VE; } else { VC(UT " S@%-6"Q"u", stream->dec_cpyoff + stream->dec_current1.addr)VE; } } else { VC(UT " ")VE; } size += stream->dec_current1.size; } if (stream->dec_current2.type != XD3_NOOP) { VC(UT " %s %6u", xd3_rtype_to_string ((xd3_rtype) stream->dec_current2.type, option_print_cpymode), (usize_t)stream->dec_current2.size)VE; if (stream->dec_current2.type >= XD3_CPY) { if (stream->dec_current2.addr >= stream->dec_cpylen) { VC(UT " T@%-6u", stream->dec_current2.addr - stream->dec_cpylen)VE; } else { VC(UT " S@%-6"Q"u", stream->dec_cpyoff + stream->dec_current2.addr)VE; } } size += stream->dec_current2.size; } VC(UT "\n")VE; if (option_verbose && addr_bytes + inst_bytes >= (size - size_before) && (stream->dec_current1.type >= XD3_CPY || stream->dec_current2.type >= XD3_CPY)) { VC(UT " %06"Q"u (inefficiency) %u encoded as %u bytes\n", stream->dec_winstart + size_before, size - size_before, addr_bytes + inst_bytes)VE; } } if (stream->dec_tgtlen != size && (stream->flags & XD3_SKIP_WINDOW) == 0) { XPR(NT "target window size inconsistency"); return XD3_INTERNAL; } if (stream->dec_position != stream->dec_maxpos) { XPR(NT "target window position inconsistency"); return XD3_INTERNAL; } if (stream->addr_sect.buf != stream->addr_sect.buf_max) { XPR(NT "address section inconsistency"); return XD3_INTERNAL; } return 0;}static intmain_print_vcdiff_file (main_file *xfile, main_file *file, const char *type){ int ret; /* Used by above macros */ if (file->filename) { VC(UT "XDELTA filename (%s): %s\n", type, file->filename)VE; } if (file->compressor) { VC(UT "XDELTA ext comp (%s): %s\n", type, file->compressor->recomp_cmdname)VE; } return 0;}/* This function prints a VCDIFF input, mainly for debugging purposes. */static intmain_print_func (xd3_stream* stream, main_file *xfile){ int ret; if (option_no_output) { return 0; } if (xfile->snprintf_buf == NULL) { if ((xfile->snprintf_buf = (uint8_t*)main_malloc(SNPRINTF_BUFSIZE)) == NULL) { return ENOMEM; } } if (stream->dec_winstart == 0) { VC(UT "VCDIFF version: 0\n")VE; VC(UT "VCDIFF header size: %d\n", stream->dec_hdrsize)VE; VC(UT "VCDIFF header indicator: ")VE; if ((stream->dec_hdr_ind & VCD_SECONDARY) != 0) VC(UT "VCD_SECONDARY ")VE; if ((stream->dec_hdr_ind & VCD_CODETABLE) != 0) VC(UT "VCD_CODETABLE ")VE; if ((stream->dec_hdr_ind & VCD_APPHEADER) != 0) VC(UT "VCD_APPHEADER ")VE; if (stream->dec_hdr_ind == 0) VC(UT "none")VE; VC(UT "\n")VE; IF_SEC(VC(UT "VCDIFF secondary compressor: %s\n", stream->sec_type ? stream->sec_type->name : "none")VE); IF_NSEC(VC(UT "VCDIFF secondary compressor: unsupported\n")VE); if (stream->dec_hdr_ind & VCD_APPHEADER) { uint8_t *apphead; usize_t appheadsz; ret = xd3_get_appheader (stream, & apphead, & appheadsz); if (ret == 0 && appheadsz > 0) { int sq = option_quiet; main_file i, o, s; XD3_ASSERT (apphead != NULL); VC(UT "VCDIFF application header: ")VE; if ((ret = main_file_write (xfile, apphead, appheadsz, "print")) != 0) { return ret; } VC(UT "\n")VE; main_file_init (& i); main_file_init (& o); main_file_init (& s); option_quiet = 1; main_get_appheader (stream, &i, & o, & s); option_quiet = sq; if ((ret = main_print_vcdiff_file (xfile, & o, "output"))) { return ret; } if ((ret = main_print_vcdiff_file (xfile, & s, "source"))) { return ret; } main_file_cleanup (& i); main_file_cleanup (& o); main_file_cleanup (& s); } } } else { VC(UT "\n")VE; } VC(UT "VCDIFF window number: %"Q"u\n", stream->current_window)VE; VC(UT "VCDIFF window indicator: ")VE; if ((stream->dec_win_ind & VCD_SOURCE) != 0) VC(UT "VCD_SOURCE ")VE; if ((stream->dec_win_ind & VCD_TARGET) != 0) VC(UT "VCD_TARGET ")VE; if ((stream->dec_win_ind & VCD_ADLER32) != 0) VC(UT "VCD_ADLER32 ")VE; if (stream->dec_win_ind == 0) VC(UT "none")VE; VC(UT "\n")VE; if ((stream->dec_win_ind & VCD_ADLER32) != 0) { VC(UT "VCDIFF adler32 checksum: %08X\n", (usize_t)stream->dec_adler32)VE; } if (stream->dec_del_ind != 0) { VC(UT "VCDIFF delta indicator: ")VE; if ((stream->dec_del_ind & VCD_DATACOMP) != 0) VC(UT "VCD_DATACOMP ")VE; if ((stream->dec_del_ind & VCD_INSTCOMP) != 0) VC(UT "VCD_INSTCOMP ")VE; if ((stream->dec_del_ind & VCD_ADDRCOMP) != 0) VC(UT "VCD_ADDRCOMP ")VE; if (stream->dec_del_ind == 0) VC(UT "none")VE; VC(UT "\n")VE; } if (stream->dec_winstart != 0) { VC(UT "VCDIFF window at offset: %"Q"u\n", stream->dec_winstart)VE; } if (SRCORTGT (stream->dec_win_ind)) { VC(UT "VCDIFF copy window length: %u\n", (usize_t)stream->dec_cpylen)VE; VC(UT "VCDIFF copy window offset: %"Q"u\n", stream->dec_cpyoff)VE; } VC(UT "VCDIFF delta encoding length: %u\n", (usize_t)stream->dec_enclen)VE; VC(UT "VCDIFF target window length: %u\n", (usize_t)stream->dec_tgtlen)VE; VC(UT "VCDIFF data section length: %u\n", (usize_t)stream->data_sect.size)VE; VC(UT "VCDIFF inst section length: %u\n", (usize_t)stream->inst_sect.size)VE; VC(UT "VCDIFF addr section length: %u\n", (usize_t)stream->addr_sect.size)VE; ret = 0; if ((stream->flags & XD3_JUST_HDR) != 0) { /* Print a header -- finished! */ ret = PRINTHDR_SPECIAL; } else if ((stream->flags & XD3_SKIP_WINDOW) == 0) { ret = main_print_window (stream, xfile); } return ret;}static intmain_recode_copy (xd3_stream* stream, xd3_output* output, xd3_desect* input){ int ret; XD3_ASSERT(output != NULL); XD3_ASSERT(output->next_page == NULL); if ((ret = xd3_decode_allocate (recode_stream, input->size, &output->base, &output->avail))) { XPR(NT XD3_LIB_ERRMSG (stream, ret)); return ret; } memcpy (output->base, /* Note: decoder advances buf, so get base of buffer with * buf_max - size */ input->buf_max - input->size, input->size); output->next = input->size; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -