diff options
author | josh.macdonald <jmacd@users.noreply.github.com> | 2007-10-28 22:20:26 +0000 |
---|---|---|
committer | josh.macdonald <jmacd@users.noreply.github.com> | 2007-10-28 22:20:26 +0000 |
commit | 93250631824866baa87bfa7aac463258250fa6b1 (patch) | |
tree | 8d4583cf77c9cccc6fbab287d273b63691648896 /xdelta3/xdelta3.c | |
parent | 49327439297ae6239f30dc77abf90e86352b7b7e (diff) |
Eliminate calls to __umoddi3 (compiler generated for 64-bit % 32-bit).
More 80col reformatting.
Diffstat (limited to 'xdelta3/xdelta3.c')
-rw-r--r-- | xdelta3/xdelta3.c | 372 |
1 files changed, 208 insertions, 164 deletions
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index 0381206..58fb8b5 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -268,9 +268,9 @@ | |||
268 | 268 | ||
269 | #include "xdelta3.h" | 269 | #include "xdelta3.h" |
270 | 270 | ||
271 | /****************************************************************************************** | 271 | /*********************************************************************** |
272 | STATIC CONFIGURATION | 272 | STATIC CONFIGURATION |
273 | ******************************************************************************************/ | 273 | ***********************************************************************/ |
274 | 274 | ||
275 | #ifndef XD3_MAIN /* the main application */ | 275 | #ifndef XD3_MAIN /* the main application */ |
276 | #define XD3_MAIN 0 | 276 | #define XD3_MAIN 0 |
@@ -304,7 +304,7 @@ | |||
304 | #define IF_ENCODER(x) | 304 | #define IF_ENCODER(x) |
305 | #endif | 305 | #endif |
306 | 306 | ||
307 | /******************************************************************************************/ | 307 | /***********************************************************************/ |
308 | 308 | ||
309 | typedef enum { | 309 | typedef enum { |
310 | 310 | ||
@@ -354,13 +354,13 @@ typedef enum | |||
354 | XD3_CPY = 3, /* XD3_CPY rtypes are represented as (XD3_CPY + copy-mode value) */ | 354 | XD3_CPY = 3, /* XD3_CPY rtypes are represented as (XD3_CPY + copy-mode value) */ |
355 | } xd3_rtype; | 355 | } xd3_rtype; |
356 | 356 | ||
357 | /******************************************************************************************/ | 357 | /***********************************************************************/ |
358 | 358 | ||
359 | #include "xdelta3-list.h" | 359 | #include "xdelta3-list.h" |
360 | 360 | ||
361 | XD3_MAKELIST(xd3_rlist, xd3_rinst, link); | 361 | XD3_MAKELIST(xd3_rlist, xd3_rinst, link); |
362 | 362 | ||
363 | /******************************************************************************************/ | 363 | /***********************************************************************/ |
364 | 364 | ||
365 | #ifndef unlikely /* The unlikely macro - any good? */ | 365 | #ifndef unlikely /* The unlikely macro - any good? */ |
366 | #if defined(__GNUC__) && __GNUC__ >= 3 | 366 | #if defined(__GNUC__) && __GNUC__ >= 3 |
@@ -536,7 +536,7 @@ IF_BUILD_DEFAULT(static const xd3_smatcher __smatcher_default;) | |||
536 | #define IF_REGRESSION(x) | 536 | #define IF_REGRESSION(x) |
537 | #endif | 537 | #endif |
538 | 538 | ||
539 | /******************************************************************************************/ | 539 | /***********************************************************************/ |
540 | 540 | ||
541 | #if XD3_ENCODER | 541 | #if XD3_ENCODER |
542 | static void* xd3_alloc0 (xd3_stream *stream, | 542 | static void* xd3_alloc0 (xd3_stream *stream, |
@@ -565,6 +565,7 @@ static int xd3_emit_double (xd3_stream *stream, xd3_rinst *first, xd3_ri | |||
565 | static int xd3_emit_single (xd3_stream *stream, xd3_rinst *single, uint code); | 565 | static int xd3_emit_single (xd3_stream *stream, xd3_rinst *single, uint code); |
566 | 566 | ||
567 | static usize_t xd3_sizeof_output (xd3_output *output); | 567 | static usize_t xd3_sizeof_output (xd3_output *output); |
568 | static void xd3_encode_reset (xd3_stream *stream); | ||
568 | 569 | ||
569 | static int xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos); | 570 | static int xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos); |
570 | static int xd3_source_extend_match (xd3_stream *stream); | 571 | static int xd3_source_extend_match (xd3_stream *stream); |
@@ -588,7 +589,7 @@ static int xd3_read_uint32_t (xd3_stream *stream, const uint8_t **inpp, | |||
588 | static int xd3_selftest (void); | 589 | static int xd3_selftest (void); |
589 | #endif | 590 | #endif |
590 | 591 | ||
591 | /******************************************************************************************/ | 592 | /***********************************************************************/ |
592 | 593 | ||
593 | #define UINT32_OFLOW_MASK 0xfe000000U | 594 | #define UINT32_OFLOW_MASK 0xfe000000U |
594 | #define UINT64_OFLOW_MASK 0xfe00000000000000ULL | 595 | #define UINT64_OFLOW_MASK 0xfe00000000000000ULL |
@@ -644,7 +645,7 @@ const char* xd3_strerror (int ret) | |||
644 | return NULL; | 645 | return NULL; |
645 | } | 646 | } |
646 | 647 | ||
647 | /******************************************************************************************/ | 648 | /***********************************************************************/ |
648 | 649 | ||
649 | #if SECONDARY_ANY == 0 | 650 | #if SECONDARY_ANY == 0 |
650 | #define IF_SEC(x) | 651 | #define IF_SEC(x) |
@@ -707,7 +708,7 @@ static const xd3_sec_type djw_sec_type = | |||
707 | return XD3_INTERNAL; | 708 | return XD3_INTERNAL; |
708 | #endif | 709 | #endif |
709 | 710 | ||
710 | /******************************************************************************************/ | 711 | /***********************************************************************/ |
711 | 712 | ||
712 | /* Process the inline pass. */ | 713 | /* Process the inline pass. */ |
713 | #define __XDELTA3_C_INLINE_PASS__ | 714 | #define __XDELTA3_C_INLINE_PASS__ |
@@ -734,9 +735,9 @@ static const xd3_sec_type djw_sec_type = | |||
734 | #endif /* __XDELTA3_C_HEADER_PASS__ */ | 735 | #endif /* __XDELTA3_C_HEADER_PASS__ */ |
735 | #ifdef __XDELTA3_C_INLINE_PASS__ | 736 | #ifdef __XDELTA3_C_INLINE_PASS__ |
736 | 737 | ||
737 | /****************************************************************************************** | 738 | /**************************************************************** |
738 | Instruction tables | 739 | Instruction tables |
739 | ******************************************************************************************/ | 740 | *****************************************************************/ |
740 | 741 | ||
741 | /* The following code implements a parametrized description of the | 742 | /* The following code implements a parametrized description of the |
742 | * code table given above for a few reasons. It is not necessary for | 743 | * code table given above for a few reasons. It is not necessary for |
@@ -969,9 +970,10 @@ xd3_alternate_code_table (void) | |||
969 | return __alternate_code_table; | 970 | return __alternate_code_table; |
970 | } | 971 | } |
971 | 972 | ||
972 | /* This function computes the ideal second instruction INST based on preceding instruction | 973 | /* This function computes the ideal second instruction INST based on |
973 | * PREV. If it is possible to issue a double instruction based on this pair it sets | 974 | * preceding instruction PREV. If it is possible to issue a double |
974 | * PREV->code2, otherwise it sets INST->code1. */ | 975 | * instruction based on this pair it sets PREV->code2, otherwise it |
976 | * sets INST->code1. */ | ||
975 | static void | 977 | static void |
976 | xd3_choose_instruction (const xd3_code_table_desc *desc, xd3_rinst *prev, xd3_rinst *inst) | 978 | xd3_choose_instruction (const xd3_code_table_desc *desc, xd3_rinst *prev, xd3_rinst *inst) |
977 | { | 979 | { |
@@ -999,17 +1001,19 @@ xd3_choose_instruction (const xd3_code_table_desc *desc, xd3_rinst *prev, xd3_ri | |||
999 | { | 1001 | { |
1000 | int prev_mode = prev->type - XD3_CPY; | 1002 | int prev_mode = prev->type - XD3_CPY; |
1001 | 1003 | ||
1002 | /* If previous is a copy. Note: as long as the previous is not a RUN | 1004 | /* If previous is a copy. Note: as long as the previous |
1003 | * instruction, it should be a copy because it cannot be an add. This check | 1005 | * is not a RUN instruction, it should be a copy because |
1004 | * is more clear. */ | 1006 | * it cannot be an add. This check is more clear. */ |
1005 | if (prev_mode >= 0 && inst->size <= desc->copyadd_add_max) | 1007 | if (prev_mode >= 0 && inst->size <= desc->copyadd_add_max) |
1006 | { | 1008 | { |
1007 | const xd3_code_table_sizes *sizes = & desc->copyadd_max_sizes[prev_mode]; | 1009 | const xd3_code_table_sizes *sizes = & desc->copyadd_max_sizes[prev_mode]; |
1008 | 1010 | ||
1009 | /* This check and the inst->size-<= above are == in the default table. */ | 1011 | /* This check and the inst->size-<= above are == in |
1012 | the default table. */ | ||
1010 | if (prev->size <= sizes->cpy_max) | 1013 | if (prev->size <= sizes->cpy_max) |
1011 | { | 1014 | { |
1012 | /* The second and third exprs are 0 in the default table. */ | 1015 | /* The second and third exprs are 0 in the |
1016 | default table. */ | ||
1013 | prev->code2 = sizes->offset + (sizes->mult * (prev->size - MIN_MATCH)) + (inst->size - MIN_ADD); | 1017 | prev->code2 = sizes->offset + (sizes->mult * (prev->size - MIN_MATCH)) + (inst->size - MIN_ADD); |
1014 | } | 1018 | } |
1015 | } | 1019 | } |
@@ -1021,9 +1025,10 @@ xd3_choose_instruction (const xd3_code_table_desc *desc, xd3_rinst *prev, xd3_ri | |||
1021 | { | 1025 | { |
1022 | int mode = inst->type - XD3_CPY; | 1026 | int mode = inst->type - XD3_CPY; |
1023 | 1027 | ||
1024 | /* The large copy instruction is offset by the run, large add, and immediate adds, | 1028 | /* The large copy instruction is offset by the run, large add, |
1025 | * then multipled by the number of immediate copies plus one (the large copy) | 1029 | * and immediate adds, then multipled by the number of |
1026 | * (i.e., if there are 15 immediate copy instructions then there are 16 copy | 1030 | * immediate copies plus one (the large copy) (i.e., if there |
1031 | * are 15 immediate copy instructions then there are 16 copy | ||
1027 | * instructions per mode). */ | 1032 | * instructions per mode). */ |
1028 | inst->code1 = 2 + desc->add_sizes + (1 + desc->cpy_sizes) * mode; | 1033 | inst->code1 = 2 + desc->add_sizes + (1 + desc->cpy_sizes) * mode; |
1029 | 1034 | ||
@@ -1118,16 +1123,17 @@ xd3_choose_instruction (/* const xd3_code_table_desc *desc,*/ xd3_rinst *prev, x | |||
1118 | } | 1123 | } |
1119 | #endif /* GENERIC_ENCODE_TABLES */ | 1124 | #endif /* GENERIC_ENCODE_TABLES */ |
1120 | 1125 | ||
1121 | /****************************************************************************************** | 1126 | /*********************************************************************** |
1122 | Instruction table encoder/decoder | 1127 | Instruction table encoder/decoder |
1123 | ******************************************************************************************/ | 1128 | ***********************************************************************/ |
1124 | 1129 | ||
1125 | #if GENERIC_ENCODE_TABLES | 1130 | #if GENERIC_ENCODE_TABLES |
1126 | #if GENERIC_ENCODE_TABLES_COMPUTE == 0 | 1131 | #if GENERIC_ENCODE_TABLES_COMPUTE == 0 |
1127 | 1132 | ||
1128 | /* In this case, we hard-code the result of compute_code_table_encoding for each alternate | 1133 | /* In this case, we hard-code the result of |
1129 | * code table, presuming that saves time/space. This has been 131 bytes, but secondary | 1134 | * compute_code_table_encoding for each alternate code table, |
1130 | * compression was turned off. */ | 1135 | * presuming that saves time/space. This has been 131 bytes, but |
1136 | * secondary compression was turned off. */ | ||
1131 | static const uint8_t __alternate_code_table_compressed[178] = | 1137 | static const uint8_t __alternate_code_table_compressed[178] = |
1132 | {0xd6,0xc3,0xc4,0x00,0x00,0x01,0x8a,0x6f,0x40,0x81,0x27,0x8c,0x00,0x00,0x4a,0x4a,0x0d,0x02,0x01,0x03, | 1138 | {0xd6,0xc3,0xc4,0x00,0x00,0x01,0x8a,0x6f,0x40,0x81,0x27,0x8c,0x00,0x00,0x4a,0x4a,0x0d,0x02,0x01,0x03, |
1133 | 0x01,0x03,0x00,0x01,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, | 1139 | 0x01,0x03,0x00,0x01,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, |
@@ -1210,9 +1216,9 @@ int xd3_compute_code_table_encoding (xd3_stream *in_stream, const xd3_dinst *cod | |||
1210 | return ret; | 1216 | return ret; |
1211 | } | 1217 | } |
1212 | 1218 | ||
1213 | /* Compute a delta between alternate and rfc3284 tables. As soon as another alternate | 1219 | /* Compute a delta between alternate and rfc3284 tables. As soon as |
1214 | * table is added, this code should become generic. For now there is only one alternate | 1220 | * another alternate table is added, this code should become generic. |
1215 | * table for testing. */ | 1221 | * For now there is only one alternate table for testing. */ |
1216 | static int | 1222 | static int |
1217 | xd3_compute_alternate_table_encoding (xd3_stream *stream, const uint8_t **data, usize_t *size) | 1223 | xd3_compute_alternate_table_encoding (xd3_stream *stream, const uint8_t **data, usize_t *size) |
1218 | { | 1224 | { |
@@ -1417,9 +1423,9 @@ xd3_apply_table_encoding (xd3_stream *in_stream, const uint8_t *data, usize_t si | |||
1417 | return ret; | 1423 | return ret; |
1418 | } | 1424 | } |
1419 | 1425 | ||
1420 | /****************************************************************************************** | 1426 | /*********************************************************************** |
1421 | Permute stuff | 1427 | Permute stuff |
1422 | ******************************************************************************************/ | 1428 | ***********************************************************************/ |
1423 | 1429 | ||
1424 | #if HASH_PERMUTE == 0 | 1430 | #if HASH_PERMUTE == 0 |
1425 | #define PERMUTE(x) (x) | 1431 | #define PERMUTE(x) (x) |
@@ -1465,9 +1471,9 @@ static const uint16_t __single_hash[256] = | |||
1465 | }; | 1471 | }; |
1466 | #endif | 1472 | #endif |
1467 | 1473 | ||
1468 | /****************************************************************************************** | 1474 | /*********************************************************************** |
1469 | Ctable stuff | 1475 | Ctable stuff |
1470 | ******************************************************************************************/ | 1476 | ***********************************************************************/ |
1471 | 1477 | ||
1472 | #if HASH_PRIME | 1478 | #if HASH_PRIME |
1473 | static const usize_t __primes[] = | 1479 | static const usize_t __primes[] = |
@@ -1499,9 +1505,9 @@ xd3_checksum_hash (const xd3_hash_cfg *cfg, const uint32_t cksum) | |||
1499 | #endif | 1505 | #endif |
1500 | } | 1506 | } |
1501 | 1507 | ||
1502 | /****************************************************************************************** | 1508 | /*********************************************************************** |
1503 | Create the hash table. | 1509 | Create the hash table. |
1504 | ******************************************************************************************/ | 1510 | ***********************************************************************/ |
1505 | 1511 | ||
1506 | static inline void | 1512 | static inline void |
1507 | xd3_swap_uint8p (uint8_t** p1, uint8_t** p2) | 1513 | xd3_swap_uint8p (uint8_t** p1, uint8_t** p2) |
@@ -1605,9 +1611,9 @@ xd3_size_hashtable (xd3_stream *stream, | |||
1605 | } | 1611 | } |
1606 | #endif | 1612 | #endif |
1607 | 1613 | ||
1608 | /****************************************************************************************** | 1614 | /*********************************************************************** |
1609 | Cksum function | 1615 | Cksum function |
1610 | ******************************************************************************************/ | 1616 | ***********************************************************************/ |
1611 | 1617 | ||
1612 | #if OLD_LARGE_CKSUM | 1618 | #if OLD_LARGE_CKSUM |
1613 | static inline uint32_t | 1619 | static inline uint32_t |
@@ -1652,9 +1658,9 @@ xd3_scksum (const uint8_t *seg, const int ln) | |||
1652 | #define xd3_scksum(seg,ln) xd3_lcksum(seg,ln) | 1658 | #define xd3_scksum(seg,ln) xd3_lcksum(seg,ln) |
1653 | #endif | 1659 | #endif |
1654 | 1660 | ||
1655 | /****************************************************************************************** | 1661 | /*********************************************************************** |
1656 | Adler32 stream function: code copied from Zlib, defined in RFC1950 | 1662 | Adler32 stream function: code copied from Zlib, defined in RFC1950 |
1657 | ******************************************************************************************/ | 1663 | ***********************************************************************/ |
1658 | 1664 | ||
1659 | #define A32_BASE 65521L /* Largest prime smaller than 2^16 */ | 1665 | #define A32_BASE 65521L /* Largest prime smaller than 2^16 */ |
1660 | #define A32_NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ | 1666 | #define A32_NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ |
@@ -1700,9 +1706,9 @@ static unsigned long adler32 (unsigned long adler, const uint8_t *buf, usize_t l | |||
1700 | return (s2 << 16) | s1; | 1706 | return (s2 << 16) | s1; |
1701 | } | 1707 | } |
1702 | 1708 | ||
1703 | /****************************************************************************************** | 1709 | /*********************************************************************** |
1704 | Run-length function | 1710 | Run-length function |
1705 | ******************************************************************************************/ | 1711 | ***********************************************************************/ |
1706 | 1712 | ||
1707 | static inline int | 1713 | static inline int |
1708 | xd3_comprun (const uint8_t *seg, int slook, uint8_t *run_cp) | 1714 | xd3_comprun (const uint8_t *seg, int slook, uint8_t *run_cp) |
@@ -1721,9 +1727,9 @@ xd3_comprun (const uint8_t *seg, int slook, uint8_t *run_cp) | |||
1721 | return run_l; | 1727 | return run_l; |
1722 | } | 1728 | } |
1723 | 1729 | ||
1724 | /****************************************************************************************** | 1730 | /*********************************************************************** |
1725 | Basic encoder/decoder functions | 1731 | Basic encoder/decoder functions |
1726 | ******************************************************************************************/ | 1732 | ***********************************************************************/ |
1727 | 1733 | ||
1728 | static int | 1734 | static int |
1729 | xd3_decode_byte (xd3_stream *stream, uint *val) | 1735 | xd3_decode_byte (xd3_stream *stream, uint *val) |
@@ -1980,9 +1986,9 @@ xd3_sizeof_uint64_t (uint64_t num) | |||
1980 | 1986 | ||
1981 | #endif | 1987 | #endif |
1982 | 1988 | ||
1983 | /****************************************************************************************** | 1989 | /*********************************************************************** |
1984 | Address cache stuff | 1990 | Address cache stuff |
1985 | ******************************************************************************************/ | 1991 | ***********************************************************************/ |
1986 | 1992 | ||
1987 | static int | 1993 | static int |
1988 | xd3_alloc_cache (xd3_stream *stream) | 1994 | xd3_alloc_cache (xd3_stream *stream) |
@@ -2135,9 +2141,9 @@ xd3_decode_address (xd3_stream *stream, usize_t here, uint mode, const uint8_t * | |||
2135 | return 0; | 2141 | return 0; |
2136 | } | 2142 | } |
2137 | 2143 | ||
2138 | /****************************************************************************************** | 2144 | /*********************************************************************** |
2139 | Alloc/free | 2145 | Alloc/free |
2140 | ******************************************************************************************/ | 2146 | ***********************************************************************/ |
2141 | 2147 | ||
2142 | static void* | 2148 | static void* |
2143 | __xd3_alloc_func (void* opaque, usize_t items, usize_t size) | 2149 | __xd3_alloc_func (void* opaque, usize_t items, usize_t size) |
@@ -2387,9 +2393,9 @@ xd3_rtype_to_string (xd3_rtype type, int print_mode) | |||
2387 | } | 2393 | } |
2388 | #endif | 2394 | #endif |
2389 | 2395 | ||
2390 | /****************************************************************************************** | 2396 | /**************************************************************** |
2391 | Stream configuration | 2397 | Stream configuration |
2392 | ******************************************************************************************/ | 2398 | ******************************************************************/ |
2393 | 2399 | ||
2394 | int | 2400 | int |
2395 | xd3_config_stream(xd3_stream *stream, | 2401 | xd3_config_stream(xd3_stream *stream, |
@@ -2565,26 +2571,27 @@ xd3_config_stream(xd3_stream *stream, | |||
2565 | return 0; | 2571 | return 0; |
2566 | } | 2572 | } |
2567 | 2573 | ||
2568 | /****************************************************************************************** | 2574 | /***************************************************************** |
2569 | Getblk interface | 2575 | Getblk interface |
2570 | ******************************************************************************************/ | 2576 | ***********************************************************/ |
2571 | 2577 | ||
2572 | /* This function interfaces with the client getblk function, checks its results, etc. */ | 2578 | /* This function interfaces with the client getblk function, checks |
2579 | * its results, etc. */ | ||
2573 | static int | 2580 | static int |
2574 | xd3_getblk (xd3_stream *stream/*, xd3_source *source*/, xoff_t blkno) | 2581 | xd3_getblk (xd3_stream *stream, xoff_t blkno) |
2575 | { | 2582 | { |
2576 | int ret; | 2583 | int ret; |
2577 | xd3_source *source = stream->src; | 2584 | xd3_source *source = stream->src; |
2578 | 2585 | ||
2579 | if (blkno >= source->blocks) | 2586 | if (source->curblk == NULL || |
2587 | blkno != source->curblkno) | ||
2580 | { | 2588 | { |
2581 | IF_DEBUG1 (DP(RINT "[getblk] block %"Q"u\n", blkno)); | 2589 | if (blkno >= source->blocks) |
2582 | stream->msg = "source file too short"; | 2590 | { |
2583 | return XD3_INTERNAL; | 2591 | stream->msg = "source file too short"; |
2584 | } | 2592 | return XD3_INTERNAL; |
2593 | } | ||
2585 | 2594 | ||
2586 | if (blkno != source->curblkno || source->curblk == NULL) | ||
2587 | { | ||
2588 | XD3_ASSERT (source->curblk != NULL || blkno != source->curblkno); | 2595 | XD3_ASSERT (source->curblk != NULL || blkno != source->curblkno); |
2589 | 2596 | ||
2590 | source->getblkno = blkno; | 2597 | source->getblkno = blkno; |
@@ -2603,7 +2610,8 @@ xd3_getblk (xd3_stream *stream/*, xd3_source *source*/, xoff_t blkno) | |||
2603 | XD3_ASSERT (source->curblk != NULL); | 2610 | XD3_ASSERT (source->curblk != NULL); |
2604 | } | 2611 | } |
2605 | 2612 | ||
2606 | if (source->onblk != xd3_bytes_on_srcblk (source, blkno)) | 2613 | if (source->onblk != (blkno == source->blocks - 1 ? |
2614 | source->onlastblk : source->blksize)) | ||
2607 | { | 2615 | { |
2608 | stream->msg = "getblk returned short block"; | 2616 | stream->msg = "getblk returned short block"; |
2609 | return XD3_INTERNAL; | 2617 | return XD3_INTERNAL; |
@@ -2612,9 +2620,9 @@ xd3_getblk (xd3_stream *stream/*, xd3_source *source*/, xoff_t blkno) | |||
2612 | return 0; | 2620 | return 0; |
2613 | } | 2621 | } |
2614 | 2622 | ||
2615 | /****************************************************************************************** | 2623 | /*********************************************************** |
2616 | Stream open/close | 2624 | Stream open/close |
2617 | ******************************************************************************************/ | 2625 | ***************************************************************/ |
2618 | 2626 | ||
2619 | int | 2627 | int |
2620 | xd3_set_source (xd3_stream *stream, | 2628 | xd3_set_source (xd3_stream *stream, |
@@ -2629,8 +2637,9 @@ xd3_set_source (xd3_stream *stream, | |||
2629 | 2637 | ||
2630 | stream->src = src; | 2638 | stream->src = src; |
2631 | blk_num = src->size / src->blksize; | 2639 | blk_num = src->size / src->blksize; |
2632 | tail_size = src->size % src->blksize; | 2640 | tail_size = src->size - (blk_num * src->blksize); |
2633 | src->blocks = blk_num + (tail_size > 0); | 2641 | src->blocks = blk_num + (tail_size > 0); |
2642 | src->onlastblk = xd3_bytes_on_srcblk (src, src->blocks - 1); | ||
2634 | src->srclen = 0; | 2643 | src->srclen = 0; |
2635 | src->srcbase = 0; | 2644 | src->srcbase = 0; |
2636 | 2645 | ||
@@ -2649,7 +2658,22 @@ xd3_close_stream (xd3_stream *stream) | |||
2649 | { | 2658 | { |
2650 | if (stream->enc_state != 0 && stream->enc_state != ENC_ABORTED) | 2659 | if (stream->enc_state != 0 && stream->enc_state != ENC_ABORTED) |
2651 | { | 2660 | { |
2652 | /* If encoding, should be ready for more input but not actually have any. */ | 2661 | if (stream->buf_leftover != NULL) |
2662 | { | ||
2663 | stream->msg = "encoding is incomplete"; | ||
2664 | return XD3_INTERNAL; | ||
2665 | } | ||
2666 | |||
2667 | if (stream->enc_state == ENC_POSTWIN) | ||
2668 | { | ||
2669 | xd3_encode_reset (stream); | ||
2670 | |||
2671 | stream->current_window += 1; | ||
2672 | stream->enc_state = ENC_INPUT; | ||
2673 | } | ||
2674 | |||
2675 | /* If encoding, should be ready for more input but not actually | ||
2676 | have any. */ | ||
2653 | if (stream->enc_state != ENC_INPUT || stream->avail_in != 0) | 2677 | if (stream->enc_state != ENC_INPUT || stream->avail_in != 0) |
2654 | { | 2678 | { |
2655 | stream->msg = "encoding is incomplete"; | 2679 | stream->msg = "encoding is incomplete"; |
@@ -2678,9 +2702,9 @@ xd3_close_stream (xd3_stream *stream) | |||
2678 | return 0; | 2702 | return 0; |
2679 | } | 2703 | } |
2680 | 2704 | ||
2681 | /****************************************************************************************** | 2705 | /************************************************************** |
2682 | Application header | 2706 | Application header |
2683 | ******************************************************************************************/ | 2707 | ****************************************************************/ |
2684 | 2708 | ||
2685 | int | 2709 | int |
2686 | xd3_get_appheader (xd3_stream *stream, | 2710 | xd3_get_appheader (xd3_stream *stream, |
@@ -2698,15 +2722,15 @@ xd3_get_appheader (xd3_stream *stream, | |||
2698 | return 0; | 2722 | return 0; |
2699 | } | 2723 | } |
2700 | 2724 | ||
2701 | /****************************************************************************************** | 2725 | /********************************************************** |
2702 | Decoder stuff | 2726 | Decoder stuff |
2703 | ******************************************************************************************/ | 2727 | *************************************************/ |
2704 | 2728 | ||
2705 | #include "xdelta3-decode.h" | 2729 | #include "xdelta3-decode.h" |
2706 | 2730 | ||
2707 | /****************************************************************************************** | 2731 | /**************************************************************** |
2708 | Encoder stuff | 2732 | Encoder stuff |
2709 | ******************************************************************************************/ | 2733 | *****************************************************************/ |
2710 | 2734 | ||
2711 | #if XD3_ENCODER | 2735 | #if XD3_ENCODER |
2712 | void | 2736 | void |
@@ -3461,9 +3485,9 @@ xd3_emit_hdr (xd3_stream *stream) | |||
3461 | return 0; | 3485 | return 0; |
3462 | } | 3486 | } |
3463 | 3487 | ||
3464 | /****************************************************************************************** | 3488 | /**************************************************************** |
3465 | Encode routines | 3489 | Encode routines |
3466 | ******************************************************************************************/ | 3490 | ****************************************************************/ |
3467 | 3491 | ||
3468 | static int | 3492 | static int |
3469 | xd3_encode_buffer_leftover (xd3_stream *stream) | 3493 | xd3_encode_buffer_leftover (xd3_stream *stream) |
@@ -3716,9 +3740,9 @@ xd3_encode_input (xd3_stream *stream) | |||
3716 | 3740 | ||
3717 | stream->enc_state = ENC_SEARCH; | 3741 | stream->enc_state = ENC_SEARCH; |
3718 | 3742 | ||
3719 | IF_DEBUG1 (DP(RINT "[input window:%"Q"u] input bytes %u offset %"Q"u\n", | 3743 | IF_DEBUG1 (DP(RINT "[WINSTART:%"Q"u] input bytes %u offset %"Q"u\n", |
3720 | stream->current_window, stream->avail_in, stream->total_in)); | 3744 | stream->current_window, stream->avail_in, |
3721 | 3745 | stream->total_in)); | |
3722 | return XD3_WINSTART; | 3746 | return XD3_WINSTART; |
3723 | 3747 | ||
3724 | case ENC_SEARCH: | 3748 | case ENC_SEARCH: |
@@ -3847,6 +3871,9 @@ xd3_encode_input (xd3_stream *stream) | |||
3847 | stream->total_in += (xoff_t) stream->avail_in; | 3871 | stream->total_in += (xoff_t) stream->avail_in; |
3848 | stream->enc_state = ENC_POSTWIN; | 3872 | stream->enc_state = ENC_POSTWIN; |
3849 | 3873 | ||
3874 | IF_DEBUG1 (DP(RINT "[WINFINISH:%"Q"u] in=%"Q"u\n", | ||
3875 | stream->current_window, | ||
3876 | stream->total_in)); | ||
3850 | return XD3_WINFINISH; | 3877 | return XD3_WINFINISH; |
3851 | 3878 | ||
3852 | case ENC_POSTWIN: | 3879 | case ENC_POSTWIN: |
@@ -4390,7 +4417,7 @@ xd3_source_extend_match (xd3_stream *stream) | |||
4390 | matchoff = stream->match_srcpos - stream->match_back; | 4417 | matchoff = stream->match_srcpos - stream->match_back; |
4391 | streamoff = stream->input_position - stream->match_back; | 4418 | streamoff = stream->input_position - stream->match_back; |
4392 | tryblk = matchoff / src->blksize; | 4419 | tryblk = matchoff / src->blksize; |
4393 | tryoff = matchoff % src->blksize; | 4420 | tryoff = matchoff - (tryblk * src->blksize); |
4394 | 4421 | ||
4395 | /* this loops backward over source blocks */ | 4422 | /* this loops backward over source blocks */ |
4396 | while (stream->match_back < stream->match_maxback) | 4423 | while (stream->match_back < stream->match_maxback) |
@@ -4439,7 +4466,7 @@ xd3_source_extend_match (xd3_stream *stream) | |||
4439 | matchoff = stream->match_srcpos + stream->match_fwd; | 4466 | matchoff = stream->match_srcpos + stream->match_fwd; |
4440 | streamoff = stream->input_position + stream->match_fwd; | 4467 | streamoff = stream->input_position + stream->match_fwd; |
4441 | tryblk = matchoff / src->blksize; | 4468 | tryblk = matchoff / src->blksize; |
4442 | tryoff = matchoff % src->blksize; | 4469 | tryoff = matchoff - (tryblk * src->blksize); |
4443 | 4470 | ||
4444 | /* Note: practically the same code as backwards case above: same comments */ | 4471 | /* Note: practically the same code as backwards case above: same comments */ |
4445 | while (stream->match_fwd < stream->match_maxfwd) | 4472 | while (stream->match_fwd < stream->match_maxfwd) |
@@ -4481,10 +4508,11 @@ xd3_source_extend_match (xd3_stream *stream) | |||
4481 | donefwd: | 4508 | donefwd: |
4482 | stream->match_state = MATCH_SEARCHING; | 4509 | stream->match_state = MATCH_SEARCHING; |
4483 | 4510 | ||
4484 | /* If the match ends short of the last instruction end, we probably don't want it. | 4511 | /* If the match ends short of the last instruction end, we probably |
4485 | * There is the possibility that a copy ends short of the last copy but also goes | 4512 | * don't want it. There is the possibility that a copy ends short |
4486 | * further back, in which case we might want it. This code does not implement such: if | 4513 | * of the last copy but also goes further back, in which case we |
4487 | * so we would need more complicated xd3_iopt_erase logic. */ | 4514 | * might want it. This code does not implement such: if so we would |
4515 | * need more complicated xd3_iopt_erase logic. */ | ||
4488 | if (stream->match_fwd < stream->min_match) | 4516 | if (stream->match_fwd < stream->min_match) |
4489 | { | 4517 | { |
4490 | stream->match_fwd = 0; | 4518 | stream->match_fwd = 0; |
@@ -4499,8 +4527,9 @@ xd3_source_extend_match (xd3_stream *stream) | |||
4499 | xoff_t match_position = stream->match_srcpos - stream->match_back; | 4527 | xoff_t match_position = stream->match_srcpos - stream->match_back; |
4500 | xoff_t match_end = stream->match_srcpos + stream->match_fwd; | 4528 | xoff_t match_end = stream->match_srcpos + stream->match_fwd; |
4501 | 4529 | ||
4502 | /* At this point we may have to erase any iopt-buffer instructions that are | 4530 | /* At this point we may have to erase any iopt-buffer |
4503 | * fully covered by a backward-extending copy. */ | 4531 | * instructions that are fully covered by a backward-extending |
4532 | * copy. */ | ||
4504 | if (stream->match_back > 0) | 4533 | if (stream->match_back > 0) |
4505 | { | 4534 | { |
4506 | xd3_iopt_erase (stream, target_position, total); | 4535 | xd3_iopt_erase (stream, target_position, total); |
@@ -4508,7 +4537,8 @@ xd3_source_extend_match (xd3_stream *stream) | |||
4508 | 4537 | ||
4509 | stream->match_back = 0; | 4538 | stream->match_back = 0; |
4510 | 4539 | ||
4511 | /* Update ranges. The first source match occurs with both values set to 0. */ | 4540 | /* Update ranges. The first source match occurs with both |
4541 | values set to 0. */ | ||
4512 | if (stream->match_maxaddr == 0 || | 4542 | if (stream->match_maxaddr == 0 || |
4513 | match_position < stream->match_minaddr) | 4543 | match_position < stream->match_minaddr) |
4514 | { | 4544 | { |
@@ -4735,40 +4765,6 @@ xd3_verify_run_state (xd3_stream *stream, | |||
4735 | XD3_ASSERT (x_run_l > slook || run_l == x_run_l); | 4765 | XD3_ASSERT (x_run_l > slook || run_l == x_run_l); |
4736 | } | 4766 | } |
4737 | #endif /* XD3_DEBUG */ | 4767 | #endif /* XD3_DEBUG */ |
4738 | #endif /* XD3_ENCODER */ | ||
4739 | |||
4740 | /****************************************************************************************** | ||
4741 | TEMPLATE pass | ||
4742 | ******************************************************************************************/ | ||
4743 | |||
4744 | #endif /* __XDELTA3_C_INLINE_PASS__ */ | ||
4745 | #ifdef __XDELTA3_C_TEMPLATE_PASS__ | ||
4746 | |||
4747 | #if XD3_ENCODER | ||
4748 | |||
4749 | /****************************************************************************************** | ||
4750 | Templates | ||
4751 | ******************************************************************************************/ | ||
4752 | |||
4753 | /* Template macros */ | ||
4754 | #define XD3_TEMPLATE(x) XD3_TEMPLATE2(x,TEMPLATE) | ||
4755 | #define XD3_TEMPLATE2(x,n) XD3_TEMPLATE3(x,n) | ||
4756 | #define XD3_TEMPLATE3(x,n) x ## n | ||
4757 | #define XD3_STRINGIFY(x) XD3_STRINGIFY2(x) | ||
4758 | #define XD3_STRINGIFY2(x) #x | ||
4759 | |||
4760 | static int XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream); | ||
4761 | |||
4762 | static const xd3_smatcher XD3_TEMPLATE(__smatcher_) = | ||
4763 | { | ||
4764 | XD3_STRINGIFY(TEMPLATE), | ||
4765 | XD3_TEMPLATE(xd3_string_match_), | ||
4766 | #if SOFTCFG == 1 | ||
4767 | 0, 0, 0, 0, 0, 0, 0 | ||
4768 | #else | ||
4769 | LLOOK, LSTEP, SLOOK, SCHAIN, SLCHAIN, MAXLAZY, LONGENOUGH | ||
4770 | #endif | ||
4771 | }; | ||
4772 | 4768 | ||
4773 | /* This function computes more source checksums to advance the window. | 4769 | /* This function computes more source checksums to advance the window. |
4774 | * Called at every entrance to the string-match loop and each time | 4770 | * Called at every entrance to the string-match loop and each time |
@@ -4778,10 +4774,9 @@ static const xd3_smatcher XD3_TEMPLATE(__smatcher_) = | |||
4778 | * | 4774 | * |
4779 | * TODO: really would like a good test for this logic. how? | 4775 | * TODO: really would like a good test for this logic. how? |
4780 | * TODO: optimize the inner loop | 4776 | * TODO: optimize the inner loop |
4781 | * TODO: do-templatize this | ||
4782 | */ | 4777 | */ |
4783 | static int | 4778 | static int |
4784 | XD3_TEMPLATE(xd3_srcwin_move_point_) (xd3_stream *stream, usize_t *next_move_point) | 4779 | xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point) |
4785 | { | 4780 | { |
4786 | xoff_t logical_input_cksum_pos; | 4781 | xoff_t logical_input_cksum_pos; |
4787 | 4782 | ||
@@ -4845,11 +4840,12 @@ XD3_TEMPLATE(xd3_srcwin_move_point_) (xd3_stream *stream, usize_t *next_move_poi | |||
4845 | stream->srcwin_cksum_pos < stream->src->size) | 4840 | stream->srcwin_cksum_pos < stream->src->size) |
4846 | { | 4841 | { |
4847 | xoff_t blkno = stream->srcwin_cksum_pos / stream->src->blksize; | 4842 | xoff_t blkno = stream->srcwin_cksum_pos / stream->src->blksize; |
4848 | ssize_t oldpos = stream->srcwin_cksum_pos % stream->src->blksize; | 4843 | xoff_t blkbaseoffset = blkno * stream->src->blksize; |
4849 | ssize_t blkpos = xd3_bytes_on_srcblk (stream->src, blkno); | 4844 | ssize_t oldpos = stream->srcwin_cksum_pos - blkbaseoffset; |
4845 | ssize_t blkpos = xd3_bytes_on_srcblk_fast (stream->src, blkno); | ||
4850 | int ret; | 4846 | int ret; |
4851 | 4847 | ||
4852 | if (oldpos + LLOOK > blkpos) | 4848 | if (oldpos + stream->smatcher.large_look > blkpos) |
4853 | { | 4849 | { |
4854 | stream->srcwin_cksum_pos = (blkno + 1) * stream->src->blksize; | 4850 | stream->srcwin_cksum_pos = (blkno + 1) * stream->src->blksize; |
4855 | continue; | 4851 | continue; |
@@ -4874,20 +4870,22 @@ XD3_TEMPLATE(xd3_srcwin_move_point_) (xd3_stream *stream, usize_t *next_move_poi | |||
4874 | * the number of bytes available. Each iteration inspects | 4870 | * the number of bytes available. Each iteration inspects |
4875 | * large_look bytes then steps back large_step bytes. The | 4871 | * large_look bytes then steps back large_step bytes. The |
4876 | * if-stmt above ensures at least one large_look of data. */ | 4872 | * if-stmt above ensures at least one large_look of data. */ |
4877 | blkpos -= LLOOK; | 4873 | blkpos -= stream->smatcher.large_look; |
4874 | blkbaseoffset = stream->src->blksize * blkno; | ||
4878 | 4875 | ||
4879 | do | 4876 | do |
4880 | { | 4877 | { |
4881 | uint32_t cksum = xd3_lcksum (stream->src->curblk + blkpos, LLOOK); | 4878 | uint32_t cksum = xd3_lcksum (stream->src->curblk + blkpos, |
4879 | stream->smatcher.large_look); | ||
4882 | usize_t hval = xd3_checksum_hash (& stream->large_hash, cksum); | 4880 | usize_t hval = xd3_checksum_hash (& stream->large_hash, cksum); |
4883 | 4881 | ||
4884 | stream->large_table[hval] = | 4882 | stream->large_table[hval] = |
4885 | (usize_t) ((stream->src->blksize * blkno) + | 4883 | (usize_t) (blkbaseoffset + |
4886 | (xoff_t)(blkpos + HASH_CKOFFSET)); | 4884 | (xoff_t)(blkpos + HASH_CKOFFSET)); |
4887 | 4885 | ||
4888 | IF_DEBUG (stream->large_ckcnt += 1); | 4886 | IF_DEBUG (stream->large_ckcnt += 1); |
4889 | 4887 | ||
4890 | blkpos -= LSTEP; | 4888 | blkpos -= stream->smatcher.large_step; |
4891 | } | 4889 | } |
4892 | while (blkpos >= oldpos); | 4890 | while (blkpos >= oldpos); |
4893 | 4891 | ||
@@ -4909,6 +4907,41 @@ XD3_TEMPLATE(xd3_srcwin_move_point_) (xd3_stream *stream, usize_t *next_move_poi | |||
4909 | return 0; | 4907 | return 0; |
4910 | } | 4908 | } |
4911 | 4909 | ||
4910 | #endif /* XD3_ENCODER */ | ||
4911 | |||
4912 | /******************************************************************** | ||
4913 | TEMPLATE pass | ||
4914 | *********************************************************************/ | ||
4915 | |||
4916 | #endif /* __XDELTA3_C_INLINE_PASS__ */ | ||
4917 | #ifdef __XDELTA3_C_TEMPLATE_PASS__ | ||
4918 | |||
4919 | #if XD3_ENCODER | ||
4920 | |||
4921 | /******************************************************************** | ||
4922 | Templates | ||
4923 | *******************************************************************/ | ||
4924 | |||
4925 | /* Template macros */ | ||
4926 | #define XD3_TEMPLATE(x) XD3_TEMPLATE2(x,TEMPLATE) | ||
4927 | #define XD3_TEMPLATE2(x,n) XD3_TEMPLATE3(x,n) | ||
4928 | #define XD3_TEMPLATE3(x,n) x ## n | ||
4929 | #define XD3_STRINGIFY(x) XD3_STRINGIFY2(x) | ||
4930 | #define XD3_STRINGIFY2(x) #x | ||
4931 | |||
4932 | static int XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream); | ||
4933 | |||
4934 | static const xd3_smatcher XD3_TEMPLATE(__smatcher_) = | ||
4935 | { | ||
4936 | XD3_STRINGIFY(TEMPLATE), | ||
4937 | XD3_TEMPLATE(xd3_string_match_), | ||
4938 | #if SOFTCFG == 1 | ||
4939 | 0, 0, 0, 0, 0, 0, 0 | ||
4940 | #else | ||
4941 | LLOOK, LSTEP, SLOOK, SCHAIN, SLCHAIN, MAXLAZY, LONGENOUGH | ||
4942 | #endif | ||
4943 | }; | ||
4944 | |||
4912 | static int | 4945 | static int |
4913 | XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) | 4946 | XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) |
4914 | { | 4947 | { |
@@ -4930,24 +4963,27 @@ XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) | |||
4930 | usize_t match_offset = 0; | 4963 | usize_t match_offset = 0; |
4931 | usize_t next_move_point; | 4964 | usize_t next_move_point; |
4932 | 4965 | ||
4933 | /* If there will be no compression due to settings or short input, skip it entirely. */ | 4966 | /* If there will be no compression due to settings or short input, |
4967 | skip it entirely. */ | ||
4934 | if (! (DO_SMALL || DO_LARGE || DO_RUN) || | 4968 | if (! (DO_SMALL || DO_LARGE || DO_RUN) || |
4935 | stream->input_position + SLOOK > stream->avail_in) { goto loopnomore; } | 4969 | stream->input_position + SLOOK > stream->avail_in) { goto loopnomore; } |
4936 | 4970 | ||
4937 | if ((ret = xd3_string_match_init (stream))) { return ret; } | 4971 | if ((ret = xd3_string_match_init (stream))) { return ret; } |
4938 | 4972 | ||
4939 | /* The restartloop label is reached when the incremental loop state needs to be | 4973 | /* The restartloop label is reached when the incremental loop state |
4940 | * reset. */ | 4974 | * needs to be reset. */ |
4941 | restartloop: | 4975 | restartloop: |
4942 | 4976 | ||
4943 | /* If there is not enough input remaining for any kind of match, skip it. */ | 4977 | /* If there is not enough input remaining for any kind of match, |
4978 | skip it. */ | ||
4944 | if (stream->input_position + SLOOK > stream->avail_in) { goto loopnomore; } | 4979 | if (stream->input_position + SLOOK > stream->avail_in) { goto loopnomore; } |
4945 | 4980 | ||
4946 | /* Now reset the incremental loop state: */ | 4981 | /* Now reset the incremental loop state: */ |
4947 | 4982 | ||
4948 | /* The min_match variable is updated to avoid matching the same lazy match over and over | 4983 | /* The min_match variable is updated to avoid matching the same lazy |
4949 | * again. For example, if you find a (small) match of length 9 at one position, you | 4984 | * match over and over again. For example, if you find a (small) |
4950 | * will likely find a match of length 8 at the next position. */ | 4985 | * match of length 9 at one position, you will likely find a match |
4986 | * of length 8 at the next position. */ | ||
4951 | if (xd3_iopt_last_matched (stream) > stream->input_position) | 4987 | if (xd3_iopt_last_matched (stream) > stream->input_position) |
4952 | { | 4988 | { |
4953 | stream->min_match = max(MIN_MATCH, 1 + xd3_iopt_last_matched(stream) - stream->input_position); | 4989 | stream->min_match = max(MIN_MATCH, 1 + xd3_iopt_last_matched(stream) - stream->input_position); |
@@ -4972,13 +5008,15 @@ XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) | |||
4972 | run_l = xd3_comprun (inp, SLOOK, & run_c); | 5008 | run_l = xd3_comprun (inp, SLOOK, & run_c); |
4973 | } | 5009 | } |
4974 | 5010 | ||
4975 | /* Large match state. We continue the loop even after not enough bytes for LLOOK | 5011 | /* Large match state. We continue the loop even after not enough |
4976 | * remain, so always check stream->input_position in DO_LARGE code. */ | 5012 | * bytes for LLOOK remain, so always check stream->input_position in |
5013 | * DO_LARGE code. */ | ||
4977 | if (DO_LARGE && (stream->input_position + LLOOK <= stream->avail_in)) | 5014 | if (DO_LARGE && (stream->input_position + LLOOK <= stream->avail_in)) |
4978 | { | 5015 | { |
4979 | /* Source window: next_move_point is the point that stream->input_position must reach before | 5016 | /* Source window: next_move_point is the point that |
4980 | * computing more source checksum. */ | 5017 | * stream->input_position must reach before computing more |
4981 | if ((ret = XD3_TEMPLATE(xd3_srcwin_move_point_) (stream, & next_move_point))) | 5018 | * source checksum. */ |
5019 | if ((ret = xd3_srcwin_move_point (stream, & next_move_point))) | ||
4982 | { | 5020 | { |
4983 | return ret; | 5021 | return ret; |
4984 | } | 5022 | } |
@@ -4986,15 +5024,16 @@ XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) | |||
4986 | lcksum = xd3_lcksum (inp, LLOOK); | 5024 | lcksum = xd3_lcksum (inp, LLOOK); |
4987 | } | 5025 | } |
4988 | 5026 | ||
4989 | /* TRYLAZYLEN: True if a certain length match should be followed by lazy search. This | 5027 | /* TRYLAZYLEN: True if a certain length match should be followed by |
4990 | * checks that LEN is shorter than MAXLAZY and that there is enough leftover data to | 5028 | * lazy search. This checks that LEN is shorter than MAXLAZY and |
4991 | * consider lazy matching. "Enough" is set to 2 since the next match will start at the | 5029 | * that there is enough leftover data to consider lazy matching. |
4992 | * next offset, it must match two extra characters. */ | 5030 | * "Enough" is set to 2 since the next match will start at the next |
5031 | * offset, it must match two extra characters. */ | ||
4993 | #define TRYLAZYLEN(LEN,POS,MAX) ((MAXLAZY) > 0 && (LEN) < (MAXLAZY) && (POS) + (LEN) <= (MAX) - 2) | 5032 | #define TRYLAZYLEN(LEN,POS,MAX) ((MAXLAZY) > 0 && (LEN) < (MAXLAZY) && (POS) + (LEN) <= (MAX) - 2) |
4994 | 5033 | ||
4995 | /* HANDLELAZY: This statement is called each time an instruciton is emitted (three | 5034 | /* HANDLELAZY: This statement is called each time an instruciton is |
4996 | * cases). If the instruction is large enough, the loop is restarted, otherwise lazy | 5035 | * emitted (three cases). If the instruction is large enough, the |
4997 | * matching may ensue. */ | 5036 | * loop is restarted, otherwise lazy matching may ensue. */ |
4998 | #define HANDLELAZY(mlen) \ | 5037 | #define HANDLELAZY(mlen) \ |
4999 | if (TRYLAZYLEN ((mlen), (stream->input_position), (stream->avail_in))) \ | 5038 | if (TRYLAZYLEN ((mlen), (stream->input_position), (stream->avail_in))) \ |
5000 | { stream->min_match = (mlen) + LEAST_MATCH_INCR; goto updateone; } \ | 5039 | { stream->min_match = (mlen) + LEAST_MATCH_INCR; goto updateone; } \ |
@@ -5007,12 +5046,13 @@ XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) | |||
5007 | /* Now we try three kinds of string match in order of expense: | 5046 | /* Now we try three kinds of string match in order of expense: |
5008 | * run, large match, small match. */ | 5047 | * run, large match, small match. */ |
5009 | 5048 | ||
5010 | /* Expand the start of a RUN. The test for (run_l == SLOOK) avoids repeating this | 5049 | /* Expand the start of a RUN. The test for (run_l == SLOOK) |
5011 | * check when we pass through a run area performing lazy matching. The run is only | 5050 | * avoids repeating this check when we pass through a run area |
5012 | * expanded once when the min_match is first reached. If lazy matching is | 5051 | * performing lazy matching. The run is only expanded once when |
5013 | * performed, the run_l variable will remain inconsistent until the first | 5052 | * the min_match is first reached. If lazy matching is |
5014 | * non-running input character is reached, at which time the run_l may then again | 5053 | * performed, the run_l variable will remain inconsistent until |
5015 | * grow to SLOOK. */ | 5054 | * the first non-running input character is reached, at which |
5055 | * time the run_l may then again grow to SLOOK. */ | ||
5016 | if (DO_RUN && run_l == SLOOK) | 5056 | if (DO_RUN && run_l == SLOOK) |
5017 | { | 5057 | { |
5018 | usize_t max_len = stream->avail_in - stream->input_position; | 5058 | usize_t max_len = stream->avail_in - stream->input_position; |
@@ -5034,7 +5074,7 @@ XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) | |||
5034 | if (DO_LARGE && (stream->input_position + LLOOK <= stream->avail_in)) | 5074 | if (DO_LARGE && (stream->input_position + LLOOK <= stream->avail_in)) |
5035 | { | 5075 | { |
5036 | if ((stream->input_position >= next_move_point) && | 5076 | if ((stream->input_position >= next_move_point) && |
5037 | (ret = XD3_TEMPLATE(xd3_srcwin_move_point_) (stream, & next_move_point))) | 5077 | (ret = xd3_srcwin_move_point (stream, & next_move_point))) |
5038 | { | 5078 | { |
5039 | return ret; | 5079 | return ret; |
5040 | } | 5080 | } |
@@ -5043,15 +5083,18 @@ XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) | |||
5043 | 5083 | ||
5044 | IF_DEBUG (xd3_verify_large_state (stream, inp, lcksum)); | 5084 | IF_DEBUG (xd3_verify_large_state (stream, inp, lcksum)); |
5045 | 5085 | ||
5046 | /* Note: To handle large checksum duplicates, this code should be rearranged to | 5086 | /* Note: To handle large checksum duplicates, this code |
5047 | * resemble the small_match case more. But how much of the code can be truly | 5087 | * should be rearranged to resemble the small_match case |
5048 | * shared? The main difference is the need for xd3_source_extend_match to work | 5088 | * more. But how much of the code can be truly shared? The |
5049 | * outside of xd3_string_match, in the case where inputs are identical. */ | 5089 | * main difference is the need for xd3_source_extend_match |
5090 | * to work outside of xd3_string_match, in the case where | ||
5091 | * inputs are identical. */ | ||
5050 | if (unlikely (stream->large_table[linx] != 0)) | 5092 | if (unlikely (stream->large_table[linx] != 0)) |
5051 | { | 5093 | { |
5052 | /* the match_setup will fail if the source window has been decided and the | 5094 | /* the match_setup will fail if the source window has |
5053 | * match lies outside it. You could consider forcing a window at this point | 5095 | * been decided and the match lies outside it. You |
5054 | * to permit a new source window. */ | 5096 | * could consider forcing a window at this point to |
5097 | * permit a new source window. */ | ||
5055 | xoff_t adj_offset = | 5098 | xoff_t adj_offset = |
5056 | xd3_source_cksum_offset(stream, | 5099 | xd3_source_cksum_offset(stream, |
5057 | stream->large_table[linx] - HASH_CKOFFSET); | 5100 | stream->large_table[linx] - HASH_CKOFFSET); |
@@ -5121,8 +5164,9 @@ XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) | |||
5121 | } | 5164 | } |
5122 | } | 5165 | } |
5123 | 5166 | ||
5124 | /* The logic above prevents excess work during lazy matching by increasing min_match | 5167 | /* The logic above prevents excess work during lazy matching by |
5125 | * to avoid smaller matches. Each time we advance stream->input_position by one, the minimum match | 5168 | * increasing min_match to avoid smaller matches. Each time we |
5169 | * advance stream->input_position by one, the minimum match | ||
5126 | * shortens as well. */ | 5170 | * shortens as well. */ |
5127 | if (stream->min_match > MIN_MATCH) | 5171 | if (stream->min_match > MIN_MATCH) |
5128 | { | 5172 | { |