summaryrefslogtreecommitdiff
path: root/xdelta3/xdelta3.h
diff options
context:
space:
mode:
authordotdotisdead <dotdotisdead@a3eca27d-f21b-0410-9b4a-6511e771f64e>2006-12-10 20:27:45 +0000
committerdotdotisdead <dotdotisdead@a3eca27d-f21b-0410-9b4a-6511e771f64e>2006-12-10 20:27:45 +0000
commit811bb03103a6e8a307c2e59863f03dd88cd9b11c (patch)
treef4f8d2851f7df333a1c2be48f50df405a5444ad0 /xdelta3/xdelta3.h
parent7fb75616337a50fb98c6c251f8d76825dfca9165 (diff)
Builds on WIN32.
Diffstat (limited to 'xdelta3/xdelta3.h')
-rwxr-xr-xxdelta3/xdelta3.h1996
1 files changed, 1000 insertions, 996 deletions
diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h
index 1c1b7aa..0375122 100755
--- a/xdelta3/xdelta3.h
+++ b/xdelta3/xdelta3.h
@@ -1,996 +1,1000 @@
1/* xdelta 3 - delta compression tools and library 1/* xdelta 3 - delta compression tools and library
2 * Copyright (C) 2001, 2003, 2004, 2005, 2006. Joshua P. MacDonald 2 * Copyright (C) 2001, 2003, 2004, 2005, 2006. Joshua P. MacDonald
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or 6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version. 7 * (at your option) any later version.
8 * 8 *
9 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */ 17 */
18 18
19/* Welcome to Xdelta. If you want to know more about Xdelta, start by reading xdelta3.c. 19/* Welcome to Xdelta. If you want to know more about Xdelta, start by reading xdelta3.c.
20 * If you are ready to use the API, continue reading here. There are two interfaces -- 20 * If you are ready to use the API, continue reading here. There are two interfaces --
21 * xd3_encode_input and xd3_decode_input -- plus a dozen or so related calls. This 21 * xd3_encode_input and xd3_decode_input -- plus a dozen or so related calls. This
22 * interface is styled after Zlib. */ 22 * interface is styled after Zlib. */
23 23
24#ifndef _XDELTA3_H_ 24#ifndef _XDELTA3_H_
25#define _XDELTA3_H_ 25#define _XDELTA3_H_
26 26
27#include <stdlib.h> 27#include <stdlib.h>
28#include <string.h> 28#include <string.h>
29#include <sys/types.h> 29#include <sys/types.h>
30 30
31/**********************************************************************/ 31/**********************************************************************/
32 32
33/* Default configured value of stream->winsize. If the program supplies 33/* Default configured value of stream->winsize. If the program supplies
34 * xd3_encode_input() with data smaller than winsize the stream will 34 * xd3_encode_input() with data smaller than winsize the stream will
35 * automatically buffer the input, otherwise the input buffer is used directly. 35 * automatically buffer the input, otherwise the input buffer is used directly.
36 */ 36 */
37#ifndef XD3_DEFAULT_WINSIZE 37#ifndef XD3_DEFAULT_WINSIZE
38#define XD3_DEFAULT_WINSIZE (1U << 18) 38#define XD3_DEFAULT_WINSIZE (1U << 18)
39#endif 39#endif
40 40
41/* This is a unit of how far to advance the checksum position in one go. */ 41/* This is a unit of how far to advance the checksum position in one go. */
42#ifndef XD3_DEFAULT_CKSUM_ADVANCE 42#ifndef XD3_DEFAULT_CKSUM_ADVANCE
43#define XD3_DEFAULT_CKSUM_ADVANCE (1U << 14) 43#define XD3_DEFAULT_CKSUM_ADVANCE (1U << 14)
44#endif 44#endif
45 45
46/* Default total size of the source window used in xdelta3-main.h */ 46/* Default total size of the source window used in xdelta3-main.h */
47#ifndef XD3_DEFAULT_SRCWINSZ 47#ifndef XD3_DEFAULT_SRCWINSZ
48#define XD3_DEFAULT_SRCWINSZ (1U << 23) 48#define XD3_DEFAULT_SRCWINSZ (1U << 23)
49#endif 49#endif
50 50
51/* Default configured value of stream->memsize. This dictates how much memory Xdelta will 51/* Default configured value of stream->memsize. This dictates how much memory Xdelta will
52 * use for string-matching data structures. */ 52 * use for string-matching data structures. */
53#ifndef XD3_DEFAULT_MEMSIZE 53#ifndef XD3_DEFAULT_MEMSIZE
54#define XD3_DEFAULT_MEMSIZE (1U << 18) 54#define XD3_DEFAULT_MEMSIZE (1U << 18)
55#endif 55#endif
56 56
57/* When Xdelta requests a memory allocation for certain buffers, it rounds up to units of 57/* When Xdelta requests a memory allocation for certain buffers, it rounds up to units of
58 * at least this size. The code assumes (and asserts) that this is a power-of-two. */ 58 * at least this size. The code assumes (and asserts) that this is a power-of-two. */
59#ifndef XD3_ALLOCSIZE 59#ifndef XD3_ALLOCSIZE
60#define XD3_ALLOCSIZE (1U<<14) 60#define XD3_ALLOCSIZE (1U<<14)
61#endif 61#endif
62 62
63/* The XD3_HARDMAXWINSIZE parameter is a safety mechanism to protect decoders against 63/* The XD3_HARDMAXWINSIZE parameter is a safety mechanism to protect decoders against
64 * malicious files. The decoder will never decode a window larger than this. If the file 64 * malicious files. The decoder will never decode a window larger than this. If the file
65 * specifies VCD_TARGET the decoder may require two buffers of this size. Rationale for 65 * specifies VCD_TARGET the decoder may require two buffers of this size. Rationale for
66 * choosing 22-bits as a maximum: this means that in the worst case, any VCDIFF address 66 * choosing 22-bits as a maximum: this means that in the worst case, any VCDIFF address
67 * without a copy window will require 3 bytes to encode (7 bits per byte, HERE and SAME 67 * without a copy window will require 3 bytes to encode (7 bits per byte, HERE and SAME
68 * modes making every address within half the window away. */ 68 * modes making every address within half the window away. */
69#ifndef XD3_HARDMAXWINSIZE 69#ifndef XD3_HARDMAXWINSIZE
70#define XD3_HARDMAXWINSIZE (1U<<23) 70#define XD3_HARDMAXWINSIZE (1U<<23)
71#endif 71#endif
72 72
73/* The XD3_NODECOMPRESSSIZE parameter tells the xdelta main routine not to try to 73/* The XD3_NODECOMPRESSSIZE parameter tells the xdelta main routine not to try to
74 * externally-decompress source inputs that are too large. Since these files must be 74 * externally-decompress source inputs that are too large. Since these files must be
75 * seekable, they are decompressed to a temporary file location and the user may not wish 75 * seekable, they are decompressed to a temporary file location and the user may not wish
76 * for this. */ 76 * for this. */
77#ifndef XD3_NODECOMPRESSSIZE 77#ifndef XD3_NODECOMPRESSSIZE
78#define XD3_NODECOMPRESSSIZE (1U<<24) 78#define XD3_NODECOMPRESSSIZE (1U<<24)
79#endif 79#endif
80 80
81/* The IOPT_SIZE value sets the size of a buffer used to batch overlapping copy 81/* The IOPT_SIZE value sets the size of a buffer used to batch overlapping copy
82 * instructions before they are optimized by picking the best non-overlapping ranges. The 82 * instructions before they are optimized by picking the best non-overlapping ranges. The
83 * larger this buffer, the longer a forced xd3_srcwin_setup() decision is held off. */ 83 * larger this buffer, the longer a forced xd3_srcwin_setup() decision is held off. */
84#ifndef XD3_DEFAULT_IOPT_SIZE 84#ifndef XD3_DEFAULT_IOPT_SIZE
85#define XD3_DEFAULT_IOPT_SIZE 128 85#define XD3_DEFAULT_IOPT_SIZE 128
86#endif 86#endif
87 87
88/* The maximum distance backward to search for small matches */ 88/* The maximum distance backward to search for small matches */
89#ifndef XD3_DEFAULT_SPREVSZ 89#ifndef XD3_DEFAULT_SPREVSZ
90#define XD3_DEFAULT_SPREVSZ (1U << 16) 90#define XD3_DEFAULT_SPREVSZ (1U << 16)
91#endif 91#endif
92 92
93/* Sizes and addresses within VCDIFF windows are represented as usize_t 93/* Sizes and addresses within VCDIFF windows are represented as usize_t
94 * 94 *
95 * For source-file offsets and total file sizes, total input and output counts, the xoff_t 95 * For source-file offsets and total file sizes, total input and output counts, the xoff_t
96 * type is used. The decoder and encoder generally check for overflow of the xoff_t size, 96 * type is used. The decoder and encoder generally check for overflow of the xoff_t size,
97 * and this is tested at the 32bit boundary [xdelta3-test.h]. 97 * and this is tested at the 32bit boundary [xdelta3-test.h].
98 */ 98 */
99#ifndef _WIN32 99#ifndef _WIN32
100typedef unsigned int usize_t; 100typedef unsigned int usize_t;
101typedef u_int8_t uint8_t; 101typedef u_int8_t uint8_t;
102typedef u_int16_t uint16_t; 102typedef u_int16_t uint16_t;
103typedef u_int32_t uint32_t; 103typedef u_int32_t uint32_t;
104typedef u_int64_t uint64_t; 104typedef u_int64_t uint64_t;
105#else 105#else
106#include <windows.h> 106// CRT_SECURE_NO_DEPRECATE silences warnings about sprintf() and strerror()
107#define inline 107#define _CRT_SECURE_NO_DEPRECATE 1
108typedef unsigned int uint; 108#define _CRT_SECURE_COPP_OVERLOAD_STANDARD_NAMES 1
109typedef unsigned int usize_t; 109#define WIN32_LEAN_AND_MEAN
110typedef unsigned char uint8_t; 110#include <windows.h>
111typedef unsigned short uint16_t; 111#define inline
112typedef unsigned long uint32_t; 112typedef unsigned int uint;
113typedef ULONGLONG uint64_t; 113typedef unsigned int usize_t;
114#endif 114typedef unsigned char uint8_t;
115 115typedef unsigned short uint16_t;
116#define SIZEOF_USIZE_T 4 116typedef unsigned long uint32_t;
117 117typedef ULONGLONG uint64_t;
118#ifndef XD3_USE_LARGEFILE64 118#endif
119#define XD3_USE_LARGEFILE64 1 119
120#endif 120#define SIZEOF_USIZE_T 4
121 121
122#if XD3_USE_LARGEFILE64 122#ifndef XD3_USE_LARGEFILE64
123#define __USE_FILE_OFFSET64 1 /* GLIBC: for 64bit fileops, ... ? */ 123#define XD3_USE_LARGEFILE64 1
124typedef uint64_t xoff_t; 124#endif
125#define SIZEOF_XOFF_T 8 125
126#else 126#if XD3_USE_LARGEFILE64
127typedef uint32_t xoff_t; 127#define __USE_FILE_OFFSET64 1 /* GLIBC: for 64bit fileops, ... ? */
128#define SIZEOF_XOFF_T 4 128typedef uint64_t xoff_t;
129#endif 129#define SIZEOF_XOFF_T 8
130 130#else
131#define USE_UINT32 (SIZEOF_USIZE_T == 4 || SIZEOF_XOFF_T == 4 || REGRESSION_TEST) 131typedef uint32_t xoff_t;
132#define USE_UINT64 (SIZEOF_USIZE_T == 8 || SIZEOF_XOFF_T == 8 || REGRESSION_TEST) 132#define SIZEOF_XOFF_T 4
133 133#endif
134/**********************************************************************/ 134
135 135#define USE_UINT32 (SIZEOF_USIZE_T == 4 || SIZEOF_XOFF_T == 4 || REGRESSION_TEST)
136#ifndef INLINE 136#define USE_UINT64 (SIZEOF_USIZE_T == 8 || SIZEOF_XOFF_T == 8 || REGRESSION_TEST)
137#define INLINE inline 137
138#endif 138/**********************************************************************/
139 139
140/* Whether to build the encoder, otherwise only build the decoder. */ 140#ifndef INLINE
141#ifndef XD3_ENCODER 141#define INLINE inline
142#define XD3_ENCODER 1 142#endif
143#endif 143
144 144/* Whether to build the encoder, otherwise only build the decoder. */
145/* The code returned when main() fails, also defined in system includes. */ 145#ifndef XD3_ENCODER
146#ifndef EXIT_FAILURE 146#define XD3_ENCODER 1
147#define EXIT_FAILURE 1 147#endif
148#endif 148
149 149/* The code returned when main() fails, also defined in system includes. */
150/* REGRESSION TEST enables the "xdelta3 test" command, which runs a series of self-tests. */ 150#ifndef EXIT_FAILURE
151#ifndef REGRESSION_TEST 151#define EXIT_FAILURE 1
152#define REGRESSION_TEST 0 152#endif
153#endif 153
154 154/* REGRESSION TEST enables the "xdelta3 test" command, which runs a series of self-tests. */
155/* XD3_DEBUG=1 enables assertions and various statistics. Levels > 1 enable some 155#ifndef REGRESSION_TEST
156 * additional output only useful during development and debugging. */ 156#define REGRESSION_TEST 0
157#ifndef XD3_DEBUG 157#endif
158#define XD3_DEBUG 0 158
159#endif 159/* XD3_DEBUG=1 enables assertions and various statistics. Levels > 1 enable some
160 160 * additional output only useful during development and debugging. */
161#ifndef PYTHON_MODULE 161#ifndef XD3_DEBUG
162#define PYTHON_MODULE 0 162#define XD3_DEBUG 0
163#endif 163#endif
164 164
165/* There are three string matching functions supplied: one fast, one slow (default), and 165#ifndef PYTHON_MODULE
166 * one soft-configurable. To disable any of these, use the following definitions. */ 166#define PYTHON_MODULE 0
167#ifndef XD3_BUILD_SLOW 167#endif
168#define XD3_BUILD_SLOW 1 168
169#endif 169/* There are three string matching functions supplied: one fast, one slow (default), and
170#ifndef XD3_BUILD_FAST 170 * one soft-configurable. To disable any of these, use the following definitions. */
171#define XD3_BUILD_FAST 1 171#ifndef XD3_BUILD_SLOW
172#endif 172#define XD3_BUILD_SLOW 1
173#ifndef XD3_BUILD_SOFT 173#endif
174#define XD3_BUILD_SOFT 1 174#ifndef XD3_BUILD_FAST
175#endif 175#define XD3_BUILD_FAST 1
176 176#endif
177#if XD3_DEBUG 177#ifndef XD3_BUILD_SOFT
178#include <stdio.h> 178#define XD3_BUILD_SOFT 1
179#endif 179#endif
180 180
181/* XPRINT. Debug output and VCDIFF_TOOLS functions report to stderr. I have used an 181#if XD3_DEBUG
182 * irregular style to abbreviate [fprintf(stderr, "] as [P(RINT "]. */ 182#include <stdio.h>
183#define P fprintf 183#endif
184#define RINT stderr, 184
185 185/* XPRINT. Debug output and VCDIFF_TOOLS functions report to stderr. I have used an
186typedef struct _xd3_stream xd3_stream; 186 * irregular style to abbreviate [fprintf(stderr, "] as [P(RINT "]. */
187typedef struct _xd3_source xd3_source; 187#define P fprintf
188typedef struct _xd3_hash_cfg xd3_hash_cfg; 188#define RINT stderr,
189typedef struct _xd3_smatcher xd3_smatcher; 189
190typedef struct _xd3_rinst xd3_rinst; 190typedef struct _xd3_stream xd3_stream;
191typedef struct _xd3_dinst xd3_dinst; 191typedef struct _xd3_source xd3_source;
192typedef struct _xd3_hinst xd3_hinst; 192typedef struct _xd3_hash_cfg xd3_hash_cfg;
193typedef struct _xd3_rpage xd3_rpage; 193typedef struct _xd3_smatcher xd3_smatcher;
194typedef struct _xd3_addr_cache xd3_addr_cache; 194typedef struct _xd3_rinst xd3_rinst;
195typedef struct _xd3_output xd3_output; 195typedef struct _xd3_dinst xd3_dinst;
196typedef struct _xd3_desect xd3_desect; 196typedef struct _xd3_hinst xd3_hinst;
197typedef struct _xd3_iopt_buf xd3_iopt_buf; 197typedef struct _xd3_rpage xd3_rpage;
198typedef struct _xd3_rlist xd3_rlist; 198typedef struct _xd3_addr_cache xd3_addr_cache;
199typedef struct _xd3_sec_type xd3_sec_type; 199typedef struct _xd3_output xd3_output;
200typedef struct _xd3_sec_cfg xd3_sec_cfg; 200typedef struct _xd3_desect xd3_desect;
201typedef struct _xd3_sec_stream xd3_sec_stream; 201typedef struct _xd3_iopt_buf xd3_iopt_buf;
202typedef struct _xd3_config xd3_config; 202typedef struct _xd3_rlist xd3_rlist;
203typedef struct _xd3_code_table_desc xd3_code_table_desc; 203typedef struct _xd3_sec_type xd3_sec_type;
204typedef struct _xd3_code_table_sizes xd3_code_table_sizes; 204typedef struct _xd3_sec_cfg xd3_sec_cfg;
205typedef struct _xd3_slist xd3_slist; 205typedef struct _xd3_sec_stream xd3_sec_stream;
206 206typedef struct _xd3_config xd3_config;
207/* The stream configuration has three callbacks functions, all of which may be supplied 207typedef struct _xd3_code_table_desc xd3_code_table_desc;
208 * with NULL values. If config->getblk is provided as NULL, the stream returns 208typedef struct _xd3_code_table_sizes xd3_code_table_sizes;
209 * XD3_GETSRCBLK. */ 209typedef struct _xd3_slist xd3_slist;
210 210
211typedef void* (xd3_alloc_func) (void *opaque, 211/* The stream configuration has three callbacks functions, all of which may be supplied
212 usize_t items, 212 * with NULL values. If config->getblk is provided as NULL, the stream returns
213 usize_t size); 213 * XD3_GETSRCBLK. */
214typedef void (xd3_free_func) (void *opaque, 214
215 void *address); 215typedef void* (xd3_alloc_func) (void *opaque,
216 216 usize_t items,
217typedef int (xd3_getblk_func) (xd3_stream *stream, 217 usize_t size);
218 xd3_source *source, 218typedef void (xd3_free_func) (void *opaque,
219 xoff_t blkno); 219 void *address);
220 220
221/* These are internal functions to delay construction of encoding tables and support 221typedef int (xd3_getblk_func) (xd3_stream *stream,
222 * alternate code tables. See the comments & code enabled by GENERIC_ENCODE_TABLES. */ 222 xd3_source *source,
223 223 xoff_t blkno);
224typedef const xd3_dinst* (xd3_code_table_func) (void); 224
225typedef int (xd3_comp_table_func) (xd3_stream *stream, 225/* These are internal functions to delay construction of encoding tables and support
226 const uint8_t **data, 226 * alternate code tables. See the comments & code enabled by GENERIC_ENCODE_TABLES. */
227 usize_t *size); 227
228 228typedef const xd3_dinst* (xd3_code_table_func) (void);
229 229typedef int (xd3_comp_table_func) (xd3_stream *stream,
230/* Some junk. */ 230 const uint8_t **data,
231 231 usize_t *size);
232#ifndef XD3_ASSERT 232
233#if XD3_DEBUG 233
234#define XD3_ASSERT(x) \ 234/* Some junk. */
235 do { if (! (x)) { P(RINT "%s:%d: XD3 assertion failed: %s\n", __FILE__, __LINE__, #x); \ 235
236 abort (); } } while (0) 236#ifndef XD3_ASSERT
237#else 237#if XD3_DEBUG
238#define XD3_ASSERT(x) (void)0 238#define XD3_ASSERT(x) \
239#endif 239 do { if (! (x)) { P(RINT "%s:%d: XD3 assertion failed: %s\n", __FILE__, __LINE__, #x); \
240#endif 240 abort (); } } while (0)
241 241#else
242#ifdef __GNUC__ 242#define XD3_ASSERT(x) (void)0
243/* As seen on linux-kernel. */ 243#endif
244#ifndef max 244#endif
245#define max(x,y) ({ \ 245
246 const typeof(x) _x = (x); \ 246#ifdef __GNUC__
247 const typeof(y) _y = (y); \ 247/* As seen on linux-kernel. */
248 (void) (&_x == &_y); \ 248#ifndef max
249 _x > _y ? _x : _y; }) 249#define max(x,y) ({ \
250#endif 250 const typeof(x) _x = (x); \
251 251 const typeof(y) _y = (y); \
252#ifndef min 252 (void) (&_x == &_y); \
253#define min(x,y) ({ \ 253 _x > _y ? _x : _y; })
254 const typeof(x) _x = (x); \ 254#endif
255 const typeof(y) _y = (y); \ 255
256 (void) (&_x == &_y); \ 256#ifndef min
257 _x < _y ? _x : _y; }) 257#define min(x,y) ({ \
258#endif 258 const typeof(x) _x = (x); \
259#else 259 const typeof(y) _y = (y); \
260#ifndef max 260 (void) (&_x == &_y); \
261#define max(x,y) ((x) < (y) ? (y) : (x)) 261 _x < _y ? _x : _y; })
262#endif 262#endif
263#ifndef min 263#else
264#define min(x,y) ((x) < (y) ? (x) : (y)) 264#ifndef max
265#endif 265#define max(x,y) ((x) < (y) ? (y) : (x))
266#endif 266#endif
267 267#ifndef min
268/****************************************************************************************** 268#define min(x,y) ((x) < (y) ? (x) : (y))
269 PUBLIC ENUMS 269#endif
270 ******************************************************************************************/ 270#endif
271 271
272/* These are the five ordinary status codes returned by the xd3_encode_input() and 272/******************************************************************************************
273 * xd3_decode_input() state machines. */ 273 PUBLIC ENUMS
274typedef enum { 274 ******************************************************************************************/
275 275
276 /* An application must be prepared to handle these five return values from either 276/* These are the five ordinary status codes returned by the xd3_encode_input() and
277 * xd3_encode_input or xd3_decode_input, except in the case of no-source compression, in 277 * xd3_decode_input() state machines. */
278 * which case XD3_GETSRCBLK is never returned. More detailed comments for these are 278typedef enum {
279 * given in xd3_encode_input and xd3_decode_input comments, below. */ 279
280 XD3_INPUT = -17703, /* need input */ 280 /* An application must be prepared to handle these five return values from either
281 XD3_OUTPUT = -17704, /* have output */ 281 * xd3_encode_input or xd3_decode_input, except in the case of no-source compression, in
282 XD3_GETSRCBLK = -17705, /* need a block of source input (with no xd3_getblk function), 282 * which case XD3_GETSRCBLK is never returned. More detailed comments for these are
283 * a chance to do non-blocking read. */ 283 * given in xd3_encode_input and xd3_decode_input comments, below. */
284 XD3_GOTHEADER = -17706, /* (decode-only) after the initial VCDIFF & first window header */ 284 XD3_INPUT = -17703, /* need input */
285 XD3_WINSTART = -17707, /* notification: returned before a window is processed, giving a 285 XD3_OUTPUT = -17704, /* have output */
286 * chance to XD3_SKIP_WINDOW or not XD3_SKIP_EMIT that window. */ 286 XD3_GETSRCBLK = -17705, /* need a block of source input (with no xd3_getblk function),
287 XD3_WINFINISH = -17708, /* notification: returned after encode/decode & output for a window */ 287 * a chance to do non-blocking read. */
288 XD3_TOOFARBACK = -17709, /* (encoder only) may be returned by getblk() if the block is too old */ 288 XD3_GOTHEADER = -17706, /* (decode-only) after the initial VCDIFF & first window header */
289 XD3_INTERNAL = -17710, /* internal error */ 289 XD3_WINSTART = -17707, /* notification: returned before a window is processed, giving a
290 290 * chance to XD3_SKIP_WINDOW or not XD3_SKIP_EMIT that window. */
291} xd3_rvalues; 291 XD3_WINFINISH = -17708, /* notification: returned after encode/decode & output for a window */
292 292 XD3_TOOFARBACK = -17709, /* (encoder only) may be returned by getblk() if the block is too old */
293/* special values in config->flags */ 293 XD3_INTERNAL = -17710, /* internal error */
294typedef enum 294
295{ 295} xd3_rvalues;
296 XD3_JUST_HDR = (1 << 1), /* used by VCDIFF tools, see xdelta3-main.h. */ 296
297 XD3_SKIP_WINDOW = (1 << 2), /* used by VCDIFF tools, see xdelta3-main.h. */ 297/* special values in config->flags */
298 XD3_SKIP_EMIT = (1 << 3), /* used by VCDIFF tools, see xdelta3-main.h. */ 298typedef enum
299 XD3_FLUSH = (1 << 4), /* flush the stream buffer to prepare for xd3_stream_close(). */ 299{
300 300 XD3_JUST_HDR = (1 << 1), /* used by VCDIFF tools, see xdelta3-main.h. */
301 XD3_SEC_DJW = (1 << 5), /* use DJW static huffman */ 301 XD3_SKIP_WINDOW = (1 << 2), /* used by VCDIFF tools, see xdelta3-main.h. */
302 XD3_SEC_FGK = (1 << 6), /* use FGK adaptive huffman */ 302 XD3_SKIP_EMIT = (1 << 3), /* used by VCDIFF tools, see xdelta3-main.h. */
303 XD3_SEC_TYPE = (XD3_SEC_DJW | XD3_SEC_FGK), 303 XD3_FLUSH = (1 << 4), /* flush the stream buffer to prepare for xd3_stream_close(). */
304 304
305 XD3_SEC_NODATA = (1 << 7), /* disable secondary compression of the data section. */ 305 XD3_SEC_DJW = (1 << 5), /* use DJW static huffman */
306 XD3_SEC_NOINST = (1 << 8), /* disable secondary compression of the inst section. */ 306 XD3_SEC_FGK = (1 << 6), /* use FGK adaptive huffman */
307 XD3_SEC_NOADDR = (1 << 9), /* disable secondary compression of the addr section. */ 307 XD3_SEC_TYPE = (XD3_SEC_DJW | XD3_SEC_FGK),
308 308
309 XD3_SEC_OTHER = (XD3_SEC_NODATA | XD3_SEC_NOINST | XD3_SEC_NOADDR), 309 XD3_SEC_NODATA = (1 << 7), /* disable secondary compression of the data section. */
310 310 XD3_SEC_NOINST = (1 << 8), /* disable secondary compression of the inst section. */
311 XD3_ADLER32 = (1 << 10), /* enable checksum computation in the encoder. */ 311 XD3_SEC_NOADDR = (1 << 9), /* disable secondary compression of the addr section. */
312 XD3_ADLER32_NOVER = (1 << 11), /* disable checksum verification in the decoder. */ 312
313 313 XD3_SEC_OTHER = (XD3_SEC_NODATA | XD3_SEC_NOINST | XD3_SEC_NOADDR),
314 XD3_ALT_CODE_TABLE = (1 << 12), /* for testing the alternate code table encoding. */ 314
315 315 XD3_ADLER32 = (1 << 10), /* enable checksum computation in the encoder. */
316 XD3_NOCOMPRESS = (1 << 13), /* disable ordinary data compression feature, 316 XD3_ADLER32_NOVER = (1 << 11), /* disable checksum verification in the decoder. */
317 * only search the source, not the target. */ 317
318 XD3_BEGREEDY = (1 << 14), /* disable the "1.5-pass algorithm", instead use 318 XD3_ALT_CODE_TABLE = (1 << 12), /* for testing the alternate code table encoding. */
319 * greedy matching. Greedy is off by default. */ 319
320} xd3_flags; 320 XD3_NOCOMPRESS = (1 << 13), /* disable ordinary data compression feature,
321 321 * only search the source, not the target. */
322/* The values of this enumeration are set in xd3_config using the smatch_cfg variable. It 322 XD3_BEGREEDY = (1 << 14), /* disable the "1.5-pass algorithm", instead use
323 * can be set to slow, fast, soft, or default. The fast and slow setting uses preset, 323 * greedy matching. Greedy is off by default. */
324 * hardcoded parameters and the soft setting is accompanied by user-supplied parameters. 324} xd3_flags;
325 * If the user supplies 'default' the code selects one of the available string matchers. 325
326 * Due to compile-time settings (see XD3_SLOW_SMATCHER, XD3_FAST_SMATCHER, 326/* The values of this enumeration are set in xd3_config using the smatch_cfg variable. It
327 * XD3_SOFT_SMATCHER variables), not all options may be available. */ 327 * can be set to slow, fast, soft, or default. The fast and slow setting uses preset,
328typedef enum 328 * hardcoded parameters and the soft setting is accompanied by user-supplied parameters.
329{ 329 * If the user supplies 'default' the code selects one of the available string matchers.
330 XD3_SMATCH_DEFAULT = 0, 330 * Due to compile-time settings (see XD3_SLOW_SMATCHER, XD3_FAST_SMATCHER,
331 XD3_SMATCH_SLOW = 1, 331 * XD3_SOFT_SMATCHER variables), not all options may be available. */
332 XD3_SMATCH_FAST = 2, 332typedef enum
333 XD3_SMATCH_SOFT = 3, 333{
334} xd3_smatch_cfg; 334 XD3_SMATCH_DEFAULT = 0,
335 335 XD3_SMATCH_SLOW = 1,
336/****************************************************************************************** 336 XD3_SMATCH_FAST = 2,
337 PRIVATE ENUMS 337 XD3_SMATCH_SOFT = 3,
338 ******************************************************************************************/ 338} xd3_smatch_cfg;
339 339
340/* stream->match_state is part of the xd3_encode_input state machine for source matching: 340/******************************************************************************************
341 * 341 PRIVATE ENUMS
342 * 1. the XD3_GETSRCBLK block-read mechanism means reentrant matching 342 ******************************************************************************************/
343 * 2. this state spans encoder windows: a match and end-of-window will continue in the next 343
344 * 3. the initial target byte and source byte are a presumed match, to avoid some computation 344/* stream->match_state is part of the xd3_encode_input state machine for source matching:
345 * in case the inputs are identical. 345 *
346 */ 346 * 1. the XD3_GETSRCBLK block-read mechanism means reentrant matching
347typedef enum { 347 * 2. this state spans encoder windows: a match and end-of-window will continue in the next
348 348 * 3. the initial target byte and source byte are a presumed match, to avoid some computation
349 MATCH_TARGET = 0, /* in this state, attempt to match the start of the target with the 349 * in case the inputs are identical.
350 * previously set source address (initially 0). */ 350 */
351 MATCH_BACKWARD = 1, /* currently expanding a match backward in the source/target. */ 351typedef enum {
352 MATCH_FORWARD = 2, /* currently expanding a match forward in the source/target. */ 352
353 MATCH_SEARCHING = 3, /* currently searching for a match. */ 353 MATCH_TARGET = 0, /* in this state, attempt to match the start of the target with the
354 354 * previously set source address (initially 0). */
355} xd3_match_state; 355 MATCH_BACKWARD = 1, /* currently expanding a match backward in the source/target. */
356 356 MATCH_FORWARD = 2, /* currently expanding a match forward in the source/target. */
357/* The xd3_encode_input state machine steps through these states in the following order. 357 MATCH_SEARCHING = 3, /* currently searching for a match. */
358 * The matcher is reentrant and returns XD3_INPUT whenever it requires more data. After 358
359 * receiving XD3_INPUT, if the application reads EOF it should call xd3_stream_close(). 359} xd3_match_state;
360 */ 360
361typedef enum { 361/* The xd3_encode_input state machine steps through these states in the following order.
362 362 * The matcher is reentrant and returns XD3_INPUT whenever it requires more data. After
363 ENC_INIT = 0, /* xd3_encode_input has never been called. */ 363 * receiving XD3_INPUT, if the application reads EOF it should call xd3_stream_close().
364 ENC_INPUT = 1, /* waiting for xd3_avail_input () to be called. */ 364 */
365 ENC_SEARCH = 2, /* currently searching for matches. */ 365typedef enum {
366 ENC_FLUSH = 3, /* currently emitting output. */ 366
367 ENC_POSTOUT = 4, /* after an output section. */ 367 ENC_INIT = 0, /* xd3_encode_input has never been called. */
368 ENC_POSTWIN = 5, /* after all output sections. */ 368 ENC_INPUT = 1, /* waiting for xd3_avail_input () to be called. */
369 ENC_ABORTED = 6, /* abort. */ 369 ENC_SEARCH = 2, /* currently searching for matches. */
370} xd3_encode_state; 370 ENC_FLUSH = 3, /* currently emitting output. */
371 371 ENC_POSTOUT = 4, /* after an output section. */
372/* The xd3_decode_input state machine steps through these states in the following order. 372 ENC_POSTWIN = 5, /* after all output sections. */
373 * The matcher is reentrant and returns XD3_INPUT whenever it requires more data. After 373 ENC_ABORTED = 6, /* abort. */
374 * receiving XD3_INPUT, if the application reads EOF it should call xd3_stream_close(). 374} xd3_encode_state;
375 * 375
376 * 0-8: the VCDIFF header 376/* The xd3_decode_input state machine steps through these states in the following order.
377 * 9-18: the VCDIFF window header 377 * The matcher is reentrant and returns XD3_INPUT whenever it requires more data. After
378 * 19-21: the three primary sections: data (which I think should have gone last), inst, addr 378 * receiving XD3_INPUT, if the application reads EOF it should call xd3_stream_close().
379 * 22: producing output: returns XD3_OUTPUT, possibly XD3_GETSRCBLK, 379 *
380 * 23: return XD3_WINFINISH, set state=9 to decode more input 380 * 0-8: the VCDIFF header
381 */ 381 * 9-18: the VCDIFF window header
382typedef enum { 382 * 19-21: the three primary sections: data (which I think should have gone last), inst, addr
383 383 * 22: producing output: returns XD3_OUTPUT, possibly XD3_GETSRCBLK,
384 DEC_VCHEAD = 0, /* VCDIFF header */ 384 * 23: return XD3_WINFINISH, set state=9 to decode more input
385 DEC_HDRIND = 1, /* header indicator */ 385 */
386 386typedef enum {
387 DEC_SECONDID = 2, /* secondary compressor ID */ 387
388 388 DEC_VCHEAD = 0, /* VCDIFF header */
389 DEC_TABLEN = 3, /* code table length */ 389 DEC_HDRIND = 1, /* header indicator */
390 DEC_NEAR = 4, /* code table near */ 390
391 DEC_SAME = 5, /* code table same */ 391 DEC_SECONDID = 2, /* secondary compressor ID */
392 DEC_TABDAT = 6, /* code table data */ 392
393 393 DEC_TABLEN = 3, /* code table length */
394 DEC_APPLEN = 7, /* application data length */ 394 DEC_NEAR = 4, /* code table near */
395 DEC_APPDAT = 8, /* application data */ 395 DEC_SAME = 5, /* code table same */
396 396 DEC_TABDAT = 6, /* code table data */
397 DEC_WININD = 9, /* window indicator */ 397
398 398 DEC_APPLEN = 7, /* application data length */
399 DEC_CPYLEN = 10, /* copy window length */ 399 DEC_APPDAT = 8, /* application data */
400 DEC_CPYOFF = 11, /* copy window offset */ 400
401 401 DEC_WININD = 9, /* window indicator */
402 DEC_ENCLEN = 12, /* length of delta encoding */ 402
403 DEC_TGTLEN = 13, /* length of target window */ 403 DEC_CPYLEN = 10, /* copy window length */
404 DEC_DELIND = 14, /* delta indicator */ 404 DEC_CPYOFF = 11, /* copy window offset */
405 405
406 DEC_DATALEN = 15, /* length of ADD+RUN data */ 406 DEC_ENCLEN = 12, /* length of delta encoding */
407 DEC_INSTLEN = 16, /* length of instruction data */ 407 DEC_TGTLEN = 13, /* length of target window */
408 DEC_ADDRLEN = 17, /* length of address data */ 408 DEC_DELIND = 14, /* delta indicator */
409 409
410 DEC_CKSUM = 18, /* window checksum */ 410 DEC_DATALEN = 15, /* length of ADD+RUN data */
411 411 DEC_INSTLEN = 16, /* length of instruction data */
412 DEC_DATA = 19, /* data section */ 412 DEC_ADDRLEN = 17, /* length of address data */
413 DEC_INST = 20, /* instruction section */ 413
414 DEC_ADDR = 21, /* address section */ 414 DEC_CKSUM = 18, /* window checksum */
415 415
416 DEC_EMIT = 22, /* producing data */ 416 DEC_DATA = 19, /* data section */
417 417 DEC_INST = 20, /* instruction section */
418 DEC_FINISH = 23, /* window finished */ 418 DEC_ADDR = 21, /* address section */
419 419
420 DEC_ABORTED = 24, /* xd3_abort_stream */ 420 DEC_EMIT = 22, /* producing data */
421} xd3_decode_state; 421
422 422 DEC_FINISH = 23, /* window finished */
423/* An application never sees these internal codes: */ 423
424typedef enum { 424 DEC_ABORTED = 24, /* xd3_abort_stream */
425 XD3_NOSECOND = -17708, /* when secondary compression finds no improvement. */ 425} xd3_decode_state;
426} xd3_pvalues; 426
427 427/* An application never sees these internal codes: */
428/****************************************************************************************** 428typedef enum {
429 internal types 429 XD3_NOSECOND = -17708, /* when secondary compression finds no improvement. */
430 ******************************************************************************************/ 430} xd3_pvalues;
431 431
432/* instruction lists used in the IOPT buffer */ 432/******************************************************************************************
433struct _xd3_rlist 433 internal types
434{ 434 ******************************************************************************************/
435 xd3_rlist *next; 435
436 xd3_rlist *prev; 436/* instruction lists used in the IOPT buffer */
437}; 437struct _xd3_rlist
438 438{
439/* the raw encoding of an instruction used in the IOPT buffer */ 439 xd3_rlist *next;
440struct _xd3_rinst 440 xd3_rlist *prev;
441{ 441};
442 uint8_t type; 442
443 uint8_t xtra; 443/* the raw encoding of an instruction used in the IOPT buffer */
444 uint8_t code1; 444struct _xd3_rinst
445 uint8_t code2; 445{
446 usize_t pos; 446 uint8_t type;
447 usize_t size; 447 uint8_t xtra;
448 xoff_t addr; 448 uint8_t code1;
449 xd3_rlist link; 449 uint8_t code2;
450}; 450 usize_t pos;
451 451 usize_t size;
452/* the code-table form of an single- or double-instruction */ 452 xoff_t addr;
453struct _xd3_dinst 453 xd3_rlist link;
454{ 454};
455 uint8_t type1; 455
456 uint8_t size1; 456/* the code-table form of an single- or double-instruction */
457 uint8_t type2; 457struct _xd3_dinst
458 uint8_t size2; 458{
459}; 459 uint8_t type1;
460 460 uint8_t size1;
461/* the decoded form of a single (half) instruction. */ 461 uint8_t type2;
462struct _xd3_hinst 462 uint8_t size2;
463{ 463};
464 uint8_t type; 464
465 usize_t size; 465/* the decoded form of a single (half) instruction. */
466 usize_t addr; 466struct _xd3_hinst
467}; 467{
468 468 uint8_t type;
469/* used by the encoder to buffer output in sections. list of blocks. */ 469 usize_t size;
470struct _xd3_output 470 usize_t addr;
471{ 471};
472 uint8_t *base; 472
473 usize_t next; 473/* used by the encoder to buffer output in sections. list of blocks. */
474 usize_t avail; 474struct _xd3_output
475 xd3_output *next_page; 475{
476}; 476 uint8_t *base;
477 477 usize_t next;
478/* the VCDIFF address cache, see the RFC */ 478 usize_t avail;
479struct _xd3_addr_cache 479 xd3_output *next_page;
480{ 480};
481 uint s_near; 481
482 uint s_same; 482/* the VCDIFF address cache, see the RFC */
483 usize_t next_slot; /* the circular index for near */ 483struct _xd3_addr_cache
484 usize_t *near_array; /* array of size s_near */ 484{
485 usize_t *same_array; /* array of size s_same*256 */ 485 uint s_near;
486}; 486 uint s_same;
487 487 usize_t next_slot; /* the circular index for near */
488/* the IOPT buffer has a used list of (ordered) instructions, possibly overlapping in 488 usize_t *near_array; /* array of size s_near */
489 * target addresses, awaiting a flush */ 489 usize_t *same_array; /* array of size s_same*256 */
490struct _xd3_iopt_buf 490};
491{ 491
492 xd3_rlist used; 492/* the IOPT buffer has a used list of (ordered) instructions, possibly overlapping in
493 xd3_rlist free; 493 * target addresses, awaiting a flush */
494 xd3_rinst *buffer; 494struct _xd3_iopt_buf
495}; 495{
496 496 xd3_rlist used;
497/* This is the record of a pre-compiled configuration, a subset of xd3_config. */ 497 xd3_rlist free;
498struct _xd3_smatcher 498 xd3_rinst *buffer;
499{ 499};
500 const char *name; 500
501 int (*string_match) (xd3_stream *stream); 501/* This is the record of a pre-compiled configuration, a subset of xd3_config. */
502 uint large_look; 502struct _xd3_smatcher
503 uint large_step; 503{
504 uint small_look; 504 const char *name;
505 uint small_chain; 505 int (*string_match) (xd3_stream *stream);
506 uint small_lchain; 506 uint large_look;
507 uint ssmatch; 507 uint large_step;
508 uint try_lazy; 508 uint small_look;
509 uint max_lazy; 509 uint small_chain;
510 uint long_enough; 510 uint small_lchain;
511 uint promote; 511 uint ssmatch;
512}; 512 uint try_lazy;
513 513 uint max_lazy;
514/* hash table size & power-of-two hash function. */ 514 uint long_enough;
515struct _xd3_hash_cfg 515 uint promote;
516{ 516};
517 usize_t size; 517
518 usize_t shift; 518/* hash table size & power-of-two hash function. */
519 usize_t mask; 519struct _xd3_hash_cfg
520}; 520{
521 521 usize_t size;
522/* a hash-chain link in the small match table, embedded with position and checksum */ 522 usize_t shift;
523struct _xd3_slist 523 usize_t mask;
524{ 524};
525 xd3_slist *next; 525
526 xd3_slist *prev; 526/* a hash-chain link in the small match table, embedded with position and checksum */
527 usize_t pos; 527struct _xd3_slist
528 usize_t scksum; 528{
529}; 529 xd3_slist *next;
530 530 xd3_slist *prev;
531/* a decoder section (data, inst, or addr). there is an optimization to avoid copying 531 usize_t pos;
532 * these sections if all the input is available, related to the copied field below. 532 usize_t scksum;
533 * secondation compression uses the copied2 field. */ 533};
534struct _xd3_desect 534
535{ 535/* a decoder section (data, inst, or addr). there is an optimization to avoid copying
536 const uint8_t *buf; 536 * these sections if all the input is available, related to the copied field below.
537 const uint8_t *buf_max; 537 * secondation compression uses the copied2 field. */
538 usize_t size; 538struct _xd3_desect
539 usize_t pos; 539{
540 uint8_t *copied1; 540 const uint8_t *buf;
541 usize_t alloc1; 541 const uint8_t *buf_max;
542 uint8_t *copied2; 542 usize_t size;
543 usize_t alloc2; 543 usize_t pos;
544}; 544 uint8_t *copied1;
545 545 usize_t alloc1;
546/****************************************************************************************** 546 uint8_t *copied2;
547 public types 547 usize_t alloc2;
548 ******************************************************************************************/ 548};
549 549
550/* Settings for the secondary compressor. */ 550/******************************************************************************************
551struct _xd3_sec_cfg 551 public types
552{ 552 ******************************************************************************************/
553 int data_type; /* Which section. (set automatically) */ 553
554 int ngroups; /* Number of DJW Huffman groups. */ 554/* Settings for the secondary compressor. */
555 int sector_size; /* Sector size. */ 555struct _xd3_sec_cfg
556 int inefficient; /* If true, ignore efficiency check [avoid XD3_NOSECOND]. */ 556{
557}; 557 int data_type; /* Which section. (set automatically) */
558 558 int ngroups; /* Number of DJW Huffman groups. */
559/* This is the user-visible stream configuration. */ 559 int sector_size; /* Sector size. */
560struct _xd3_config 560 int inefficient; /* If true, ignore efficiency check [avoid XD3_NOSECOND]. */
561{ 561};
562 usize_t memsize; /* How much memory Xdelta may allocate */ 562
563 usize_t winsize; /* The encoder window size. */ 563/* This is the user-visible stream configuration. */
564 usize_t sprevsz; /* How far back small string matching goes */ 564struct _xd3_config
565 usize_t iopt_size; /* entries in the instruction-optimizing buffer */ 565{
566 usize_t srcwin_size; /* Initial size of the source-window lookahead */ 566 usize_t memsize; /* How much memory Xdelta may allocate */
567 usize_t srcwin_maxsz; /* srcwin_size grows by a factor of 2 when no matches are found */ 567 usize_t winsize; /* The encoder window size. */
568 568 usize_t sprevsz; /* How far back small string matching goes */
569 xd3_getblk_func *getblk; /* The three callbacks. */ 569 usize_t iopt_size; /* entries in the instruction-optimizing buffer */
570 xd3_alloc_func *alloc; 570 usize_t srcwin_size; /* Initial size of the source-window lookahead */
571 xd3_free_func *freef; 571 usize_t srcwin_maxsz; /* srcwin_size grows by a factor of 2 when no matches are found */
572 void *opaque; /* Not used. */ 572
573 int flags; /* stream->flags are initialized from xd3_config & 573 xd3_getblk_func *getblk; /* The three callbacks. */
574 * never modified by the library. Use xd3_set_flags 574 xd3_alloc_func *alloc;
575 * to modify flags settings mid-stream. */ 575 xd3_free_func *freef;
576 576 void *opaque; /* Not used. */
577 xd3_sec_cfg sec_data; /* Secondary compressor config: data */ 577 int flags; /* stream->flags are initialized from xd3_config &
578 xd3_sec_cfg sec_inst; /* Secondary compressor config: inst */ 578 * never modified by the library. Use xd3_set_flags
579 xd3_sec_cfg sec_addr; /* Secondary compressor config: addr */ 579 * to modify flags settings mid-stream. */
580 580
581 xd3_smatch_cfg smatch_cfg; /* See enum: use fields below for soft config */ 581 xd3_sec_cfg sec_data; /* Secondary compressor config: data */
582 xd3_smatcher smatcher_soft; 582 xd3_sec_cfg sec_inst; /* Secondary compressor config: inst */
583}; 583 xd3_sec_cfg sec_addr; /* Secondary compressor config: addr */
584 584
585/* The primary source file object. You create one of these objects and initialize the 585 xd3_smatch_cfg smatch_cfg; /* See enum: use fields below for soft config */
586 * first four fields. This library maintains the next 5 fields. The configured getblk 586 xd3_smatcher smatcher_soft;
587 * implementation is responsible for setting the final 3 fields when called (and/or when 587};
588 * XD3_GETSRCBLK is returned). 588
589 */ 589/* The primary source file object. You create one of these objects and initialize the
590struct _xd3_source 590 * first four fields. This library maintains the next 5 fields. The configured getblk
591{ 591 * implementation is responsible for setting the final 3 fields when called (and/or when
592 /* you set */ 592 * XD3_GETSRCBLK is returned).
593 xoff_t size; /* size of this source */ 593 */
594 usize_t blksize; /* block size */ 594struct _xd3_source
595 const char *name; /* its name, for debug/print purposes */ 595{
596 void *ioh; /* opaque handle */ 596 /* you set */
597 597 xoff_t size; /* size of this source */
598 /* xd3 sets */ 598 usize_t blksize; /* block size */
599 usize_t srclen; /* length of this source window */ 599 const char *name; /* its name, for debug/print purposes */
600 xoff_t srcbase; /* offset of this source window in the source itself */ 600 void *ioh; /* opaque handle */
601 xoff_t blocks; /* the total number of blocks in this source */ 601
602 usize_t cpyoff_blocks; /* offset of copy window in blocks */ 602 /* xd3 sets */
603 usize_t cpyoff_blkoff; /* offset of copy window in blocks, remainder */ 603 usize_t srclen; /* length of this source window */
604 xoff_t getblkno; /* request block number: xd3 sets current getblk request */ 604 xoff_t srcbase; /* offset of this source window in the source itself */
605 605 xoff_t blocks; /* the total number of blocks in this source */
606 /* getblk sets */ 606 usize_t cpyoff_blocks; /* offset of copy window in blocks */
607 xoff_t curblkno; /* current block number: client sets after getblk request */ 607 usize_t cpyoff_blkoff; /* offset of copy window in blocks, remainder */
608 usize_t onblk; /* number of bytes on current block: client sets, xd3 verifies */ 608 xoff_t getblkno; /* request block number: xd3 sets current getblk request */
609 const uint8_t *curblk; /* current block array: client sets after getblk request */ 609
610}; 610 /* getblk sets */
611 611 xoff_t curblkno; /* current block number: client sets after getblk request */
612/* The primary xd3_stream object, used for encoding and decoding. You may access only two 612 usize_t onblk; /* number of bytes on current block: client sets, xd3 verifies */
613 * fields: avail_out, next_out. Use the methods above to operate on xd3_stream. */ 613 const uint8_t *curblk; /* current block array: client sets after getblk request */
614struct _xd3_stream 614};
615{ 615
616 /* input state */ 616/* The primary xd3_stream object, used for encoding and decoding. You may access only two
617 const uint8_t *next_in; /* next input byte */ 617 * fields: avail_out, next_out. Use the methods above to operate on xd3_stream. */
618 usize_t avail_in; /* number of bytes available at next_in */ 618struct _xd3_stream
619 xoff_t total_in; /* how many bytes in */ 619{
620 620 /* input state */
621 /* output state */ 621 const uint8_t *next_in; /* next input byte */
622 uint8_t *next_out; /* next output byte */ 622 usize_t avail_in; /* number of bytes available at next_in */
623 usize_t avail_out; /* number of bytes available at next_out */ 623 xoff_t total_in; /* how many bytes in */
624 usize_t space_out; /* total out space */ 624
625 xoff_t current_window; /* number of windows encoded/decoded */ 625 /* output state */
626 xoff_t total_out; /* how many bytes out */ 626 uint8_t *next_out; /* next output byte */
627 627 usize_t avail_out; /* number of bytes available at next_out */
628 /* to indicate an error, xd3 sets */ 628 usize_t space_out; /* total out space */
629 const char *msg; /* last error message, NULL if no error */ 629 xoff_t current_window; /* number of windows encoded/decoded */
630 630 xoff_t total_out; /* how many bytes out */
631 /* source configuration */ 631
632 xd3_source *src; /* source array */ 632 /* to indicate an error, xd3 sets */
633 633 const char *msg; /* last error message, NULL if no error */
634 /* encoder memory configuration */ 634
635 usize_t winsize; /* suggested window size */ 635 /* source configuration */
636 usize_t memsize; /* memory size parameter */ 636 xd3_source *src; /* source array */
637 usize_t sprevsz; /* small string, previous window size (power of 2) */ 637
638 usize_t sprevmask; /* small string, previous window size mask */ 638 /* encoder memory configuration */
639 uint iopt_size; 639 usize_t winsize; /* suggested window size */
640 uint srcwin_size; 640 usize_t memsize; /* memory size parameter */
641 uint srcwin_maxsz; 641 usize_t sprevsz; /* small string, previous window size (power of 2) */
642 642 usize_t sprevmask; /* small string, previous window size mask */
643 /* general configuration */ 643 uint iopt_size;
644 xd3_getblk_func *getblk; /* set nxtblk, nxtblkno to scanblkno */ 644 uint srcwin_size;
645 xd3_alloc_func *alloc; /* malloc function */ 645 uint srcwin_maxsz;
646 xd3_free_func *free; /* free function */ 646
647 void* opaque; /* private data object passed to alloc, free, and getblk */ 647 /* general configuration */
648 int flags; /* various options */ 648 xd3_getblk_func *getblk; /* set nxtblk, nxtblkno to scanblkno */
649 649 xd3_alloc_func *alloc; /* malloc function */
650 /* secondary compressor configuration */ 650 xd3_free_func *free; /* free function */
651 xd3_sec_cfg sec_data; /* Secondary compressor config: data */ 651 void* opaque; /* private data object passed to alloc, free, and getblk */
652 xd3_sec_cfg sec_inst; /* Secondary compressor config: inst */ 652 int flags; /* various options */
653 xd3_sec_cfg sec_addr; /* Secondary compressor config: addr */ 653
654 654 /* secondary compressor configuration */
655 xd3_smatcher smatcher; 655 xd3_sec_cfg sec_data; /* Secondary compressor config: data */
656 656 xd3_sec_cfg sec_inst; /* Secondary compressor config: inst */
657 usize_t *large_table; /* table of large checksums */ 657 xd3_sec_cfg sec_addr; /* Secondary compressor config: addr */
658 xd3_hash_cfg large_hash; /* large hash config */ 658
659 659 xd3_smatcher smatcher;
660 usize_t *small_table; /* table of small checksums */ 660
661 xd3_slist *small_prev; /* table of previous offsets, circular linked list */ 661 usize_t *large_table; /* table of large checksums */
662 int small_reset; /* true if small table should be reset */ 662 xd3_hash_cfg large_hash; /* large hash config */
663 663
664 xd3_hash_cfg small_hash; /* small hash config */ 664 usize_t *small_table; /* table of small checksums */
665 xd3_addr_cache acache; /* the vcdiff address cache */ 665 xd3_slist *small_prev; /* table of previous offsets, circular linked list */
666 xd3_encode_state enc_state; /* state of the encoder */ 666 int small_reset; /* true if small table should be reset */
667 667
668 usize_t taroff; /* base offset of the target input */ 668 xd3_hash_cfg small_hash; /* small hash config */
669 usize_t input_position; /* current input position */ 669 xd3_addr_cache acache; /* the vcdiff address cache */
670 usize_t min_match; /* current minimum match length, avoids redundent matches */ 670 xd3_encode_state enc_state; /* state of the encoder */
671 usize_t unencoded_offset; /* current input, first unencoded offset. this value is <= the first 671
672 * instruction's position in the iopt buffer, if there is at least one 672 usize_t taroff; /* base offset of the target input */
673 * match in the buffer. */ 673 usize_t input_position; /* current input position */
674 674 usize_t min_match; /* current minimum match length, avoids redundent matches */
675 // SRCWIN 675 usize_t unencoded_offset; /* current input, first unencoded offset. this value is <= the first
676 // these variables plus srcwin_size, srcwin_maxsz above (set by config) 676 * instruction's position in the iopt buffer, if there is at least one
677 int srcwin_decided; /* boolean: true if the srclen,srcbase have been decided. */ 677 * match in the buffer. */
678 xoff_t srcwin_cksum_pos; /* Source checksum position */ 678
679 679 // SRCWIN
680 // MATCH 680 // these variables plus srcwin_size, srcwin_maxsz above (set by config)
681 xd3_match_state match_state; /* encoder match state */ 681 int srcwin_decided; /* boolean: true if the srclen,srcbase have been decided. */
682 xoff_t match_srcpos; /* current match source position relative to srcbase */ 682 xoff_t srcwin_cksum_pos; /* Source checksum position */
683 xoff_t match_minaddr; /* smallest matching address to set window params 683
684 * (reset each window xd3_encode_reset) */ 684 // MATCH
685 xoff_t match_maxaddr; /* largest matching address to set window params 685 xd3_match_state match_state; /* encoder match state */
686 * (reset each window xd3_encode_reset) */ 686 xoff_t match_srcpos; /* current match source position relative to srcbase */
687 usize_t match_back; /* match extends back so far */ 687 xoff_t match_minaddr; /* smallest matching address to set window params
688 usize_t match_maxback; /* match extends back maximum */ 688 * (reset each window xd3_encode_reset) */
689 usize_t match_fwd; /* match extends forward so far */ 689 xoff_t match_maxaddr; /* largest matching address to set window params
690 usize_t match_maxfwd; /* match extends forward maximum */ 690 * (reset each window xd3_encode_reset) */
691 691 usize_t match_back; /* match extends back so far */
692 xoff_t maxsrcaddr; /* address of the last source match (across windows) */ 692 usize_t match_maxback; /* match extends back maximum */
693 693 usize_t match_fwd; /* match extends forward so far */
694 uint8_t *buf_in; /* for saving buffered input */ 694 usize_t match_maxfwd; /* match extends forward maximum */
695 usize_t buf_avail; /* amount of saved input */ 695
696 const uint8_t *buf_leftover; /* leftover content of next_in (i.e., user's buffer) */ 696 xoff_t maxsrcaddr; /* address of the last source match (across windows) */
697 usize_t buf_leftavail; /* amount of leftover content */ 697
698 698 uint8_t *buf_in; /* for saving buffered input */
699 xd3_output *enc_current; /* current output buffer */ 699 usize_t buf_avail; /* amount of saved input */
700 xd3_output *enc_free; /* free output buffers */ 700 const uint8_t *buf_leftover; /* leftover content of next_in (i.e., user's buffer) */
701 xd3_output *enc_heads[4]; /* array of encoded outputs: head of chain */ 701 usize_t buf_leftavail; /* amount of leftover content */
702 xd3_output *enc_tails[4]; /* array of encoded outputs: tail of chain */ 702
703 703 xd3_output *enc_current; /* current output buffer */
704 xd3_iopt_buf iopt; /* instruction optimizing buffer */ 704 xd3_output *enc_free; /* free output buffers */
705 xd3_rinst *iout; /* next single instruction */ 705 xd3_output *enc_heads[4]; /* array of encoded outputs: head of chain */
706 706 xd3_output *enc_tails[4]; /* array of encoded outputs: tail of chain */
707 const uint8_t *enc_appheader; /* application header to encode */ 707
708 usize_t enc_appheadsz; /* application header size */ 708 xd3_iopt_buf iopt; /* instruction optimizing buffer */
709 709 xd3_rinst *iout; /* next single instruction */
710 /* decoder stuff */ 710
711 xd3_decode_state dec_state; /* current DEC_XXX value */ 711 const uint8_t *enc_appheader; /* application header to encode */
712 uint dec_hdr_ind; /* VCDIFF header indicator */ 712 usize_t enc_appheadsz; /* application header size */
713 uint dec_win_ind; /* VCDIFF window indicator */ 713
714 uint dec_del_ind; /* VCDIFF delta indicator */ 714 /* decoder stuff */
715 715 xd3_decode_state dec_state; /* current DEC_XXX value */
716 uint8_t dec_magic[4]; /* First four bytes */ 716 uint dec_hdr_ind; /* VCDIFF header indicator */
717 usize_t dec_magicbytes; /* Magic position. */ 717 uint dec_win_ind; /* VCDIFF window indicator */
718 718 uint dec_del_ind; /* VCDIFF delta indicator */
719 uint dec_secondid; /* Optional secondary compressor ID. */ 719
720 720 uint8_t dec_magic[4]; /* First four bytes */
721 usize_t dec_codetblsz; /* Optional code table: length. */ 721 usize_t dec_magicbytes; /* Magic position. */
722 uint8_t *dec_codetbl; /* Optional code table: storage. */ 722
723 usize_t dec_codetblbytes; /* Optional code table: position. */ 723 uint dec_secondid; /* Optional secondary compressor ID. */
724 724
725 usize_t dec_appheadsz; /* Optional application header: size. */ 725 usize_t dec_codetblsz; /* Optional code table: length. */
726 uint8_t *dec_appheader; /* Optional application header: storage */ 726 uint8_t *dec_codetbl; /* Optional code table: storage. */
727 usize_t dec_appheadbytes; /* Optional application header: position. */ 727 usize_t dec_codetblbytes; /* Optional code table: position. */
728 728
729 usize_t dec_cksumbytes; /* Optional checksum: position. */ 729 usize_t dec_appheadsz; /* Optional application header: size. */
730 uint8_t dec_cksum[4]; /* Optional checksum: storage. */ 730 uint8_t *dec_appheader; /* Optional application header: storage */
731 uint32_t dec_adler32; /* Optional checksum: value. */ 731 usize_t dec_appheadbytes; /* Optional application header: position. */
732 732
733 usize_t dec_cpylen; /* length of copy window (VCD_SOURCE or VCD_TARGET) */ 733 usize_t dec_cksumbytes; /* Optional checksum: position. */
734 xoff_t dec_cpyoff; /* offset of copy window (VCD_SOURCE or VCD_TARGET) */ 734 uint8_t dec_cksum[4]; /* Optional checksum: storage. */
735 usize_t dec_enclen; /* length of delta encoding */ 735 uint32_t dec_adler32; /* Optional checksum: value. */
736 usize_t dec_tgtlen; /* length of target window */ 736
737 737 usize_t dec_cpylen; /* length of copy window (VCD_SOURCE or VCD_TARGET) */
738#if USE_UINT64 738 xoff_t dec_cpyoff; /* offset of copy window (VCD_SOURCE or VCD_TARGET) */
739 uint64_t dec_64part; /* part of a decoded uint64_t */ 739 usize_t dec_enclen; /* length of delta encoding */
740#endif 740 usize_t dec_tgtlen; /* length of target window */
741#if USE_UINT32 741
742 uint32_t dec_32part; /* part of a decoded uint32_t */ 742#if USE_UINT64
743#endif 743 uint64_t dec_64part; /* part of a decoded uint64_t */
744 744#endif
745 xoff_t dec_winstart; /* offset of the start of current target window */ 745#if USE_UINT32
746 xoff_t dec_window_count; /* == current_window + 1 in DEC_FINISH */ 746 uint32_t dec_32part; /* part of a decoded uint32_t */
747 usize_t dec_winbytes; /* bytes of the three sections so far consumed */ 747#endif
748 usize_t dec_hdrsize; /* VCDIFF + app header size */ 748
749 749 xoff_t dec_winstart; /* offset of the start of current target window */
750 const uint8_t *dec_tgtaddrbase; /* Base of decoded target addresses (addr >= dec_cpylen). */ 750 xoff_t dec_window_count; /* == current_window + 1 in DEC_FINISH */
751 const uint8_t *dec_cpyaddrbase; /* Base of decoded copy addresses (addr < dec_cpylen). */ 751 usize_t dec_winbytes; /* bytes of the three sections so far consumed */
752 752 usize_t dec_hdrsize; /* VCDIFF + app header size */
753 usize_t dec_position; /* current decoder position counting the cpylen offset */ 753
754 usize_t dec_maxpos; /* maximum decoder position counting the cpylen offset */ 754 const uint8_t *dec_tgtaddrbase; /* Base of decoded target addresses (addr >= dec_cpylen). */
755 xd3_hinst dec_current1; /* current instruction */ 755 const uint8_t *dec_cpyaddrbase; /* Base of decoded copy addresses (addr < dec_cpylen). */
756 xd3_hinst dec_current2; /* current instruction */ 756
757 757 usize_t dec_position; /* current decoder position counting the cpylen offset */
758 uint8_t *dec_buffer; /* Decode buffer */ 758 usize_t dec_maxpos; /* maximum decoder position counting the cpylen offset */
759 uint8_t *dec_lastwin; /* In case of VCD_TARGET, the last target window. */ 759 xd3_hinst dec_current1; /* current instruction */
760 usize_t dec_lastlen; /* length of the last target window */ 760 xd3_hinst dec_current2; /* current instruction */
761 xoff_t dec_laststart; /* offset of the start of last target window */ 761
762 usize_t dec_lastspace; /* allocated space of last target window, for reuse */ 762 uint8_t *dec_buffer; /* Decode buffer */
763 763 uint8_t *dec_lastwin; /* In case of VCD_TARGET, the last target window. */
764 xd3_desect inst_sect; /* staging area for decoding window sections */ 764 usize_t dec_lastlen; /* length of the last target window */
765 xd3_desect addr_sect; 765 xoff_t dec_laststart; /* offset of the start of last target window */
766 xd3_desect data_sect; 766 usize_t dec_lastspace; /* allocated space of last target window, for reuse */
767 767
768 xd3_code_table_func *code_table_func; 768 xd3_desect inst_sect; /* staging area for decoding window sections */
769 xd3_comp_table_func *comp_table_func; 769 xd3_desect addr_sect;
770 const xd3_dinst *code_table; 770 xd3_desect data_sect;
771 const xd3_code_table_desc *code_table_desc; 771
772 xd3_dinst *code_table_alloc; 772 xd3_code_table_func *code_table_func;
773 773 xd3_comp_table_func *comp_table_func;
774 /* secondary compression */ 774 const xd3_dinst *code_table;
775 const xd3_sec_type *sec_type; 775 const xd3_code_table_desc *code_table_desc;
776 xd3_sec_stream *sec_stream_d; 776 xd3_dinst *code_table_alloc;
777 xd3_sec_stream *sec_stream_i; 777
778 xd3_sec_stream *sec_stream_a; 778 /* secondary compression */
779 779 const xd3_sec_type *sec_type;
780#if XD3_DEBUG 780 xd3_sec_stream *sec_stream_d;
781 /* statistics */ 781 xd3_sec_stream *sec_stream_i;
782 usize_t n_cpy; 782 xd3_sec_stream *sec_stream_a;
783 usize_t n_add; 783
784 usize_t n_run; 784#if XD3_DEBUG
785 785 /* statistics */
786 usize_t n_ibytes; 786 usize_t n_cpy;
787 usize_t n_sbytes; 787 usize_t n_add;
788 usize_t n_dbytes; 788 usize_t n_run;
789 789
790 usize_t l_cpy; 790 usize_t n_ibytes;
791 usize_t l_add; 791 usize_t n_sbytes;
792 usize_t l_run; 792 usize_t n_dbytes;
793 793
794 usize_t sh_searches; 794 usize_t l_cpy;
795 usize_t sh_compares; 795 usize_t l_add;
796 796 usize_t l_run;
797 usize_t *i_freqs; 797
798 usize_t *i_modes; 798 usize_t sh_searches;
799 usize_t *i_sizes; 799 usize_t sh_compares;
800 800
801 usize_t large_ckcnt; 801 usize_t *i_freqs;
802 802 usize_t *i_modes;
803 /* memory usage */ 803 usize_t *i_sizes;
804 usize_t alloc_cnt; 804
805 usize_t free_cnt; 805 usize_t large_ckcnt;
806 806
807 xoff_t n_emit; 807 /* memory usage */
808#endif 808 usize_t alloc_cnt;
809}; 809 usize_t free_cnt;
810 810
811/****************************************************************************************** 811 xoff_t n_emit;
812 PUBLIC FUNCTIONS 812#endif
813 ******************************************************************************************/ 813};
814 814
815/* The two I/O disciplines, encode and decode, have similar stream semantics. It is 815/******************************************************************************************
816 * recommended that applications use the same code for compression and decompression - 816 PUBLIC FUNCTIONS
817 * because there are only a few differences in handling encoding/decoding. 817 ******************************************************************************************/
818 * 818
819 * See also the xd3_avail_input() and xd3_consume_output() routines, inlined below. 819/* The two I/O disciplines, encode and decode, have similar stream semantics. It is
820 * 820 * recommended that applications use the same code for compression and decompression -
821 * XD3_INPUT: the process requires more input: call xd3_avail_input() then repeat 821 * because there are only a few differences in handling encoding/decoding.
822 * XD3_OUTPUT: the process has more output: read stream->next_out, stream->avail_out, 822 *
823 * then call xd3_consume_output(), then repeat 823 * See also the xd3_avail_input() and xd3_consume_output() routines, inlined below.
824 * XD3_GOTHEADER: (decoder-only) notification returned following the VCDIFF header and 824 *
825 * first window header. the decoder may use the header to configure itself. 825 * XD3_INPUT: the process requires more input: call xd3_avail_input() then repeat
826 * XD3_WINSTART: a general notification returned once for each window except the 0-th 826 * XD3_OUTPUT: the process has more output: read stream->next_out, stream->avail_out,
827 * window, which is implied by XD3_GOTHEADER. It is recommended to 827 * then call xd3_consume_output(), then repeat
828 * use a switch-stmt such as: 828 * XD3_GOTHEADER: (decoder-only) notification returned following the VCDIFF header and
829 * ... 829 * first window header. the decoder may use the header to configure itself.
830 * again: 830 * XD3_WINSTART: a general notification returned once for each window except the 0-th
831 * switch ((ret = xd3_decode_input (stream))) { 831 * window, which is implied by XD3_GOTHEADER. It is recommended to
832 * case XD3_GOTHEADER: { 832 * use a switch-stmt such as:
833 * assert(stream->current_window == 0); 833 * ...
834 * stuff; 834 * again:
835 * } 835 * switch ((ret = xd3_decode_input (stream))) {
836 * // fallthrough 836 * case XD3_GOTHEADER: {
837 * case XD3_WINSTART: { 837 * assert(stream->current_window == 0);
838 * something(stream->current_window); 838 * stuff;
839 * goto again; 839 * }
840 * } 840 * // fallthrough
841 * ... 841 * case XD3_WINSTART: {
842 * XD3_WINFINISH: a general notification, following the complete input & output of a 842 * something(stream->current_window);
843 * window. at this point, stream->total_in and stream->total_out are 843 * goto again;
844 * consistent for either encoding or decoding. 844 * }
845 * XD3_GETSRCBLK: If the xd3_getblk() callback is NULL, this value is returned to 845 * ...
846 * initiate a non-blocking source read. 846 * XD3_WINFINISH: a general notification, following the complete input & output of a
847 * 847 * window. at this point, stream->total_in and stream->total_out are
848 * For simple usage, see the xd3_process_completely() function, which underlies 848 * consistent for either encoding or decoding.
849 * xd3_encode_completely() and xd3_decode_completely() [xdelta3.c]. For real application 849 * XD3_GETSRCBLK: If the xd3_getblk() callback is NULL, this value is returned to
850 * usage, including the application header, the see command-line utility [xdelta3-main.h]. 850 * initiate a non-blocking source read.
851 * 851 *
852 * main_input() implements the command-line encode and decode as well as the optional 852 * For simple usage, see the xd3_process_completely() function, which underlies
853 * VCDIFF_TOOLS printhdr, printhdrs, and printdelta with a single loop [xdelta3-main.h]. 853 * xd3_encode_completely() and xd3_decode_completely() [xdelta3.c]. For real application
854 */ 854 * usage, including the application header, the see command-line utility [xdelta3-main.h].
855int xd3_decode_input (xd3_stream *stream); 855 *
856int xd3_encode_input (xd3_stream *stream); 856 * main_input() implements the command-line encode and decode as well as the optional
857 857 * VCDIFF_TOOLS printhdr, printhdrs, and printdelta with a single loop [xdelta3-main.h].
858/* The xd3_config structure is used to initialize a stream - all data is copied into 858 */
859 * stream so config may be a temporary variable. See the [documentation] or comments on 859int xd3_decode_input (xd3_stream *stream);
860 * the xd3_config structure. */ 860int xd3_encode_input (xd3_stream *stream);
861int xd3_config_stream (xd3_stream *stream, 861
862 xd3_config *config); 862/* The xd3_config structure is used to initialize a stream - all data is copied into
863 863 * stream so config may be a temporary variable. See the [documentation] or comments on
864/* Since Xdelta3 doesn't open any files, xd3_close_stream is just an error check that the 864 * the xd3_config structure. */
865 * stream is in a proper state to be closed: this means the encoder is flushed and the 865int xd3_config_stream (xd3_stream *stream,
866 * decoder is at a window boundary. The application is responsible for freeing any of the 866 xd3_config *config);
867 * resources it supplied. */ 867
868int xd3_close_stream (xd3_stream *stream); 868/* Since Xdelta3 doesn't open any files, xd3_close_stream is just an error check that the
869 869 * stream is in a proper state to be closed: this means the encoder is flushed and the
870/* This unconditionally closes/frees the stream, future close() will succeed.*/ 870 * decoder is at a window boundary. The application is responsible for freeing any of the
871void xd3_abort_stream (xd3_stream *stream); 871 * resources it supplied. */
872 872int xd3_close_stream (xd3_stream *stream);
873/* xd3_free_stream frees all memory allocated for the stream. The application is 873
874 * responsible for freeing any of the resources it supplied. */ 874/* This unconditionally closes/frees the stream, future close() will succeed.*/
875void xd3_free_stream (xd3_stream *stream); 875void xd3_abort_stream (xd3_stream *stream);
876 876
877/* This function informs the encoder or decoder that source matching (i.e., 877/* xd3_free_stream frees all memory allocated for the stream. The application is
878 * delta-compression) is possible. For encoding, this should be called before the first 878 * responsible for freeing any of the resources it supplied. */
879 * xd3_encode_input. A NULL source is ignored. For decoding, this should be called 879void xd3_free_stream (xd3_stream *stream);
880 * before the first window is decoded, but the appheader may be read first 880
881 * (XD3_GOTHEADER). At this point, consult xd3_decoder_needs_source(), inlined below, to 881/* This function informs the encoder or decoder that source matching (i.e.,
882 * determine if a source is expected by the decoder. */ 882 * delta-compression) is possible. For encoding, this should be called before the first
883int xd3_set_source (xd3_stream *stream, 883 * xd3_encode_input. A NULL source is ignored. For decoding, this should be called
884 xd3_source *source); 884 * before the first window is decoded, but the appheader may be read first
885 885 * (XD3_GOTHEADER). At this point, consult xd3_decoder_needs_source(), inlined below, to
886/* This function invokes xd3_encode_input using whole-file, in-memory inputs. The output 886 * determine if a source is expected by the decoder. */
887 * array must be large enough to hold the output or else ENOSPC is returned. */ 887int xd3_set_source (xd3_stream *stream,
888int xd3_encode_completely (xd3_stream *stream, 888 xd3_source *source);
889 const uint8_t *input, 889
890 usize_t input_size, 890/* This function invokes xd3_encode_input using whole-file, in-memory inputs. The output
891 uint8_t *output, 891 * array must be large enough to hold the output or else ENOSPC is returned. */
892 usize_t *output_size, 892int xd3_encode_completely (xd3_stream *stream,
893 usize_t avail_output); 893 const uint8_t *input,
894 894 usize_t input_size,
895/* This function invokes xd3_decode_input using whole-file, in-memory inputs. The output 895 uint8_t *output,
896 * array must be large enough to hold the output or else ENOSPC is returned. */ 896 usize_t *output_size,
897int xd3_decode_completely (xd3_stream *stream, 897 usize_t avail_output);
898 const uint8_t *input, 898
899 usize_t input_size, 899/* This function invokes xd3_decode_input using whole-file, in-memory inputs. The output
900 uint8_t *output, 900 * array must be large enough to hold the output or else ENOSPC is returned. */
901 usize_t *output_size, 901int xd3_decode_completely (xd3_stream *stream,
902 usize_t avail_size); 902 const uint8_t *input,
903 903 usize_t input_size,
904/* This should be called before the first call to xd3_encode_input() to include 904 uint8_t *output,
905 * application-specific data in the VCDIFF header. */ 905 usize_t *output_size,
906void xd3_set_appheader (xd3_stream *stream, 906 usize_t avail_size);
907 const uint8_t *data, 907
908 usize_t size); 908/* This should be called before the first call to xd3_encode_input() to include
909 909 * application-specific data in the VCDIFF header. */
910/* xd3_get_appheader may be called in the decoder after XD3_GOTHEADER. For convenience, 910void xd3_set_appheader (xd3_stream *stream,
911 * the decoder always adds a single byte padding to the end of the application header, 911 const uint8_t *data,
912 * which is set to zero in case the application header is a string. */ 912 usize_t size);
913int xd3_get_appheader (xd3_stream *stream, 913
914 uint8_t **data, 914/* xd3_get_appheader may be called in the decoder after XD3_GOTHEADER. For convenience,
915 usize_t *size); 915 * the decoder always adds a single byte padding to the end of the application header,
916 916 * which is set to zero in case the application header is a string. */
917/* After receiving XD3_GOTHEADER, the decoder should check this function which returns 1 917int xd3_get_appheader (xd3_stream *stream,
918 * if the decoder will require source data. */ 918 uint8_t **data,
919int xd3_decoder_needs_source (xd3_stream *stream); 919 usize_t *size);
920 920
921/* Includes the above rvalues */ 921/* After receiving XD3_GOTHEADER, the decoder should check this function which returns 1
922const char* xd3_strerror (int ret); 922 * if the decoder will require source data. */
923 923int xd3_decoder_needs_source (xd3_stream *stream);
924/* For convenience, zero & initialize the xd3_config structure with specified flags. */ 924
925static inline 925/* Includes the above rvalues */
926void xd3_init_config (xd3_config *config, 926const char* xd3_strerror (int ret);
927 int flags) 927
928{ 928/* For convenience, zero & initialize the xd3_config structure with specified flags. */
929 memset (config, 0, sizeof (*config)); 929static inline
930 config->flags = flags; 930void xd3_init_config (xd3_config *config,
931} 931 int flags)
932 932{
933/* This supplies some input to the stream. */ 933 memset (config, 0, sizeof (*config));
934static inline 934 config->flags = flags;
935void xd3_avail_input (xd3_stream *stream, 935}
936 const uint8_t *idata, 936
937 usize_t isize) 937/* This supplies some input to the stream. */
938{ 938static inline
939 /* Even if isize is zero, the code expects a non-NULL idata. Why? It uses this value 939void xd3_avail_input (xd3_stream *stream,
940 * to determine whether xd3_avail_input has ever been called. If xd3_encode_input is 940 const uint8_t *idata,
941 * called before xd3_avail_input it will return XD3_INPUT right away without allocating 941 usize_t isize)
942 * a stream->winsize buffer. This is to avoid an unwanted allocation. */ 942{
943 XD3_ASSERT (idata != NULL); 943 /* Even if isize is zero, the code expects a non-NULL idata. Why? It uses this value
944 944 * to determine whether xd3_avail_input has ever been called. If xd3_encode_input is
945 stream->next_in = idata; 945 * called before xd3_avail_input it will return XD3_INPUT right away without allocating
946 stream->avail_in = isize; 946 * a stream->winsize buffer. This is to avoid an unwanted allocation. */
947} 947 XD3_ASSERT (idata != NULL);
948 948
949/* This acknowledges receipt of output data, must be called after any XD3_OUTPUT 949 stream->next_in = idata;
950 * return. */ 950 stream->avail_in = isize;
951static inline 951}
952void xd3_consume_output (xd3_stream *stream) 952
953{ 953/* This acknowledges receipt of output data, must be called after any XD3_OUTPUT
954 stream->avail_out = 0; 954 * return. */
955} 955static inline
956 956void xd3_consume_output (xd3_stream *stream)
957/* These are set for each XD3_WINFINISH return. */ 957{
958static inline 958 stream->avail_out = 0;
959int xd3_encoder_used_source (xd3_stream *stream) { return stream->src != NULL && stream->src->srclen > 0; } 959}
960static inline 960
961xoff_t xd3_encoder_srcbase (xd3_stream *stream) { return stream->src->srcbase; } 961/* These are set for each XD3_WINFINISH return. */
962static inline 962static inline
963usize_t xd3_encoder_srclen (xd3_stream *stream) { return stream->src->srclen; } 963int xd3_encoder_used_source (xd3_stream *stream) { return stream->src != NULL && stream->src->srclen > 0; }
964 964static inline
965/* Checks for legal flag changes. */ 965xoff_t xd3_encoder_srcbase (xd3_stream *stream) { return stream->src->srcbase; }
966static inline 966static inline
967void xd3_set_flags (xd3_stream *stream, int flags) 967usize_t xd3_encoder_srclen (xd3_stream *stream) { return stream->src->srclen; }
968{ 968
969 /* The bitwise difference should contain only XD3_FLUSH or XD3_SKIP_WINDOW */ 969/* Checks for legal flag changes. */
970 XD3_ASSERT(((flags ^ stream->flags) & ~(XD3_FLUSH | XD3_SKIP_WINDOW)) == 0); 970static inline
971 stream->flags = flags; 971void xd3_set_flags (xd3_stream *stream, int flags)
972} 972{
973 973 /* The bitwise difference should contain only XD3_FLUSH or XD3_SKIP_WINDOW */
974/* Gives some extra information about the latest library error, if any is known. */ 974 XD3_ASSERT(((flags ^ stream->flags) & ~(XD3_FLUSH | XD3_SKIP_WINDOW)) == 0);
975static inline 975 stream->flags = flags;
976const char* xd3_errstring (xd3_stream *stream) 976}
977{ 977
978 return stream->msg ? stream->msg : ""; 978/* Gives some extra information about the latest library error, if any is known. */
979} 979static inline
980 980const char* xd3_errstring (xd3_stream *stream)
981/* This function tells the number of bytes expected to be set in source->onblk after a 981{
982 * getblk request. This is for convenience of handling a partial last block. */ 982 return stream->msg ? stream->msg : "";
983static inline 983}
984usize_t xd3_bytes_on_srcblk (xd3_source *source, xoff_t blkno) 984
985{ 985/* This function tells the number of bytes expected to be set in source->onblk after a
986 XD3_ASSERT (blkno < source->blocks); 986 * getblk request. This is for convenience of handling a partial last block. */
987 987static inline
988 if (blkno != source->blocks - 1) 988usize_t xd3_bytes_on_srcblk (xd3_source *source, xoff_t blkno)
989 { 989{
990 return source->blksize; 990 XD3_ASSERT (blkno < source->blocks);
991 } 991
992 992 if (blkno != source->blocks - 1)
993 return (usize_t)((source->size - 1) % source->blksize) + 1; 993 {
994} 994 return source->blksize;
995 995 }
996#endif /* _XDELTA3_H_ */ 996
997 return (usize_t)((source->size - 1) % source->blksize) + 1;
998}
999
1000#endif /* _XDELTA3_H_ */