📄 xdelta3.h
字号:
const uint8_t *enc_appheader; /* application header to encode */ usize_t enc_appheadsz; /* application header size */ /* decoder stuff */ xd3_decode_state dec_state; /* current DEC_XXX value */ usize_t dec_hdr_ind; /* VCDIFF header indicator */ usize_t dec_win_ind; /* VCDIFF window indicator */ usize_t dec_del_ind; /* VCDIFF delta indicator */ uint8_t dec_magic[4]; /* First four bytes */ usize_t dec_magicbytes; /* Magic position. */ usize_t dec_secondid; /* Optional secondary compressor ID. */ /* TODO: why decode breaks if this is usize_t? */ uint32_t dec_codetblsz; /* Optional code table: length. */ uint8_t *dec_codetbl; /* Optional code table: storage. */ usize_t dec_codetblbytes; /* Optional code table: position. */ /* TODO: why decode breaks if this is usize_t? */ uint32_t dec_appheadsz; /* Optional application header: size. */ uint8_t *dec_appheader; /* Optional application header: storage */ usize_t dec_appheadbytes; /* Optional application header: position. */ usize_t dec_cksumbytes; /* Optional checksum: position. */ uint8_t dec_cksum[4]; /* Optional checksum: storage. */ uint32_t dec_adler32; /* Optional checksum: value. */ /* TODO: why decode breaks if this is usize_t? */ uint32_t dec_cpylen; /* length of copy window (VCD_SOURCE or VCD_TARGET) */ xoff_t dec_cpyoff; /* offset of copy window (VCD_SOURCE or VCD_TARGET) */ /* TODO: why decode breaks if this is usize_t? */ uint32_t dec_enclen; /* length of delta encoding */ /* TODO: why decode breaks if this is usize_t? */ uint32_t dec_tgtlen; /* length of target window */#if USE_UINT64 uint64_t dec_64part; /* part of a decoded uint64_t */#endif#if USE_UINT32 uint32_t dec_32part; /* part of a decoded uint32_t */#endif xoff_t dec_winstart; /* offset of the start of current target window */ xoff_t dec_window_count; /* == current_window + 1 in DEC_FINISH */ usize_t dec_winbytes; /* bytes of the three sections so far consumed */ usize_t dec_hdrsize; /* VCDIFF + app header size */ const uint8_t *dec_tgtaddrbase; /* Base of decoded target addresses (addr >= dec_cpylen). */ const uint8_t *dec_cpyaddrbase; /* Base of decoded copy addresses (addr < dec_cpylen). */ usize_t dec_position; /* current decoder position counting the cpylen offset */ usize_t dec_maxpos; /* maximum decoder position counting the cpylen offset */ xd3_hinst dec_current1; /* current instruction */ xd3_hinst dec_current2; /* current instruction */ uint8_t *dec_buffer; /* Decode buffer */ uint8_t *dec_lastwin; /* In case of VCD_TARGET, the last target window. */ usize_t dec_lastlen; /* length of the last target window */ xoff_t dec_laststart; /* offset of the start of last target window */ usize_t dec_lastspace; /* allocated space of last target window, for reuse */ xd3_desect inst_sect; /* staging area for decoding window sections */ xd3_desect addr_sect; xd3_desect data_sect; xd3_code_table_func *code_table_func; xd3_comp_table_func *comp_table_func; const xd3_dinst *code_table; const xd3_code_table_desc *code_table_desc; xd3_dinst *code_table_alloc; /* secondary compression */ const xd3_sec_type *sec_type; xd3_sec_stream *sec_stream_d; xd3_sec_stream *sec_stream_i; xd3_sec_stream *sec_stream_a; /* state for reconstructing whole files (e.g., for merge), this only * supports loading USIZE_T_MAX instructions, adds, etc. */ xd3_whole_state whole_target; /* statistics */ xoff_t n_scpy; xoff_t n_tcpy; xoff_t n_add; xoff_t n_run; xoff_t l_scpy; xoff_t l_tcpy; xoff_t l_add; xoff_t l_run; usize_t i_slots_used;#if XD3_DEBUG usize_t large_ckcnt; /* memory usage */ usize_t alloc_cnt; usize_t free_cnt;#endif};/************************************************************************** PUBLIC FUNCTIONS **************************************************************************//* This function configures an xd3_stream using the provided in-memory * input buffer, source buffer, output buffer, and flags. The output * array must be large enough or else ENOSPC will be returned. This * is the simplest in-memory encoding interface. */int xd3_encode_memory (const uint8_t *input, usize_t input_size, const uint8_t *source, usize_t source_size, uint8_t *output_buffer, usize_t *output_size, usize_t avail_output, int flags);/* The reverse of xd3_encode_memory. */int xd3_decode_memory (const uint8_t *input, usize_t input_size, const uint8_t *source, usize_t source_size, uint8_t *output_buf, usize_t *output_size, usize_t avail_output, int flags);/* This function encodes an in-memory input. Everything else about * the xd3_stream is configurable. The output array must be large * enough to hold the output or else ENOSPC is returned. The source * (if any) should be set using xd3_set_source() with a single-block * xd3_source. This calls the underlying non-blocking interface, * xd3_encode_input(), handling the necessary input/output states. * This method be considered a reference for any application using * xd3_encode_input() directly. * * xd3_stream stream; * xd3_config config; * xd3_source src; * * memset (& src, 0, sizeof (src)); * memset (& stream, 0, sizeof (stream)); * memset (& config, 0, sizeof (config)); * * if (source != NULL) * { * src.size = source_size; * src.blksize = source_size; * src.curblkno = 0; * src.onblk = source_size; * src.curblk = source; * xd3_set_source(&stream, &src); * } * * config.flags = flags; * config.srcwin_maxsz = source_size; * config.winsize = input_size; * * ... set smatcher, appheader, encoding-table, compression-level, etc. * * xd3_config_stream(&stream, &config); * xd3_encode_stream(&stream, ...); * xd3_free_stream(&stream); * * DO NOT USE except for testing. These methods are allocate bad buffer sizes. */int xd3_encode_stream (xd3_stream *stream, const uint8_t *input, usize_t input_size, uint8_t *output, usize_t *output_size, usize_t avail_output);/* The reverse of xd3_encode_stream. */int xd3_decode_stream (xd3_stream *stream, const uint8_t *input, usize_t input_size, uint8_t *output, usize_t *output_size, usize_t avail_size);/* This is the non-blocking interface. * * Handling input and output states is the same for encoding or * decoding using the xd3_avail_input() and xd3_consume_output() * routines, inlined below. * * Return values: * * XD3_INPUT: the process requires more input: call * xd3_avail_input() then repeat * * XD3_OUTPUT: the process has more output: read stream->next_out, * stream->avail_out, then call xd3_consume_output(), * then repeat * * XD3_GOTHEADER: (decoder-only) notification returned following the * VCDIFF header and first window header. the decoder * may use the header to configure itself. * * XD3_WINSTART: a general notification returned once for each * window except the 0-th window, which is implied by * XD3_GOTHEADER. It is recommended to use a * switch-stmt such as: * * ... * again: * switch ((ret = xd3_decode_input (stream))) { * case XD3_GOTHEADER: { * assert(stream->current_window == 0); * stuff; * } * // fallthrough * case XD3_WINSTART: { * something(stream->current_window); * goto again; * } * ... * * XD3_WINFINISH: a general notification, following the complete * input & output of a window. at this point, * stream->total_in and stream->total_out are consistent * for either encoding or decoding. * * XD3_GETSRCBLK: If the xd3_getblk() callback is NULL, this value * is returned to initiate a non-blocking source read. */int xd3_decode_input (xd3_stream *stream);int xd3_encode_input (xd3_stream *stream);/* The xd3_config structure is used to initialize a stream - all data * is copied into stream so config may be a temporary variable. See * the [documentation] or comments on the xd3_config structure. */int xd3_config_stream (xd3_stream *stream, xd3_config *config);/* Since Xdelta3 doesn't open any files, xd3_close_stream is just an * error check that the stream is in a proper state to be closed: this * means the encoder is flushed and the decoder is at a window * boundary. The application is responsible for freeing any of the * resources it supplied. */int xd3_close_stream (xd3_stream *stream);/* This arranges for closes the stream to succeed. Does not free the * stream.*/void xd3_abort_stream (xd3_stream *stream);/* xd3_free_stream frees all memory allocated for the stream. The * application is responsible for freeing any of the resources it * supplied. */void xd3_free_stream (xd3_stream *stream);/* This function informs the encoder or decoder that source matching * (i.e., delta-compression) is possible. For encoding, this should * be called before the first xd3_encode_input. A NULL source is * ignored. For decoding, this should be called before the first * window is decoded, but the appheader may be read first * (XD3_GOTHEADER). After decoding the header, call xd3_set_source() * if you have a source file. Note: if (stream->dec_win_ind & VCD_SOURCE) * is true, it means the first window expects there to be a source file. */int xd3_set_source (xd3_stream *stream, xd3_source *source);/* This should be called before the first call to xd3_encode_input() * to include application-specific data in the VCDIFF header. */void xd3_set_appheader (xd3_stream *stream, const uint8_t *data, usize_t size);/* xd3_get_appheader may be called in the decoder after XD3_GOTHEADER. * For convenience, the decoder always adds a single byte padding to * the end of the application header, which is set to zero in case the * application header is a string. */int xd3_get_appheader (xd3_stream *stream, uint8_t **data, usize_t *size);/* To generate a VCDIFF encoded delta with xd3_encode_init() from * another format, use: * * xd3_encode_init_partial() -- initialze encoder state (w/o hash tables) * xd3_init_cache() -- reset VCDIFF address cache * xd3_found_match() -- to report a copy instruction * * set stream->enc_state to ENC_INSTR and call xd3_encode_input as usual. */int xd3_encode_init_partial (xd3_stream *stream);void xd3_init_cache (xd3_addr_cache* acache);int xd3_found_match (xd3_stream *stream, usize_t pos, usize_t size, xoff_t addr, int is_source);/* Gives an error string for xdelta3-speficic errors, returns NULL for system errors */const char* xd3_strerror (int ret);/* For convenience, zero & initialize the xd3_config structure with specified flags. */static inlinevoid xd3_init_config (xd3_config *config, int flags){ memset (config, 0, sizeof (*config)); config->flags = flags;}/* This supplies some input to the stream. */static inlinevoid xd3_avail_input (xd3_stream *stream, const uint8_t *idata, usize_t isize){ /* Even if isize is zero, the code expects a non-NULL idata. Why? * It uses this value to determine whether xd3_avail_input has ever * been called. If xd3_encode_input is called before * xd3_avail_input it will return XD3_INPUT right away without * allocating a stream->winsize buffer. This is to avoid an * unwanted allocation. */ XD3_ASSERT (idata != NULL || isize == 0); stream->next_in = idata; stream->avail_in = isize;}/* This acknowledges receipt of output data, must be called after any * XD3_OUTPUT return. */static inlinevoid xd3_consume_output (xd3_stream *stream){ stream->avail_out = 0;}/* These are set for each XD3_WINFINISH return. */static inlineint xd3_encoder_used_source (xd3_stream *stream) { return stream->src != NULL && stream->src->srclen > 0;}static inlinexoff_t xd3_encoder_srcbase (xd3_stream *stream) { return stream->src->srcbase;}static inlineusize_t xd3_encoder_srclen (xd3_stream *stream) { return stream->src->srclen;}/* Checks for legal flag changes. */static inlinevoid xd3_set_flags (xd3_stream *stream, int flags){ /* The bitwise difference should contain only XD3_FLUSH or XD3_SKIP_WINDOW */ XD3_ASSERT(((flags ^ stream->flags) & ~(XD3_FLUSH | XD3_SKIP_WINDOW)) == 0); stream->flags = flags;}/* Gives some extra information about the latest library error, if any is known. */static inlineconst char* xd3_errstring (xd3_stream *stream){ return stream->msg ? stream->msg : "";}/* 64-bit divisions are expensive. on a 32bit platform, these show in * a profile as __udivdi3(). these are all the xoff_t divisions: */static inlinevoid xd3_blksize_div (const xoff_t offset, const xd3_source *source, xoff_t *blkno, usize_t *blkoff) { *blkno = source->maskby ? (offset >> source->shiftby) : (offset / source->blksize); *blkoff = source->maskby ? (offset & source->maskby) : (offset - *blkno * source->blksize);}/* This function tells the number of bytes expected to be set in * source->onblk after a getblk request. This is for convenience of * handling a partial last block. Note that this is a relatively * expensive function for 64-bit binaries on platforms w/o native * 64-bit integers, so source->onlastblk is set to this value. * TODO: force source->blksize to a power of two? */static inlineusize_t xd3_bytes_on_srcblk (xd3_source *source, xoff_t blkno){ xoff_t s_1_div; usize_t s_1_rem; XD3_ASSERT (blkno < source->blocks); if (blkno != source->blocks - 1) { return source->blksize; } xd3_blksize_div(source->size - 1, source, &s_1_div, &s_1_rem); return s_1_rem + 1;}static inlineusize_t xd3_bytes_on_srcblk_fast (xd3_source *source, xoff_t blkno){ return (blkno == source->blocks - 1 ? source->onlastblk : source->blksize);}#endif /* _XDELTA3_H_ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -