diff options
Diffstat (limited to 'xdelta3')
-rw-r--r-- | xdelta3/Makefile | 13 | ||||
-rw-r--r-- | xdelta3/examples/speed_test.c | 2 | ||||
-rw-r--r-- | xdelta3/xdelta3-main.h | 5 | ||||
-rw-r--r-- | xdelta3/xdelta3-second.h | 13 | ||||
-rw-r--r-- | xdelta3/xdelta3-test.h | 179 | ||||
-rw-r--r-- | xdelta3/xdelta3.c | 25 | ||||
-rw-r--r-- | xdelta3/xdelta3.h | 354 |
7 files changed, 341 insertions, 250 deletions
diff --git a/xdelta3/Makefile b/xdelta3/Makefile index 36f03b1..40647e8 100644 --- a/xdelta3/Makefile +++ b/xdelta3/Makefile | |||
@@ -114,6 +114,16 @@ xdelta3: $(SOURCES) | |||
114 | -DXD3_MAIN=1 \ | 114 | -DXD3_MAIN=1 \ |
115 | -DXD3_POSIX=1 | 115 | -DXD3_POSIX=1 |
116 | 116 | ||
117 | xdelta3-32: $(SOURCES) | ||
118 | $(CC) -g -Wall -Wshadow xdelta3.c -lm -o xdelta3-32 \ | ||
119 | -DXD3_DEBUG=1 \ | ||
120 | -DXD3_USE_LARGEFILE64=0 \ | ||
121 | -DREGRESSION_TEST=1 \ | ||
122 | -DSECONDARY_DJW=1 \ | ||
123 | -DSECONDARY_FGK=1 \ | ||
124 | -DXD3_MAIN=1 \ | ||
125 | -DXD3_POSIX=1 | ||
126 | |||
117 | xdelta3-debug: $(SOURCES) | 127 | xdelta3-debug: $(SOURCES) |
118 | $(CC) -g -Wall -Wshadow xdelta3.c -o xdelta3-debug -DXD3_MAIN=1 -DGENERIC_ENCODE_TABLES=1 \ | 128 | $(CC) -g -Wall -Wshadow xdelta3.c -o xdelta3-debug -DXD3_MAIN=1 -DGENERIC_ENCODE_TABLES=1 \ |
119 | -DXD3_USE_LARGEFILE64=1 -DXD3_STDIO=1 -DREGRESSION_TEST=1 -DXD3_DEBUG=1 -DSECONDARY_DJW=1 -DSECONDARY_FGK=1 -lm | 129 | -DXD3_USE_LARGEFILE64=1 -DXD3_STDIO=1 -DREGRESSION_TEST=1 -DXD3_DEBUG=1 -DSECONDARY_DJW=1 -DSECONDARY_FGK=1 -lm |
@@ -162,9 +172,6 @@ xdelta3-decoder-nomain.o: $(SOURCES) linkxd3lib.c | |||
162 | -o xdelta3-decoder-nomain.o | 172 | -o xdelta3-decoder-nomain.o |
163 | strip xdelta3-decoder-nomain.o | 173 | strip xdelta3-decoder-nomain.o |
164 | 174 | ||
165 | xdelta3-32: $(SOURCES) | ||
166 | $(CC) -g -O2 -Wall -Wshadow xdelta3.c -o xdelta3-32 -DXD3_MAIN=1 -DSECONDARY_DJW=1 -DREGRESSION_TEST=1 -lm | ||
167 | |||
168 | xdelta3-O++: $(SOURCES) | 175 | xdelta3-O++: $(SOURCES) |
169 | $(CXX) -g -O2 -Wall -Wshadow xdelta3.c -o xdelta3-O++ -DXD3_MAIN=1 -DSECONDARY_DJW=1 -DREGRESSION_TEST=1 -lm | 176 | $(CXX) -g -O2 -Wall -Wshadow xdelta3.c -o xdelta3-O++ -DXD3_MAIN=1 -DSECONDARY_DJW=1 -DREGRESSION_TEST=1 -lm |
170 | 177 | ||
diff --git a/xdelta3/examples/speed_test.c b/xdelta3/examples/speed_test.c index 9e5a91f..58e9aca 100644 --- a/xdelta3/examples/speed_test.c +++ b/xdelta3/examples/speed_test.c | |||
@@ -13,7 +13,7 @@ usize_t bench_speed(const uint8_t *from_buf, const size_t from_len, | |||
13 | int ret = xd3_encode_memory(to_buf, to_len, from_buf, from_len, | 13 | int ret = xd3_encode_memory(to_buf, to_len, from_buf, from_len, |
14 | delta_buf, &delta_size, delta_alloc, flags); | 14 | delta_buf, &delta_size, delta_alloc, flags); |
15 | if (ret != 0) { | 15 | if (ret != 0) { |
16 | fprintf(stderr, "encode failure: %d\n", ret); | 16 | fprintf(stderr, "encode failure: %d: %s\n", ret, xd3_strerror(ret)); |
17 | abort(); | 17 | abort(); |
18 | } | 18 | } |
19 | return delta_size; | 19 | return delta_size; |
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h index 36de366..3cb4a5d 100644 --- a/xdelta3/xdelta3-main.h +++ b/xdelta3/xdelta3-main.h | |||
@@ -368,6 +368,11 @@ main_config (void) | |||
368 | DP(RINT "XD3_DEFAULT_SRCWINSZ=%d\n", XD3_DEFAULT_SRCWINSZ); | 368 | DP(RINT "XD3_DEFAULT_SRCWINSZ=%d\n", XD3_DEFAULT_SRCWINSZ); |
369 | DP(RINT "XD3_DEFAULT_WINSIZE=%d\n", XD3_DEFAULT_WINSIZE); | 369 | DP(RINT "XD3_DEFAULT_WINSIZE=%d\n", XD3_DEFAULT_WINSIZE); |
370 | DP(RINT "XD3_HARDMAXWINSIZE=%d\n", XD3_HARDMAXWINSIZE); | 370 | DP(RINT "XD3_HARDMAXWINSIZE=%d\n", XD3_HARDMAXWINSIZE); |
371 | DP(RINT "sizeof(int)=%d\n", sizeof(int)); | ||
372 | DP(RINT "sizeof(uint32_t)=%d\n", sizeof(uint32_t)); | ||
373 | DP(RINT "sizeof(uint64_t)=%d\n", sizeof(uint64_t)); | ||
374 | DP(RINT "sizeof(usize_t)=%d\n", sizeof(usize_t)); | ||
375 | DP(RINT "sizeof(xoff_t)=%d\n", sizeof(xoff_t)); | ||
371 | 376 | ||
372 | return EXIT_SUCCESS; | 377 | return EXIT_SUCCESS; |
373 | } | 378 | } |
diff --git a/xdelta3/xdelta3-second.h b/xdelta3/xdelta3-second.h index 3a91e10..a1fe120 100644 --- a/xdelta3/xdelta3-second.h +++ b/xdelta3/xdelta3-second.h | |||
@@ -19,9 +19,9 @@ | |||
19 | #ifndef _XDELTA3_SECOND_H_ | 19 | #ifndef _XDELTA3_SECOND_H_ |
20 | #define _XDELTA3_SECOND_H_ | 20 | #define _XDELTA3_SECOND_H_ |
21 | 21 | ||
22 | /****************************************************************************************** | 22 | /************************************************************** |
23 | Secondary compression | 23 | Secondary compression |
24 | ******************************************************************************************/ | 24 | **************************************************************/ |
25 | 25 | ||
26 | #define xd3_sec_data(s) ((s)->sec_stream_d) | 26 | #define xd3_sec_data(s) ((s)->sec_stream_d) |
27 | #define xd3_sec_inst(s) ((s)->sec_stream_i) | 27 | #define xd3_sec_inst(s) ((s)->sec_stream_i) |
@@ -291,13 +291,14 @@ xd3_encode_secondary (xd3_stream *stream, | |||
291 | 291 | ||
292 | tmp_head = xd3_alloc_output (stream, NULL); | 292 | tmp_head = xd3_alloc_output (stream, NULL); |
293 | 293 | ||
294 | /* Encode the size, encode the data. @@ Encoding the size makes it simpler, but is a | 294 | /* Encode the size, encode the data. @@ Encoding the size makes it |
295 | * little gross. Should not need the entire section in contiguous memory, but it is | 295 | * simpler, but is a little gross. Should not need the entire |
296 | * much easier this way. */ | 296 | * section in contiguous memory, but it is much easier this way. */ |
297 | if ((ret = xd3_emit_size (stream, & tmp_head, orig_size)) || | 297 | if ((ret = xd3_emit_size (stream, & tmp_head, orig_size)) || |
298 | (ret = stream->sec_type->encode (stream, sec_stream, *head, tmp_head, cfg))) { goto getout; } | 298 | (ret = stream->sec_type->encode (stream, sec_stream, *head, tmp_head, cfg))) { goto getout; } |
299 | 299 | ||
300 | /* If the secondary compressor determines its no good, it returns XD3_NOSECOND. */ | 300 | /* If the secondary compressor determines its no good, it returns |
301 | XD3_NOSECOND. */ | ||
301 | 302 | ||
302 | /* Setup tmp_tail, comp_size */ | 303 | /* Setup tmp_tail, comp_size */ |
303 | tmp_tail = tmp_head; | 304 | tmp_tail = tmp_head; |
diff --git a/xdelta3/xdelta3-test.h b/xdelta3/xdelta3-test.h index 9bc1ba4..f4fb76f 100644 --- a/xdelta3/xdelta3-test.h +++ b/xdelta3/xdelta3-test.h | |||
@@ -413,95 +413,96 @@ test_decode_integer_end_of_input (xd3_stream *stream, int unused) | |||
413 | return test_read_integer_error (stream, 1, "end-of-input in read_integer"); | 413 | return test_read_integer_error (stream, 1, "end-of-input in read_integer"); |
414 | } | 414 | } |
415 | 415 | ||
416 | /* Test that emit_integer/decode_integer/sizeof_integer/read_integer work on correct | 416 | /* Test that emit_integer/decode_integer/sizeof_integer/read_integer |
417 | * inputs. Tests powers of (2^7), plus or minus, up to the maximum value. */ | 417 | * work on correct inputs. Tests powers of (2^7), plus or minus, up |
418 | #define TEST_ENCODE_DECODE_INTEGER(TYPE,ONE,MAX) \ | 418 | * to the maximum value. */ |
419 | xd3_output *rbuf = NULL; \ | 419 | #define TEST_ENCODE_DECODE_INTEGER(TYPE,ONE,MAX) \ |
420 | xd3_output *dbuf = NULL; \ | 420 | xd3_output *rbuf = NULL; \ |
421 | TYPE values[64]; \ | 421 | xd3_output *dbuf = NULL; \ |
422 | int nvalues = 0; \ | 422 | TYPE values[64]; \ |
423 | int i, ret = 0; \ | 423 | int nvalues = 0; \ |
424 | \ | 424 | int i, ret = 0; \ |
425 | for (i = 0; i < (sizeof (TYPE) * 8); i += 7) \ | 425 | \ |
426 | { \ | 426 | for (i = 0; i < (sizeof (TYPE) * 8); i += 7) \ |
427 | values[nvalues++] = (ONE << i) - ONE; \ | 427 | { \ |
428 | values[nvalues++] = (ONE << i); \ | 428 | values[nvalues++] = (ONE << i) - ONE; \ |
429 | values[nvalues++] = (ONE << i) + ONE; \ | 429 | values[nvalues++] = (ONE << i); \ |
430 | } \ | 430 | values[nvalues++] = (ONE << i) + ONE; \ |
431 | \ | 431 | } \ |
432 | values[nvalues++] = MAX-ONE; \ | 432 | \ |
433 | values[nvalues++] = MAX; \ | 433 | values[nvalues++] = MAX-ONE; \ |
434 | \ | 434 | values[nvalues++] = MAX; \ |
435 | rbuf = xd3_alloc_output (stream, rbuf); \ | 435 | \ |
436 | dbuf = xd3_alloc_output (stream, dbuf); \ | 436 | rbuf = xd3_alloc_output (stream, rbuf); \ |
437 | \ | 437 | dbuf = xd3_alloc_output (stream, dbuf); \ |
438 | for (i = 0; i < nvalues; i += 1) \ | 438 | \ |
439 | { \ | 439 | for (i = 0; i < nvalues; i += 1) \ |
440 | const uint8_t *max; \ | 440 | { \ |
441 | const uint8_t *inp; \ | 441 | const uint8_t *max; \ |
442 | TYPE val; \ | 442 | const uint8_t *inp; \ |
443 | \ | 443 | TYPE val; \ |
444 | DOT (); \ | 444 | \ |
445 | rbuf->next = 0; \ | 445 | DOT (); \ |
446 | \ | 446 | rbuf->next = 0; \ |
447 | if ((ret = xd3_emit_ ## TYPE (stream, & rbuf, values[i])) || \ | 447 | \ |
448 | (ret = xd3_emit_ ## TYPE (stream, & dbuf, values[i]))) \ | 448 | if ((ret = xd3_emit_ ## TYPE (stream, & rbuf, values[i])) || \ |
449 | { \ | 449 | (ret = xd3_emit_ ## TYPE (stream, & dbuf, values[i]))) \ |
450 | goto fail; \ | 450 | { \ |
451 | } \ | 451 | goto fail; \ |
452 | \ | 452 | } \ |
453 | inp = rbuf->base; \ | 453 | \ |
454 | max = rbuf->base + rbuf->next; \ | 454 | inp = rbuf->base; \ |
455 | \ | 455 | max = rbuf->base + rbuf->next; \ |
456 | if (rbuf->next != xd3_sizeof_ ## TYPE (values[i])) \ | 456 | \ |
457 | { \ | 457 | if (rbuf->next != xd3_sizeof_ ## TYPE (values[i])) \ |
458 | ret = XD3_INTERNAL; \ | 458 | { \ |
459 | goto fail; \ | 459 | ret = XD3_INTERNAL; \ |
460 | } \ | 460 | goto fail; \ |
461 | \ | 461 | } \ |
462 | if ((ret = xd3_read_ ## TYPE (stream, & inp, max, & val))) \ | 462 | \ |
463 | { \ | 463 | if ((ret = xd3_read_ ## TYPE (stream, & inp, max, & val))) \ |
464 | goto fail; \ | 464 | { \ |
465 | } \ | 465 | goto fail; \ |
466 | \ | 466 | } \ |
467 | if (val != values[i]) \ | 467 | \ |
468 | { \ | 468 | if (val != values[i]) \ |
469 | ret = XD3_INTERNAL; \ | 469 | { \ |
470 | goto fail; \ | 470 | ret = XD3_INTERNAL; \ |
471 | } \ | 471 | goto fail; \ |
472 | \ | 472 | } \ |
473 | DOT (); \ | 473 | \ |
474 | } \ | 474 | DOT (); \ |
475 | \ | 475 | } \ |
476 | stream->next_in = dbuf->base; \ | 476 | \ |
477 | stream->avail_in = dbuf->next; \ | 477 | stream->next_in = dbuf->base; \ |
478 | \ | 478 | stream->avail_in = dbuf->next; \ |
479 | for (i = 0; i < nvalues; i += 1) \ | 479 | \ |
480 | { \ | 480 | for (i = 0; i < nvalues; i += 1) \ |
481 | TYPE val; \ | 481 | { \ |
482 | \ | 482 | TYPE val; \ |
483 | if ((ret = xd3_decode_ ## TYPE (stream, & val))) \ | 483 | \ |
484 | { \ | 484 | if ((ret = xd3_decode_ ## TYPE (stream, & val))) \ |
485 | goto fail; \ | 485 | { \ |
486 | } \ | 486 | goto fail; \ |
487 | \ | 487 | } \ |
488 | if (val != values[i]) \ | 488 | \ |
489 | { \ | 489 | if (val != values[i]) \ |
490 | ret = XD3_INTERNAL; \ | 490 | { \ |
491 | goto fail; \ | 491 | ret = XD3_INTERNAL; \ |
492 | } \ | 492 | goto fail; \ |
493 | } \ | 493 | } \ |
494 | \ | 494 | } \ |
495 | if (stream->avail_in != 0) \ | 495 | \ |
496 | { \ | 496 | if (stream->avail_in != 0) \ |
497 | ret = XD3_INTERNAL; \ | 497 | { \ |
498 | goto fail; \ | 498 | ret = XD3_INTERNAL; \ |
499 | } \ | 499 | goto fail; \ |
500 | \ | 500 | } \ |
501 | fail: \ | 501 | \ |
502 | xd3_free_output (stream, rbuf); \ | 502 | fail: \ |
503 | xd3_free_output (stream, dbuf); \ | 503 | xd3_free_output (stream, rbuf); \ |
504 | \ | 504 | xd3_free_output (stream, dbuf); \ |
505 | \ | ||
505 | return ret | 506 | return ret |
506 | 507 | ||
507 | static int | 508 | static int |
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index 9c8f6aa..8c536b3 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -1830,9 +1830,9 @@ xd3_emit_bytes (xd3_stream *stream, | |||
1830 | } | 1830 | } |
1831 | #endif /* XD3_ENCODER */ | 1831 | #endif /* XD3_ENCODER */ |
1832 | 1832 | ||
1833 | /****************************************************************************************** | 1833 | /********************************************************************* |
1834 | Integer encoder/decoder functions | 1834 | Integer encoder/decoder functions |
1835 | ******************************************************************************************/ | 1835 | **********************************************************************/ |
1836 | 1836 | ||
1837 | #define DECODE_INTEGER_TYPE(PART,OFLOW) \ | 1837 | #define DECODE_INTEGER_TYPE(PART,OFLOW) \ |
1838 | while (stream->avail_in != 0) \ | 1838 | while (stream->avail_in != 0) \ |
@@ -1930,7 +1930,8 @@ xd3_decode_uint32_t (xd3_stream *stream, uint32_t *val) | |||
1930 | { DECODE_INTEGER_TYPE (stream->dec_32part, UINT32_OFLOW_MASK); } | 1930 | { DECODE_INTEGER_TYPE (stream->dec_32part, UINT32_OFLOW_MASK); } |
1931 | 1931 | ||
1932 | static int | 1932 | static int |
1933 | xd3_read_uint32_t (xd3_stream *stream, const uint8_t **inpp, const uint8_t *max, uint32_t *valp) | 1933 | xd3_read_uint32_t (xd3_stream *stream, const uint8_t **inpp, |
1934 | const uint8_t *max, uint32_t *valp) | ||
1934 | { READ_INTEGER_TYPE (uint32_t, UINT32_OFLOW_MASK); } | 1935 | { READ_INTEGER_TYPE (uint32_t, UINT32_OFLOW_MASK); } |
1935 | 1936 | ||
1936 | #if XD3_ENCODER | 1937 | #if XD3_ENCODER |
@@ -1954,7 +1955,8 @@ xd3_emit_uint64_t (xd3_stream *stream, xd3_output **output, uint64_t num) | |||
1954 | /* These are tested but not used */ | 1955 | /* These are tested but not used */ |
1955 | #if REGRESSION_TEST | 1956 | #if REGRESSION_TEST |
1956 | static int | 1957 | static int |
1957 | xd3_read_uint64_t (xd3_stream *stream, const uint8_t **inpp, const uint8_t *max, uint64_t *valp) | 1958 | xd3_read_uint64_t (xd3_stream *stream, const uint8_t **inpp, |
1959 | const uint8_t *max, uint64_t *valp) | ||
1958 | { READ_INTEGER_TYPE (uint64_t, UINT64_OFLOW_MASK); } | 1960 | { READ_INTEGER_TYPE (uint64_t, UINT64_OFLOW_MASK); } |
1959 | 1961 | ||
1960 | static uint | 1962 | static uint |
@@ -3935,14 +3937,15 @@ xd3_process_memory (int is_encode, | |||
3935 | xd3_source src; | 3937 | xd3_source src; |
3936 | int ret; | 3938 | int ret; |
3937 | 3939 | ||
3940 | memset (& stream, 0, sizeof (stream)); | ||
3941 | memset (& config, 0, sizeof (config)); | ||
3942 | |||
3938 | if (input == NULL || output == NULL) { | 3943 | if (input == NULL || output == NULL) { |
3939 | stream.msg = "invalid input/output buffer"; | 3944 | stream.msg = "invalid input/output buffer"; |
3940 | return XD3_INTERNAL; | 3945 | ret = XD3_INTERNAL; |
3946 | goto exit; | ||
3941 | } | 3947 | } |
3942 | 3948 | ||
3943 | memset (& stream, 0, sizeof (stream)); | ||
3944 | memset (& config, 0, sizeof (config)); | ||
3945 | |||
3946 | config.flags = flags; | 3949 | config.flags = flags; |
3947 | 3950 | ||
3948 | if (is_encode) | 3951 | if (is_encode) |
@@ -3992,6 +3995,9 @@ xd3_process_memory (int is_encode, | |||
3992 | } | 3995 | } |
3993 | 3996 | ||
3994 | exit: | 3997 | exit: |
3998 | if (ret != 0) { | ||
3999 | IF_DEBUG1 (DP(RINT "process_memory: %d: %s", ret, stream.msg)); | ||
4000 | } | ||
3995 | xd3_free_stream(&stream); | 4001 | xd3_free_stream(&stream); |
3996 | return ret; | 4002 | return ret; |
3997 | } | 4003 | } |
@@ -4178,7 +4184,8 @@ xd3_srcwin_setup (xd3_stream *stream) | |||
4178 | * and related parameters are extreme - should use smaller windows. */ | 4184 | * and related parameters are extreme - should use smaller windows. */ |
4179 | length = stream->match_maxaddr - stream->match_minaddr; | 4185 | length = stream->match_maxaddr - stream->match_minaddr; |
4180 | 4186 | ||
4181 | if (length > (xoff_t) USIZE_T_MAX) | 4187 | xoff_t x = (xoff_t) USIZE_T_MAX; |
4188 | if (length > x) | ||
4182 | { | 4189 | { |
4183 | stream->msg = "source window length overflow (not 64bit)"; | 4190 | stream->msg = "source window length overflow (not 64bit)"; |
4184 | return XD3_INTERNAL; | 4191 | return XD3_INTERNAL; |
diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h index a76a124..cd7a2a0 100644 --- a/xdelta3/xdelta3.h +++ b/xdelta3/xdelta3.h | |||
@@ -16,10 +16,10 @@ | |||
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 | /* To know more about Xdelta, start by reading xdelta3.c. If you are |
20 | * If you are ready to use the API, continue reading here. There are two interfaces -- | 20 | * ready to use the API, continue reading here. There are two |
21 | * xd3_encode_input and xd3_decode_input -- plus a dozen or so related calls. This | 21 | * interfaces -- xd3_encode_input and xd3_decode_input -- plus a dozen |
22 | * interface is styled after Zlib. */ | 22 | * or so related calls. This interface is styled after Zlib. */ |
23 | 23 | ||
24 | #ifndef _XDELTA3_H_ | 24 | #ifndef _XDELTA3_H_ |
25 | #define _XDELTA3_H_ | 25 | #define _XDELTA3_H_ |
@@ -28,11 +28,12 @@ | |||
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 |
34 | * xd3_encode_input() with data smaller than winsize the stream will | 34 | * supplies xd3_encode_input() with data smaller than winsize the |
35 | * automatically buffer the input, otherwise the input buffer is used directly. | 35 | * stream will automatically buffer the input, otherwise the input |
36 | * buffer is used directly. | ||
36 | */ | 37 | */ |
37 | #ifndef XD3_DEFAULT_WINSIZE | 38 | #ifndef XD3_DEFAULT_WINSIZE |
38 | #define XD3_DEFAULT_WINSIZE (1U << 23) | 39 | #define XD3_DEFAULT_WINSIZE (1U << 23) |
@@ -43,24 +44,27 @@ | |||
43 | #define XD3_DEFAULT_SRCWINSZ (1U << 26) | 44 | #define XD3_DEFAULT_SRCWINSZ (1U << 26) |
44 | #endif | 45 | #endif |
45 | 46 | ||
46 | /* When Xdelta requests a memory allocation for certain buffers, it rounds up to units of | 47 | /* When Xdelta requests a memory allocation for certain buffers, it |
47 | * at least this size. The code assumes (and asserts) that this is a power-of-two. */ | 48 | * rounds up to units of at least this size. The code assumes (and |
49 | * asserts) that this is a power-of-two. */ | ||
48 | #ifndef XD3_ALLOCSIZE | 50 | #ifndef XD3_ALLOCSIZE |
49 | #define XD3_ALLOCSIZE (1U<<14) | 51 | #define XD3_ALLOCSIZE (1U<<14) |
50 | #endif | 52 | #endif |
51 | 53 | ||
52 | /* The XD3_HARDMAXWINSIZE parameter is a safety mechanism to protect decoders against | 54 | /* The XD3_HARDMAXWINSIZE parameter is a safety mechanism to protect |
53 | * malicious files. The decoder will never decode a window larger than this. If the file | 55 | * decoders against malicious files. The decoder will never decode a |
54 | * specifies VCD_TARGET the decoder may require two buffers of this size. | 56 | * window larger than this. If the file specifies VCD_TARGET the |
57 | * decoder may require two buffers of this size. | ||
55 | * | 58 | * |
56 | * 8-16MB is reasonable, probably don't need to go larger. */ | 59 | * 8-16MB is reasonable, probably don't need to go larger. */ |
57 | #ifndef XD3_HARDMAXWINSIZE | 60 | #ifndef XD3_HARDMAXWINSIZE |
58 | #define XD3_HARDMAXWINSIZE (1U<<24) | 61 | #define XD3_HARDMAXWINSIZE (1U<<24) |
59 | #endif | 62 | #endif |
60 | /* The IOPT_SIZE value sets the size of a buffer used to batch overlapping copy | 63 | /* The IOPT_SIZE value sets the size of a buffer used to batch |
61 | * instructions before they are optimized by picking the best non-overlapping ranges. The | 64 | * overlapping copy instructions before they are optimized by picking |
62 | * larger this buffer, the longer a forced xd3_srcwin_setup() decision is held off. | 65 | * the best non-overlapping ranges. The larger this buffer, the |
63 | * Setting this value to 0 causes an unlimited buffer to be used. */ | 66 | * longer a forced xd3_srcwin_setup() decision is held off. Setting |
67 | * this value to 0 causes an unlimited buffer to be used. */ | ||
64 | #ifndef XD3_DEFAULT_IOPT_SIZE | 68 | #ifndef XD3_DEFAULT_IOPT_SIZE |
65 | #define XD3_DEFAULT_IOPT_SIZE (1U<<15) | 69 | #define XD3_DEFAULT_IOPT_SIZE (1U<<15) |
66 | #endif | 70 | #endif |
@@ -78,18 +82,20 @@ | |||
78 | 82 | ||
79 | /* Sizes and addresses within VCDIFF windows are represented as usize_t | 83 | /* Sizes and addresses within VCDIFF windows are represented as usize_t |
80 | * | 84 | * |
81 | * For source-file offsets and total file sizes, total input and output counts, the xoff_t | 85 | * For source-file offsets and total file sizes, total input and |
82 | * type is used. The decoder and encoder generally check for overflow of the xoff_t size | 86 | * output counts, the xoff_t type is used. The decoder and encoder |
83 | * (this is tested at the 32bit boundary [xdelta3-test.h]). | 87 | * generally check for overflow of the xoff_t size (this is tested at |
88 | * the 32bit boundary [xdelta3-test.h]). | ||
84 | * | 89 | * |
85 | * As of 3.0r, a 64bit xoff_t is ~33% slower on a 32bit platform. TODO: fix this. | 90 | * As of 3.0r, a 64bit xoff_t is ~33% slower on a 32bit platform. |
91 | * TODO: fix this. | ||
86 | */ | 92 | */ |
87 | #ifndef _WIN32 | 93 | #ifndef _WIN32 |
88 | typedef unsigned int usize_t; | 94 | typedef unsigned int usize_t; |
89 | typedef u_int8_t uint8_t; | 95 | typedef u_int8_t uint8_t; |
90 | typedef u_int16_t uint16_t; | 96 | typedef u_int16_t uint16_t; |
91 | #ifndef __uint32_t_defined | 97 | #ifndef __uint32_t_defined |
92 | typedef int uint32_t; | 98 | typedef unsigned int uint32_t; |
93 | #endif | 99 | #endif |
94 | typedef long long unsigned int uint64_t; | 100 | typedef long long unsigned int uint64_t; |
95 | #else | 101 | #else |
@@ -105,8 +111,6 @@ typedef unsigned long uint32_t; | |||
105 | typedef ULONGLONG uint64_t; | 111 | typedef ULONGLONG uint64_t; |
106 | #endif | 112 | #endif |
107 | 113 | ||
108 | #define SIZEOF_USIZE_T 4 | ||
109 | |||
110 | #ifndef XD3_USE_LARGEFILE64 | 114 | #ifndef XD3_USE_LARGEFILE64 |
111 | #define XD3_USE_LARGEFILE64 1 | 115 | #define XD3_USE_LARGEFILE64 1 |
112 | #endif | 116 | #endif |
@@ -115,6 +119,7 @@ typedef ULONGLONG uint64_t; | |||
115 | #define __USE_FILE_OFFSET64 1 /* GLIBC: for 64bit fileops, ... ? */ | 119 | #define __USE_FILE_OFFSET64 1 /* GLIBC: for 64bit fileops, ... ? */ |
116 | typedef uint64_t xoff_t; | 120 | typedef uint64_t xoff_t; |
117 | #define SIZEOF_XOFF_T 8 | 121 | #define SIZEOF_XOFF_T 8 |
122 | #define SIZEOF_USIZE_T 4 | ||
118 | #ifndef WIN32 | 123 | #ifndef WIN32 |
119 | #define Q "q" | 124 | #define Q "q" |
120 | #else | 125 | #else |
@@ -123,6 +128,7 @@ typedef uint64_t xoff_t; | |||
123 | #else | 128 | #else |
124 | typedef uint32_t xoff_t; | 129 | typedef uint32_t xoff_t; |
125 | #define SIZEOF_XOFF_T 4 | 130 | #define SIZEOF_XOFF_T 4 |
131 | #define SIZEOF_USIZE_T 4 | ||
126 | #define Q | 132 | #define Q |
127 | #endif | 133 | #endif |
128 | 134 | ||
@@ -136,18 +142,21 @@ typedef uint32_t xoff_t; | |||
136 | #define XD3_ENCODER 1 | 142 | #define XD3_ENCODER 1 |
137 | #endif | 143 | #endif |
138 | 144 | ||
139 | /* The code returned when main() fails, also defined in system includes. */ | 145 | /* The code returned when main() fails, also defined in system |
146 | includes. */ | ||
140 | #ifndef EXIT_FAILURE | 147 | #ifndef EXIT_FAILURE |
141 | #define EXIT_FAILURE 1 | 148 | #define EXIT_FAILURE 1 |
142 | #endif | 149 | #endif |
143 | 150 | ||
144 | /* REGRESSION TEST enables the "xdelta3 test" command, which runs a series of self-tests. */ | 151 | /* REGRESSION TEST enables the "xdelta3 test" command, which runs a |
152 | series of self-tests. */ | ||
145 | #ifndef REGRESSION_TEST | 153 | #ifndef REGRESSION_TEST |
146 | #define REGRESSION_TEST 0 | 154 | #define REGRESSION_TEST 0 |
147 | #endif | 155 | #endif |
148 | 156 | ||
149 | /* XD3_DEBUG=1 enables assertions and various statistics. Levels > 1 enable some | 157 | /* XD3_DEBUG=1 enables assertions and various statistics. Levels > 1 |
150 | * additional output only useful during development and debugging. */ | 158 | * enable some additional output only useful during development and |
159 | * debugging. */ | ||
151 | #ifndef XD3_DEBUG | 160 | #ifndef XD3_DEBUG |
152 | #define XD3_DEBUG 0 | 161 | #define XD3_DEBUG 0 |
153 | #endif | 162 | #endif |
@@ -160,8 +169,9 @@ typedef uint32_t xoff_t; | |||
160 | #define SWIG_MODULE 0 | 169 | #define SWIG_MODULE 0 |
161 | #endif | 170 | #endif |
162 | 171 | ||
163 | /* There are three string matching functions supplied: one fast, one slow (default), and | 172 | /* There are three string matching functions supplied: one fast, one |
164 | * one soft-configurable. To disable any of these, use the following definitions. */ | 173 | * slow (default), and one soft-configurable. To disable any of |
174 | * these, use the following definitions. */ | ||
165 | #ifndef XD3_BUILD_SLOW | 175 | #ifndef XD3_BUILD_SLOW |
166 | #define XD3_BUILD_SLOW 1 | 176 | #define XD3_BUILD_SLOW 1 |
167 | #endif | 177 | #endif |
@@ -182,8 +192,9 @@ typedef uint32_t xoff_t; | |||
182 | #include <stdio.h> | 192 | #include <stdio.h> |
183 | #endif | 193 | #endif |
184 | 194 | ||
185 | /* XPRINT. Debug output and VCDIFF_TOOLS functions report to stderr. I have used an | 195 | /* XPRINT. Debug output and VCDIFF_TOOLS functions report to stderr. |
186 | * irregular style to abbreviate [fprintf(stderr, "] as [DP(RINT "]. */ | 196 | * I have used an irregular style to abbreviate [fprintf(stderr, "] as |
197 | * [DP(RINT "]. */ | ||
187 | #define DP fprintf | 198 | #define DP fprintf |
188 | #define RINT stderr, | 199 | #define RINT stderr, |
189 | 200 | ||
@@ -208,9 +219,9 @@ typedef struct _xd3_code_table_desc xd3_code_table_desc; | |||
208 | typedef struct _xd3_code_table_sizes xd3_code_table_sizes; | 219 | typedef struct _xd3_code_table_sizes xd3_code_table_sizes; |
209 | typedef struct _xd3_slist xd3_slist; | 220 | typedef struct _xd3_slist xd3_slist; |
210 | 221 | ||
211 | /* The stream configuration has three callbacks functions, all of which may be supplied | 222 | /* The stream configuration has three callbacks functions, all of |
212 | * with NULL values. If config->getblk is provided as NULL, the stream returns | 223 | * which may be supplied with NULL values. If config->getblk is |
213 | * XD3_GETSRCBLK. */ | 224 | * provided as NULL, the stream returns XD3_GETSRCBLK. */ |
214 | 225 | ||
215 | typedef void* (xd3_alloc_func) (void *opaque, | 226 | typedef void* (xd3_alloc_func) (void *opaque, |
216 | usize_t items, | 227 | usize_t items, |
@@ -222,8 +233,9 @@ typedef int (xd3_getblk_func) (xd3_stream *stream, | |||
222 | xd3_source *source, | 233 | xd3_source *source, |
223 | xoff_t blkno); | 234 | xoff_t blkno); |
224 | 235 | ||
225 | /* These are internal functions to delay construction of encoding tables and support | 236 | /* These are internal functions to delay construction of encoding |
226 | * alternate code tables. See the comments & code enabled by GENERIC_ENCODE_TABLES. */ | 237 | * tables and support alternate code tables. See the comments & code |
238 | * enabled by GENERIC_ENCODE_TABLES. */ | ||
227 | 239 | ||
228 | typedef const xd3_dinst* (xd3_code_table_func) (void); | 240 | typedef const xd3_dinst* (xd3_code_table_func) (void); |
229 | typedef int (xd3_comp_table_func) (xd3_stream *stream, | 241 | typedef int (xd3_comp_table_func) (xd3_stream *stream, |
@@ -269,61 +281,83 @@ typedef int (xd3_comp_table_func) (xd3_stream *stream, | |||
269 | #endif | 281 | #endif |
270 | #endif | 282 | #endif |
271 | 283 | ||
272 | /****************************************************************************************** | 284 | /**************************************************************** |
273 | PUBLIC ENUMS | 285 | PUBLIC ENUMS |
274 | ******************************************************************************************/ | 286 | ******************************************************************/ |
275 | 287 | ||
276 | /* These are the five ordinary status codes returned by the xd3_encode_input() and | 288 | /* These are the five ordinary status codes returned by the |
277 | * xd3_decode_input() state machines. */ | 289 | * xd3_encode_input() and xd3_decode_input() state machines. */ |
278 | typedef enum { | 290 | typedef enum { |
279 | 291 | ||
280 | /* An application must be prepared to handle these five return values from either | 292 | /* An application must be prepared to handle these five return |
281 | * xd3_encode_input or xd3_decode_input, except in the case of no-source compression, in | 293 | * values from either xd3_encode_input or xd3_decode_input, except |
282 | * which case XD3_GETSRCBLK is never returned. More detailed comments for these are | 294 | * in the case of no-source compression, in which case XD3_GETSRCBLK |
283 | * given in xd3_encode_input and xd3_decode_input comments, below. */ | 295 | * is never returned. More detailed comments for these are given in |
296 | * xd3_encode_input and xd3_decode_input comments, below. */ | ||
284 | XD3_INPUT = -17703, /* need input */ | 297 | XD3_INPUT = -17703, /* need input */ |
285 | XD3_OUTPUT = -17704, /* have output */ | 298 | XD3_OUTPUT = -17704, /* have output */ |
286 | XD3_GETSRCBLK = -17705, /* need a block of source input (with no xd3_getblk function), | 299 | XD3_GETSRCBLK = -17705, /* need a block of source input (with no |
287 | * a chance to do non-blocking read. */ | 300 | * xd3_getblk function), a chance to do |
288 | XD3_GOTHEADER = -17706, /* (decode-only) after the initial VCDIFF & first window header */ | 301 | * non-blocking read. */ |
289 | XD3_WINSTART = -17707, /* notification: returned before a window is processed, giving a | 302 | XD3_GOTHEADER = -17706, /* (decode-only) after the initial VCDIFF & |
290 | * chance to XD3_SKIP_WINDOW or not XD3_SKIP_EMIT that window. */ | 303 | first window header */ |
291 | XD3_WINFINISH = -17708, /* notification: returned after encode/decode & output for a window */ | 304 | XD3_WINSTART = -17707, /* notification: returned before a window is |
292 | XD3_TOOFARBACK = -17709, /* (encoder only) may be returned by getblk() if the block is too old */ | 305 | * processed, giving a chance to |
306 | * XD3_SKIP_WINDOW or not XD3_SKIP_EMIT that | ||
307 | * window. */ | ||
308 | XD3_WINFINISH = -17708, /* notification: returned after | ||
309 | encode/decode & output for a window */ | ||
310 | XD3_TOOFARBACK = -17709, /* (encoder only) may be returned by | ||
311 | getblk() if the block is too old */ | ||
293 | XD3_INTERNAL = -17710, /* internal error */ | 312 | XD3_INTERNAL = -17710, /* internal error */ |
294 | XD3_INVALID = -17711, /* invalid config */ | 313 | XD3_INVALID = -17711, /* invalid config */ |
295 | XD3_INVALID_INPUT = -17712, /* invalid input/decoder error */ | 314 | XD3_INVALID_INPUT = -17712, /* invalid input/decoder error */ |
296 | XD3_NOSECOND = -17713, /* when secondary compression finds no improvement. */ | 315 | XD3_NOSECOND = -17713, /* when secondary compression finds no |
316 | improvement. */ | ||
297 | 317 | ||
298 | } xd3_rvalues; | 318 | } xd3_rvalues; |
299 | 319 | ||
300 | /* special values in config->flags */ | 320 | /* special values in config->flags */ |
301 | typedef enum | 321 | typedef enum |
302 | { | 322 | { |
303 | XD3_JUST_HDR = (1 << 1), /* used by VCDIFF tools, see xdelta3-main.h. */ | 323 | XD3_JUST_HDR = (1 << 1), /* used by VCDIFF tools, see |
304 | XD3_SKIP_WINDOW = (1 << 2), /* used by VCDIFF tools, see xdelta3-main.h. */ | 324 | xdelta3-main.h. */ |
305 | XD3_SKIP_EMIT = (1 << 3), /* used by VCDIFF tools, see xdelta3-main.h. */ | 325 | XD3_SKIP_WINDOW = (1 << 2), /* used by VCDIFF tools, see |
306 | XD3_FLUSH = (1 << 4), /* flush the stream buffer to prepare for xd3_stream_close(). */ | 326 | xdelta3-main.h. */ |
327 | XD3_SKIP_EMIT = (1 << 3), /* used by VCDIFF tools, see | ||
328 | xdelta3-main.h. */ | ||
329 | XD3_FLUSH = (1 << 4), /* flush the stream buffer to | ||
330 | prepare for | ||
331 | xd3_stream_close(). */ | ||
307 | 332 | ||
308 | XD3_SEC_DJW = (1 << 5), /* use DJW static huffman */ | 333 | XD3_SEC_DJW = (1 << 5), /* use DJW static huffman */ |
309 | XD3_SEC_FGK = (1 << 6), /* use FGK adaptive huffman */ | 334 | XD3_SEC_FGK = (1 << 6), /* use FGK adaptive huffman */ |
310 | XD3_SEC_TYPE = (XD3_SEC_DJW | XD3_SEC_FGK), | 335 | XD3_SEC_TYPE = (XD3_SEC_DJW | XD3_SEC_FGK), |
311 | 336 | ||
312 | XD3_SEC_NODATA = (1 << 7), /* disable secondary compression of the data section. */ | 337 | XD3_SEC_NODATA = (1 << 7), /* disable secondary compression of |
313 | XD3_SEC_NOINST = (1 << 8), /* disable secondary compression of the inst section. */ | 338 | the data section. */ |
314 | XD3_SEC_NOADDR = (1 << 9), /* disable secondary compression of the addr section. */ | 339 | XD3_SEC_NOINST = (1 << 8), /* disable secondary compression of |
340 | the inst section. */ | ||
341 | XD3_SEC_NOADDR = (1 << 9), /* disable secondary compression of | ||
342 | the addr section. */ | ||
315 | 343 | ||
316 | XD3_SEC_OTHER = (XD3_SEC_NODATA | XD3_SEC_NOINST | XD3_SEC_NOADDR), | 344 | XD3_SEC_OTHER = (XD3_SEC_NODATA | XD3_SEC_NOINST | XD3_SEC_NOADDR), |
317 | 345 | ||
318 | XD3_ADLER32 = (1 << 10), /* enable checksum computation in the encoder. */ | 346 | XD3_ADLER32 = (1 << 10), /* enable checksum computation in |
319 | XD3_ADLER32_NOVER = (1 << 11), /* disable checksum verification in the decoder. */ | 347 | the encoder. */ |
348 | XD3_ADLER32_NOVER = (1 << 11), /* disable checksum verification in | ||
349 | the decoder. */ | ||
320 | 350 | ||
321 | XD3_ALT_CODE_TABLE = (1 << 12), /* for testing the alternate code table encoding. */ | 351 | XD3_ALT_CODE_TABLE = (1 << 12), /* for testing th |
352 | e alternate code table encoding. */ | ||
322 | 353 | ||
323 | XD3_NOCOMPRESS = (1 << 13), /* disable ordinary data compression feature, | 354 | XD3_NOCOMPRESS = (1 << 13), /* disable ordinary data |
324 | * only search the source, not the target. */ | 355 | * compression feature, only search |
325 | XD3_BEGREEDY = (1 << 14), /* disable the "1.5-pass algorithm", instead use | 356 | * the source, not the target. */ |
326 | * greedy matching. Greedy is off by default. */ | 357 | XD3_BEGREEDY = (1 << 14), /* disable the "1.5-pass |
358 | * algorithm", instead use greedy | ||
359 | * matching. Greedy is off by | ||
360 | * default. */ | ||
327 | 361 | ||
328 | /* 4 bits to set the compression level the same as the command-line | 362 | /* 4 bits to set the compression level the same as the command-line |
329 | * setting -1 through -9 (-0 corresponds to the XD3_NOCOMPRESS flag, | 363 | * setting -1 through -9 (-0 corresponds to the XD3_NOCOMPRESS flag, |
@@ -344,37 +378,45 @@ typedef enum | |||
344 | * and soft. */ | 378 | * and soft. */ |
345 | typedef enum | 379 | typedef enum |
346 | { | 380 | { |
347 | XD3_SMATCH_DEFAULT = 0, /* Flags may contain XD3_COMPLEVEL bits, else default. */ | 381 | XD3_SMATCH_DEFAULT = 0, /* Flags may contain XD3_COMPLEVEL bits, |
382 | else default. */ | ||
348 | XD3_SMATCH_SLOW = 1, | 383 | XD3_SMATCH_SLOW = 1, |
349 | XD3_SMATCH_FAST = 2, | 384 | XD3_SMATCH_FAST = 2, |
350 | XD3_SMATCH_FASTEST = 3, | 385 | XD3_SMATCH_FASTEST = 3, |
351 | XD3_SMATCH_SOFT = 4, | 386 | XD3_SMATCH_SOFT = 4, |
352 | } xd3_smatch_cfg; | 387 | } xd3_smatch_cfg; |
353 | 388 | ||
354 | /****************************************************************************************** | 389 | /********************************************************************* |
355 | PRIVATE ENUMS | 390 | PRIVATE ENUMS |
356 | ******************************************************************************************/ | 391 | **********************************************************************/ |
357 | 392 | ||
358 | /* stream->match_state is part of the xd3_encode_input state machine for source matching: | 393 | /* stream->match_state is part of the xd3_encode_input state machine |
394 | * for source matching: | ||
359 | * | 395 | * |
360 | * 1. the XD3_GETSRCBLK block-read mechanism means reentrant matching | 396 | * 1. the XD3_GETSRCBLK block-read mechanism means reentrant matching |
361 | * 2. this state spans encoder windows: a match and end-of-window will continue in the next | 397 | * 2. this state spans encoder windows: a match and end-of-window |
362 | * 3. the initial target byte and source byte are a presumed match, to avoid some computation | 398 | * will continue in the next 3. the initial target byte and source |
363 | * in case the inputs are identical. | 399 | * byte are a presumed match, to avoid some computation in case the |
400 | * inputs are identical. | ||
364 | */ | 401 | */ |
365 | typedef enum { | 402 | typedef enum { |
366 | 403 | ||
367 | MATCH_TARGET = 0, /* in this state, attempt to match the start of the target with the | 404 | MATCH_TARGET = 0, /* in this state, attempt to match the start of |
368 | * previously set source address (initially 0). */ | 405 | * the target with the previously set source |
369 | MATCH_BACKWARD = 1, /* currently expanding a match backward in the source/target. */ | 406 | * address (initially 0). */ |
370 | MATCH_FORWARD = 2, /* currently expanding a match forward in the source/target. */ | 407 | MATCH_BACKWARD = 1, /* currently expanding a match backward in the |
408 | source/target. */ | ||
409 | MATCH_FORWARD = 2, /* currently expanding a match forward in the | ||
410 | source/target. */ | ||
371 | MATCH_SEARCHING = 3, /* currently searching for a match. */ | 411 | MATCH_SEARCHING = 3, /* currently searching for a match. */ |
372 | 412 | ||
373 | } xd3_match_state; | 413 | } xd3_match_state; |
374 | 414 | ||
375 | /* The xd3_encode_input state machine steps through these states in the following order. | 415 | /* The xd3_encode_input state machine steps through these states in |
376 | * The matcher is reentrant and returns XD3_INPUT whenever it requires more data. After | 416 | * the following order. The matcher is reentrant and returns |
377 | * receiving XD3_INPUT, if the application reads EOF it should call xd3_stream_close(). | 417 | * XD3_INPUT whenever it requires more data. After receiving |
418 | * XD3_INPUT, if the application reads EOF it should call | ||
419 | * xd3_stream_close(). | ||
378 | */ | 420 | */ |
379 | typedef enum { | 421 | typedef enum { |
380 | 422 | ||
@@ -387,13 +429,15 @@ typedef enum { | |||
387 | ENC_ABORTED = 6, /* abort. */ | 429 | ENC_ABORTED = 6, /* abort. */ |
388 | } xd3_encode_state; | 430 | } xd3_encode_state; |
389 | 431 | ||
390 | /* The xd3_decode_input state machine steps through these states in the following order. | 432 | /* The xd3_decode_input state machine steps through these states in |
391 | * The matcher is reentrant and returns XD3_INPUT whenever it requires more data. After | 433 | * the following order. The matcher is reentrant and returns |
392 | * receiving XD3_INPUT, if the application reads EOF it should call xd3_stream_close(). | 434 | * XD3_INPUT whenever it requires more data. After receiving |
435 | * XD3_INPUT, if the application reads EOF it should call | ||
436 | * xd3_stream_close(). | ||
393 | * | 437 | * |
394 | * 0-8: the VCDIFF header | 438 | * 0-8: the VCDIFF header |
395 | * 9-18: the VCDIFF window header | 439 | * 9-18: the VCDIFF window header |
396 | * 19-21: the three primary sections: data (which I think should have gone last), inst, addr | 440 | * 19-21: the three primary sections: data, inst, addr |
397 | * 22: producing output: returns XD3_OUTPUT, possibly XD3_GETSRCBLK, | 441 | * 22: producing output: returns XD3_OUTPUT, possibly XD3_GETSRCBLK, |
398 | * 23: return XD3_WINFINISH, set state=9 to decode more input | 442 | * 23: return XD3_WINFINISH, set state=9 to decode more input |
399 | */ | 443 | */ |
@@ -438,9 +482,9 @@ typedef enum { | |||
438 | DEC_ABORTED = 24, /* xd3_abort_stream */ | 482 | DEC_ABORTED = 24, /* xd3_abort_stream */ |
439 | } xd3_decode_state; | 483 | } xd3_decode_state; |
440 | 484 | ||
441 | /****************************************************************************************** | 485 | /************************************************************ |
442 | internal types | 486 | internal types |
443 | ******************************************************************************************/ | 487 | ************************************************************/ |
444 | 488 | ||
445 | /* instruction lists used in the IOPT buffer */ | 489 | /* instruction lists used in the IOPT buffer */ |
446 | struct _xd3_rlist | 490 | struct _xd3_rlist |
@@ -523,7 +567,8 @@ struct _xd3_iopt_buflist | |||
523 | xd3_iopt_buflist *next; | 567 | xd3_iopt_buflist *next; |
524 | }; | 568 | }; |
525 | 569 | ||
526 | /* This is the record of a pre-compiled configuration, a subset of xd3_config. */ | 570 | /* This is the record of a pre-compiled configuration, a subset of |
571 | xd3_config. */ | ||
527 | struct _xd3_smatcher | 572 | struct _xd3_smatcher |
528 | { | 573 | { |
529 | const char *name; | 574 | const char *name; |
@@ -551,9 +596,9 @@ struct _xd3_slist | |||
551 | usize_t last_pos; | 596 | usize_t last_pos; |
552 | }; | 597 | }; |
553 | 598 | ||
554 | /****************************************************************************************** | 599 | /******************************************************************** |
555 | public types | 600 | public types |
556 | ******************************************************************************************/ | 601 | *******************************************************************/ |
557 | 602 | ||
558 | /* Settings for the secondary compressor. */ | 603 | /* Settings for the secondary compressor. */ |
559 | struct _xd3_sec_cfg | 604 | struct _xd3_sec_cfg |
@@ -588,10 +633,11 @@ struct _xd3_config | |||
588 | xd3_smatcher smatcher_soft; | 633 | xd3_smatcher smatcher_soft; |
589 | }; | 634 | }; |
590 | 635 | ||
591 | /* The primary source file object. You create one of these objects and initialize the | 636 | /* The primary source file object. You create one of these objects and |
592 | * first four fields. This library maintains the next 5 fields. The configured getblk | 637 | * initialize the first four fields. This library maintains the next |
593 | * implementation is responsible for setting the final 3 fields when called (and/or when | 638 | * 5 fields. The configured getblk implementation is responsible for |
594 | * XD3_GETSRCBLK is returned). | 639 | * setting the final 3 fields when called (and/or when XD3_GETSRCBLK |
640 | * is returned). | ||
595 | */ | 641 | */ |
596 | struct _xd3_source | 642 | struct _xd3_source |
597 | { | 643 | { |
@@ -810,9 +856,10 @@ struct _xd3_stream | |||
810 | PUBLIC FUNCTIONS | 856 | PUBLIC FUNCTIONS |
811 | ******************************************************************************************/ | 857 | ******************************************************************************************/ |
812 | 858 | ||
813 | /* This function configures an xd3_stream using the provided in-memory input buffer, | 859 | /* This function configures an xd3_stream using the provided in-memory |
814 | * source buffer, output buffer, and flags. The output array must be large enough or else | 860 | * input buffer, source buffer, output buffer, and flags. The output |
815 | * ENOSPC will be returned. This is the simplest in-memory encoding interface. */ | 861 | * array must be large enough or else ENOSPC will be returned. This |
862 | * is the simplest in-memory encoding interface. */ | ||
816 | int xd3_encode_memory (const uint8_t *input, | 863 | int xd3_encode_memory (const uint8_t *input, |
817 | usize_t input_size, | 864 | usize_t input_size, |
818 | const uint8_t *source, | 865 | const uint8_t *source, |
@@ -832,12 +879,14 @@ int xd3_decode_memory (const uint8_t *input, | |||
832 | usize_t avail_output, | 879 | usize_t avail_output, |
833 | int flags); | 880 | int flags); |
834 | 881 | ||
835 | /* This function encodes an in-memory input. Everything else about the xd3_stream is | 882 | /* This function encodes an in-memory input. Everything else about |
836 | * configurable. The output array must be large enough to hold the output or else ENOSPC | 883 | * the xd3_stream is configurable. The output array must be large |
837 | * is returned. The source (if any) should be set using xd3_set_source() with a | 884 | * enough to hold the output or else ENOSPC is returned. The source |
838 | * single-block xd3_source. This calls the underlying non-blocking interface, | 885 | * (if any) should be set using xd3_set_source() with a single-block |
839 | * xd3_encode_input(), handling the necessary input/output states. This method be | 886 | * xd3_source. This calls the underlying non-blocking interface, |
840 | * considered a reference for any application using xd3_encode_input() directly. | 887 | * xd3_encode_input(), handling the necessary input/output states. |
888 | * This method be considered a reference for any application using | ||
889 | * xd3_encode_input() directly. | ||
841 | * | 890 | * |
842 | * xd3_stream stream; | 891 | * xd3_stream stream; |
843 | * xd3_config config; | 892 | * xd3_config config; |
@@ -886,8 +935,9 @@ int xd3_decode_stream (xd3_stream *stream, | |||
886 | 935 | ||
887 | /* This is the non-blocking interface. | 936 | /* This is the non-blocking interface. |
888 | * | 937 | * |
889 | * Handling input and output states is the same for encoding or decoding using the | 938 | * Handling input and output states is the same for encoding or |
890 | * xd3_avail_input() and xd3_consume_output() routines, inlined below. | 939 | * decoding using the xd3_avail_input() and xd3_consume_output() |
940 | * routines, inlined below. | ||
891 | * | 941 | * |
892 | * Return values: | 942 | * Return values: |
893 | * | 943 | * |
@@ -921,55 +971,64 @@ int xd3_decode_stream (xd3_stream *stream, | |||
921 | int xd3_decode_input (xd3_stream *stream); | 971 | int xd3_decode_input (xd3_stream *stream); |
922 | int xd3_encode_input (xd3_stream *stream); | 972 | int xd3_encode_input (xd3_stream *stream); |
923 | 973 | ||
924 | /* The xd3_config structure is used to initialize a stream - all data is copied into | 974 | /* The xd3_config structure is used to initialize a stream - all data |
925 | * stream so config may be a temporary variable. See the [documentation] or comments on | 975 | * is copied into stream so config may be a temporary variable. See |
926 | * the xd3_config structure. */ | 976 | * the [documentation] or comments on the xd3_config structure. */ |
927 | int xd3_config_stream (xd3_stream *stream, | 977 | int xd3_config_stream (xd3_stream *stream, |
928 | xd3_config *config); | 978 | xd3_config *config); |
929 | 979 | ||
930 | /* Since Xdelta3 doesn't open any files, xd3_close_stream is just an error check that the | 980 | /* Since Xdelta3 doesn't open any files, xd3_close_stream is just an |
931 | * stream is in a proper state to be closed: this means the encoder is flushed and the | 981 | * error check that the stream is in a proper state to be closed: this |
932 | * decoder is at a window boundary. The application is responsible for freeing any of the | 982 | * means the encoder is flushed and the decoder is at a window |
983 | * boundary. The application is responsible for freeing any of the | ||
933 | * resources it supplied. */ | 984 | * resources it supplied. */ |
934 | int xd3_close_stream (xd3_stream *stream); | 985 | int xd3_close_stream (xd3_stream *stream); |
935 | 986 | ||
936 | /* This unconditionally closes/frees the stream, future close() will succeed. */ | 987 | /* This unconditionally closes/frees the stream, future close() will |
988 | succeed. */ | ||
937 | void xd3_abort_stream (xd3_stream *stream); | 989 | void xd3_abort_stream (xd3_stream *stream); |
938 | 990 | ||
939 | /* xd3_free_stream frees all memory allocated for the stream. The application is | 991 | /* xd3_free_stream frees all memory allocated for the stream. The |
940 | * responsible for freeing any of the resources it supplied. */ | 992 | * application is responsible for freeing any of the resources it |
993 | * supplied. */ | ||
941 | void xd3_free_stream (xd3_stream *stream); | 994 | void xd3_free_stream (xd3_stream *stream); |
942 | 995 | ||
943 | /* This function informs the encoder or decoder that source matching (i.e., | 996 | /* This function informs the encoder or decoder that source matching |
944 | * delta-compression) is possible. For encoding, this should be called before the first | 997 | * (i.e., delta-compression) is possible. For encoding, this should |
945 | * xd3_encode_input. A NULL source is ignored. For decoding, this should be called | 998 | * be called before the first xd3_encode_input. A NULL source is |
946 | * before the first window is decoded, but the appheader may be read first | 999 | * ignored. For decoding, this should be called before the first |
947 | * (XD3_GOTHEADER). At this point, consult xd3_decoder_needs_source(), inlined below, to | 1000 | * window is decoded, but the appheader may be read first |
948 | * determine if a source is expected by the decoder. */ | 1001 | * (XD3_GOTHEADER). At this point, consult |
1002 | * xd3_decoder_needs_source(), inlined below, to determine if a source | ||
1003 | * is expected by the decoder. */ | ||
949 | int xd3_set_source (xd3_stream *stream, | 1004 | int xd3_set_source (xd3_stream *stream, |
950 | xd3_source *source); | 1005 | xd3_source *source); |
951 | 1006 | ||
952 | /* This should be called before the first call to xd3_encode_input() to include | 1007 | /* This should be called before the first call to xd3_encode_input() |
953 | * application-specific data in the VCDIFF header. */ | 1008 | * to include application-specific data in the VCDIFF header. */ |
954 | void xd3_set_appheader (xd3_stream *stream, | 1009 | void xd3_set_appheader (xd3_stream *stream, |
955 | const uint8_t *data, | 1010 | const uint8_t *data, |
956 | usize_t size); | 1011 | usize_t size); |
957 | 1012 | ||
958 | /* xd3_get_appheader may be called in the decoder after XD3_GOTHEADER. For convenience, | 1013 | /* xd3_get_appheader may be called in the decoder after XD3_GOTHEADER. |
959 | * the decoder always adds a single byte padding to the end of the application header, | 1014 | * For convenience, the decoder always adds a single byte padding to |
960 | * which is set to zero in case the application header is a string. */ | 1015 | * the end of the application header, which is set to zero in case the |
1016 | * application header is a string. */ | ||
961 | int xd3_get_appheader (xd3_stream *stream, | 1017 | int xd3_get_appheader (xd3_stream *stream, |
962 | uint8_t **data, | 1018 | uint8_t **data, |
963 | usize_t *size); | 1019 | usize_t *size); |
964 | 1020 | ||
965 | /* After receiving XD3_GOTHEADER, the decoder should check this function which returns 1 | 1021 | /* After receiving XD3_GOTHEADER, the decoder should check this |
966 | * if the decoder will require source data. */ | 1022 | * function which returns 1 if the decoder will require source |
1023 | * data. */ | ||
967 | int xd3_decoder_needs_source (xd3_stream *stream); | 1024 | int xd3_decoder_needs_source (xd3_stream *stream); |
968 | 1025 | ||
969 | /* Gives an error string for xdelta3-speficic errors, returns NULL for system errors */ | 1026 | /* Gives an error string for xdelta3-speficic errors, returns NULL for |
1027 | system errors */ | ||
970 | const char* xd3_strerror (int ret); | 1028 | const char* xd3_strerror (int ret); |
971 | 1029 | ||
972 | /* For convenience, zero & initialize the xd3_config structure with specified flags. */ | 1030 | /* For convenience, zero & initialize the xd3_config structure with |
1031 | specified flags. */ | ||
973 | static inline | 1032 | static inline |
974 | void xd3_init_config (xd3_config *config, | 1033 | void xd3_init_config (xd3_config *config, |
975 | int flags) | 1034 | int flags) |
@@ -984,18 +1043,20 @@ void xd3_avail_input (xd3_stream *stream, | |||
984 | const uint8_t *idata, | 1043 | const uint8_t *idata, |
985 | usize_t isize) | 1044 | usize_t isize) |
986 | { | 1045 | { |
987 | /* Even if isize is zero, the code expects a non-NULL idata. Why? It uses this value | 1046 | /* Even if isize is zero, the code expects a non-NULL idata. Why? |
988 | * to determine whether xd3_avail_input has ever been called. If xd3_encode_input is | 1047 | * It uses this value to determine whether xd3_avail_input has ever |
989 | * called before xd3_avail_input it will return XD3_INPUT right away without allocating | 1048 | * been called. If xd3_encode_input is called before |
990 | * a stream->winsize buffer. This is to avoid an unwanted allocation. */ | 1049 | * xd3_avail_input it will return XD3_INPUT right away without |
1050 | * allocating a stream->winsize buffer. This is to avoid an | ||
1051 | * unwanted allocation. */ | ||
991 | XD3_ASSERT (idata != NULL); | 1052 | XD3_ASSERT (idata != NULL); |
992 | 1053 | ||
993 | stream->next_in = idata; | 1054 | stream->next_in = idata; |
994 | stream->avail_in = isize; | 1055 | stream->avail_in = isize; |
995 | } | 1056 | } |
996 | 1057 | ||
997 | /* This acknowledges receipt of output data, must be called after any XD3_OUTPUT | 1058 | /* This acknowledges receipt of output data, must be called after any |
998 | * return. */ | 1059 | * XD3_OUTPUT return. */ |
999 | static inline | 1060 | static inline |
1000 | void xd3_consume_output (xd3_stream *stream) | 1061 | void xd3_consume_output (xd3_stream *stream) |
1001 | { | 1062 | { |
@@ -1004,30 +1065,39 @@ void xd3_consume_output (xd3_stream *stream) | |||
1004 | 1065 | ||
1005 | /* These are set for each XD3_WINFINISH return. */ | 1066 | /* These are set for each XD3_WINFINISH return. */ |
1006 | static inline | 1067 | static inline |
1007 | int xd3_encoder_used_source (xd3_stream *stream) { return stream->src != NULL && stream->src->srclen > 0; } | 1068 | int xd3_encoder_used_source (xd3_stream *stream) { |
1069 | return stream->src != NULL && stream->src->srclen > 0; | ||
1070 | } | ||
1008 | static inline | 1071 | static inline |
1009 | xoff_t xd3_encoder_srcbase (xd3_stream *stream) { return stream->src->srcbase; } | 1072 | xoff_t xd3_encoder_srcbase (xd3_stream *stream) { |
1073 | return stream->src->srcbase; | ||
1074 | } | ||
1010 | static inline | 1075 | static inline |
1011 | usize_t xd3_encoder_srclen (xd3_stream *stream) { return stream->src->srclen; } | 1076 | usize_t xd3_encoder_srclen (xd3_stream *stream) { |
1077 | return stream->src->srclen; | ||
1078 | } | ||
1012 | 1079 | ||
1013 | /* Checks for legal flag changes. */ | 1080 | /* Checks for legal flag changes. */ |
1014 | static inline | 1081 | static inline |
1015 | void xd3_set_flags (xd3_stream *stream, int flags) | 1082 | void xd3_set_flags (xd3_stream *stream, int flags) |
1016 | { | 1083 | { |
1017 | /* The bitwise difference should contain only XD3_FLUSH or XD3_SKIP_WINDOW */ | 1084 | /* The bitwise difference should contain only XD3_FLUSH or |
1085 | XD3_SKIP_WINDOW */ | ||
1018 | XD3_ASSERT(((flags ^ stream->flags) & ~(XD3_FLUSH | XD3_SKIP_WINDOW)) == 0); | 1086 | XD3_ASSERT(((flags ^ stream->flags) & ~(XD3_FLUSH | XD3_SKIP_WINDOW)) == 0); |
1019 | stream->flags = flags; | 1087 | stream->flags = flags; |
1020 | } | 1088 | } |
1021 | 1089 | ||
1022 | /* Gives some extra information about the latest library error, if any is known. */ | 1090 | /* Gives some extra information about the latest library error, if any |
1091 | is known. */ | ||
1023 | static inline | 1092 | static inline |
1024 | const char* xd3_errstring (xd3_stream *stream) | 1093 | const char* xd3_errstring (xd3_stream *stream) |
1025 | { | 1094 | { |
1026 | return stream->msg ? stream->msg : ""; | 1095 | return stream->msg ? stream->msg : ""; |
1027 | } | 1096 | } |
1028 | 1097 | ||
1029 | /* This function tells the number of bytes expected to be set in source->onblk after a | 1098 | /* This function tells the number of bytes expected to be set in |
1030 | * getblk request. This is for convenience of handling a partial last block. */ | 1099 | * source->onblk after a getblk request. This is for convenience of |
1100 | * handling a partial last block. */ | ||
1031 | static inline | 1101 | static inline |
1032 | usize_t xd3_bytes_on_srcblk (xd3_source *source, xoff_t blkno) | 1102 | usize_t xd3_bytes_on_srcblk (xd3_source *source, xoff_t blkno) |
1033 | { | 1103 | { |