diff options
Diffstat (limited to 'xdelta3/xdelta3.c')
-rw-r--r-- | xdelta3/xdelta3.c | 309 |
1 files changed, 146 insertions, 163 deletions
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index 95ff509..d95d97d 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -350,7 +350,9 @@ typedef unsigned int xd3_rtype; | |||
350 | 350 | ||
351 | #include "xdelta3-list.h" | 351 | #include "xdelta3-list.h" |
352 | 352 | ||
353 | #if XD3_ENCODER | ||
353 | XD3_MAKELIST(xd3_rlist, xd3_rinst, link); | 354 | XD3_MAKELIST(xd3_rlist, xd3_rinst, link); |
355 | #endif | ||
354 | 356 | ||
355 | /***********************************************************************/ | 357 | /***********************************************************************/ |
356 | 358 | ||
@@ -376,9 +378,6 @@ XD3_MAKELIST(xd3_rlist, xd3_rinst, link); | |||
376 | #define ALPHABET_SIZE 256 /* Used in test code--size of the secondary | 378 | #define ALPHABET_SIZE 256 /* Used in test code--size of the secondary |
377 | * compressor alphabet. */ | 379 | * compressor alphabet. */ |
378 | 380 | ||
379 | #define HASH_PERMUTE 1 /* The input is permuted by random nums */ | ||
380 | #define ADLER_LARGE_CKSUM 1 /* Adler checksum vs. RK checksum */ | ||
381 | |||
382 | #define HASH_CKOFFSET 1U /* Table entries distinguish "no-entry" from | 381 | #define HASH_CKOFFSET 1U /* Table entries distinguish "no-entry" from |
383 | * offset 0 using this offset. */ | 382 | * offset 0 using this offset. */ |
384 | 383 | ||
@@ -476,9 +475,9 @@ static void xd3_free_output (xd3_stream *stream, | |||
476 | xd3_output *output); | 475 | xd3_output *output); |
477 | 476 | ||
478 | static int xd3_emit_double (xd3_stream *stream, xd3_rinst *first, | 477 | static int xd3_emit_double (xd3_stream *stream, xd3_rinst *first, |
479 | xd3_rinst *second, usize_t code); | 478 | xd3_rinst *second, uint8_t code); |
480 | static int xd3_emit_single (xd3_stream *stream, xd3_rinst *single, | 479 | static int xd3_emit_single (xd3_stream *stream, xd3_rinst *single, |
481 | usize_t code); | 480 | uint8_t code); |
482 | 481 | ||
483 | static usize_t xd3_sizeof_output (xd3_output *output); | 482 | static usize_t xd3_sizeof_output (xd3_output *output); |
484 | static void xd3_encode_reset (xd3_stream *stream); | 483 | static void xd3_encode_reset (xd3_stream *stream); |
@@ -503,8 +502,6 @@ static int xd3_srcwin_move_point (xd3_stream *stream, | |||
503 | 502 | ||
504 | static int xd3_emit_run (xd3_stream *stream, usize_t pos, | 503 | static int xd3_emit_run (xd3_stream *stream, usize_t pos, |
505 | usize_t size, uint8_t *run_c); | 504 | usize_t size, uint8_t *run_c); |
506 | static usize_t xd3_checksum_hash (const xd3_hash_cfg *cfg, | ||
507 | const usize_t cksum); | ||
508 | static xoff_t xd3_source_cksum_offset(xd3_stream *stream, usize_t low); | 505 | static xoff_t xd3_source_cksum_offset(xd3_stream *stream, usize_t low); |
509 | static void xd3_scksum_insert (xd3_stream *stream, | 506 | static void xd3_scksum_insert (xd3_stream *stream, |
510 | usize_t inx, | 507 | usize_t inx, |
@@ -519,7 +516,7 @@ static void xd3_verify_run_state (xd3_stream *stream, | |||
519 | uint8_t *x_run_c); | 516 | uint8_t *x_run_c); |
520 | static void xd3_verify_large_state (xd3_stream *stream, | 517 | static void xd3_verify_large_state (xd3_stream *stream, |
521 | const uint8_t *inp, | 518 | const uint8_t *inp, |
522 | uint32_t x_cksum); | 519 | usize_t x_cksum); |
523 | static void xd3_verify_small_state (xd3_stream *stream, | 520 | static void xd3_verify_small_state (xd3_stream *stream, |
524 | const uint8_t *inp, | 521 | const uint8_t *inp, |
525 | uint32_t x_cksum); | 522 | uint32_t x_cksum); |
@@ -533,15 +530,6 @@ static int xd3_decode_allocate (xd3_stream *stream, usize_t size, | |||
533 | static void* xd3_alloc (xd3_stream *stream, usize_t elts, usize_t size); | 530 | static void* xd3_alloc (xd3_stream *stream, usize_t elts, usize_t size); |
534 | static void xd3_free (xd3_stream *stream, void *ptr); | 531 | static void xd3_free (xd3_stream *stream, void *ptr); |
535 | 532 | ||
536 | static int xd3_read_uint32_t (xd3_stream *stream, const uint8_t **inpp, | ||
537 | const uint8_t *max, uint32_t *valp); | ||
538 | |||
539 | #if REGRESSION_TEST | ||
540 | static int xd3_selftest (void); | ||
541 | #endif | ||
542 | |||
543 | /***********************************************************************/ | ||
544 | |||
545 | const char* xd3_strerror (int ret) | 533 | const char* xd3_strerror (int ret) |
546 | { | 534 | { |
547 | switch (ret) | 535 | switch (ret) |
@@ -570,7 +558,7 @@ const char* xd3_strerror (int ret) | |||
570 | 558 | ||
571 | struct _xd3_sec_type | 559 | struct _xd3_sec_type |
572 | { | 560 | { |
573 | int id; | 561 | uint8_t id; |
574 | const char *name; | 562 | const char *name; |
575 | xd3_secondary_flags flags; | 563 | xd3_secondary_flags flags; |
576 | 564 | ||
@@ -602,7 +590,7 @@ struct _xd3_sec_type | |||
602 | typedef struct _bit_state bit_state; | 590 | typedef struct _bit_state bit_state; |
603 | struct _bit_state | 591 | struct _bit_state |
604 | { | 592 | { |
605 | usize_t cur_byte; | 593 | uint8_t cur_byte; |
606 | usize_t cur_mask; | 594 | usize_t cur_mask; |
607 | }; | 595 | }; |
608 | 596 | ||
@@ -747,44 +735,6 @@ const xd3_sec_type lzma_sec_type = | |||
747 | #endif /* __XDELTA3_C_HEADER_PASS__ */ | 735 | #endif /* __XDELTA3_C_HEADER_PASS__ */ |
748 | #ifdef __XDELTA3_C_INLINE_PASS__ | 736 | #ifdef __XDELTA3_C_INLINE_PASS__ |
749 | 737 | ||
750 | const uint16_t __single_hash[256] = | ||
751 | { | ||
752 | /* Random numbers generated using SLIB's pseudo-random number generator. | ||
753 | * This hashes the input alphabet. */ | ||
754 | 0xbcd1, 0xbb65, 0x42c2, 0xdffe, 0x9666, 0x431b, 0x8504, 0xeb46, | ||
755 | 0x6379, 0xd460, 0xcf14, 0x53cf, 0xdb51, 0xdb08, 0x12c8, 0xf602, | ||
756 | 0xe766, 0x2394, 0x250d, 0xdcbb, 0xa678, 0x02af, 0xa5c6, 0x7ea6, | ||
757 | 0xb645, 0xcb4d, 0xc44b, 0xe5dc, 0x9fe6, 0x5b5c, 0x35f5, 0x701a, | ||
758 | 0x220f, 0x6c38, 0x1a56, 0x4ca3, 0xffc6, 0xb152, 0x8d61, 0x7a58, | ||
759 | 0x9025, 0x8b3d, 0xbf0f, 0x95a3, 0xe5f4, 0xc127, 0x3bed, 0x320b, | ||
760 | 0xb7f3, 0x6054, 0x333c, 0xd383, 0x8154, 0x5242, 0x4e0d, 0x0a94, | ||
761 | 0x7028, 0x8689, 0x3a22, 0x0980, 0x1847, 0xb0f1, 0x9b5c, 0x4176, | ||
762 | 0xb858, 0xd542, 0x1f6c, 0x2497, 0x6a5a, 0x9fa9, 0x8c5a, 0x7743, | ||
763 | 0xa8a9, 0x9a02, 0x4918, 0x438c, 0xc388, 0x9e2b, 0x4cad, 0x01b6, | ||
764 | 0xab19, 0xf777, 0x365f, 0x1eb2, 0x091e, 0x7bf8, 0x7a8e, 0x5227, | ||
765 | 0xeab1, 0x2074, 0x4523, 0xe781, 0x01a3, 0x163d, 0x3b2e, 0x287d, | ||
766 | 0x5e7f, 0xa063, 0xb134, 0x8fae, 0x5e8e, 0xb7b7, 0x4548, 0x1f5a, | ||
767 | 0xfa56, 0x7a24, 0x900f, 0x42dc, 0xcc69, 0x02a0, 0x0b22, 0xdb31, | ||
768 | 0x71fe, 0x0c7d, 0x1732, 0x1159, 0xcb09, 0xe1d2, 0x1351, 0x52e9, | ||
769 | 0xf536, 0x5a4f, 0xc316, 0x6bf9, 0x8994, 0xb774, 0x5f3e, 0xf6d6, | ||
770 | 0x3a61, 0xf82c, 0xcc22, 0x9d06, 0x299c, 0x09e5, 0x1eec, 0x514f, | ||
771 | 0x8d53, 0xa650, 0x5c6e, 0xc577, 0x7958, 0x71ac, 0x8916, 0x9b4f, | ||
772 | 0x2c09, 0x5211, 0xf6d8, 0xcaaa, 0xf7ef, 0x287f, 0x7a94, 0xab49, | ||
773 | 0xfa2c, 0x7222, 0xe457, 0xd71a, 0x00c3, 0x1a76, 0xe98c, 0xc037, | ||
774 | 0x8208, 0x5c2d, 0xdfda, 0xe5f5, 0x0b45, 0x15ce, 0x8a7e, 0xfcad, | ||
775 | 0xaa2d, 0x4b5c, 0xd42e, 0xb251, 0x907e, 0x9a47, 0xc9a6, 0xd93f, | ||
776 | 0x085e, 0x35ce, 0xa153, 0x7e7b, 0x9f0b, 0x25aa, 0x5d9f, 0xc04d, | ||
777 | 0x8a0e, 0x2875, 0x4a1c, 0x295f, 0x1393, 0xf760, 0x9178, 0x0f5b, | ||
778 | 0xfa7d, 0x83b4, 0x2082, 0x721d, 0x6462, 0x0368, 0x67e2, 0x8624, | ||
779 | 0x194d, 0x22f6, 0x78fb, 0x6791, 0xb238, 0xb332, 0x7276, 0xf272, | ||
780 | 0x47ec, 0x4504, 0xa961, 0x9fc8, 0x3fdc, 0xb413, 0x007a, 0x0806, | ||
781 | 0x7458, 0x95c6, 0xccaa, 0x18d6, 0xe2ae, 0x1b06, 0xf3f6, 0x5050, | ||
782 | 0xc8e8, 0xf4ac, 0xc04c, 0xf41c, 0x992f, 0xae44, 0x5f1b, 0x1113, | ||
783 | 0x1738, 0xd9a8, 0x19ea, 0x2d33, 0x9698, 0x2fe9, 0x323f, 0xcde2, | ||
784 | 0x6d71, 0xe37d, 0xb697, 0x2c4f, 0x4373, 0x9102, 0x075d, 0x8e25, | ||
785 | 0x1672, 0xec28, 0x6acb, 0x86cc, 0x186e, 0x9414, 0xd674, 0xd1a5 | ||
786 | }; | ||
787 | |||
788 | /**************************************************************** | 738 | /**************************************************************** |
789 | Instruction tables | 739 | Instruction tables |
790 | *****************************************************************/ | 740 | *****************************************************************/ |
@@ -841,24 +791,32 @@ struct _xd3_code_table_desc | |||
841 | /* Assumes a single RUN instruction */ | 791 | /* Assumes a single RUN instruction */ |
842 | /* Assumes that MIN_MATCH is 4 */ | 792 | /* Assumes that MIN_MATCH is 4 */ |
843 | 793 | ||
844 | uint8_t add_sizes; /* Number of immediate-size single adds (default 17) */ | 794 | uint8_t add_sizes; /* Number of immediate-size single |
795 | adds (default 17) */ | ||
845 | uint8_t near_modes; /* Number of near copy modes (default 4) */ | 796 | uint8_t near_modes; /* Number of near copy modes (default 4) */ |
846 | uint8_t same_modes; /* Number of same copy modes (default 3) */ | 797 | uint8_t same_modes; /* Number of same copy modes (default 3) */ |
847 | uint8_t cpy_sizes; /* Number of immediate-size single copies (default 15) */ | 798 | uint8_t cpy_sizes; /* Number of immediate-size single |
848 | 799 | copies (default 15) */ | |
849 | uint8_t addcopy_add_max; /* Maximum add size for an add-copy double instruction, | 800 | |
850 | all modes (default 4) */ | 801 | uint8_t addcopy_add_max; /* Maximum add size for an add-copy |
851 | uint8_t addcopy_near_cpy_max; /* Maximum cpy size for an add-copy double instruction, | 802 | double instruction, all modes |
852 | up through VCD_NEAR modes (default 6) */ | 803 | (default 4) */ |
853 | uint8_t addcopy_same_cpy_max; /* Maximum cpy size for an add-copy double instruction, | 804 | uint8_t addcopy_near_cpy_max; /* Maximum cpy size for an add-copy |
854 | VCD_SAME modes (default 4) */ | 805 | double instruction, up through |
855 | 806 | VCD_NEAR modes (default 6) */ | |
856 | uint8_t copyadd_add_max; /* Maximum add size for a copy-add double instruction, | 807 | uint8_t addcopy_same_cpy_max; /* Maximum cpy size for an add-copy |
857 | all modes (default 1) */ | 808 | double instruction, VCD_SAME modes |
858 | uint8_t copyadd_near_cpy_max; /* Maximum cpy size for a copy-add double instruction, | 809 | (default 4) */ |
859 | up through VCD_NEAR modes (default 4) */ | 810 | |
860 | uint8_t copyadd_same_cpy_max; /* Maximum cpy size for a copy-add double instruction, | 811 | uint8_t copyadd_add_max; /* Maximum add size for a copy-add |
861 | VCD_SAME modes (default 4) */ | 812 | double instruction, all modes |
813 | (default 1) */ | ||
814 | uint8_t copyadd_near_cpy_max; /* Maximum cpy size for a copy-add | ||
815 | double instruction, up through | ||
816 | VCD_NEAR modes (default 4) */ | ||
817 | uint8_t copyadd_same_cpy_max; /* Maximum cpy size for a copy-add | ||
818 | double instruction, VCD_SAME modes | ||
819 | (default 4) */ | ||
862 | 820 | ||
863 | xd3_code_table_sizes addcopy_max_sizes[MAX_MODES]; | 821 | xd3_code_table_sizes addcopy_max_sizes[MAX_MODES]; |
864 | xd3_code_table_sizes copyadd_max_sizes[MAX_MODES]; | 822 | xd3_code_table_sizes copyadd_max_sizes[MAX_MODES]; |
@@ -880,17 +838,20 @@ static const xd3_code_table_desc __rfc3284_code_table_desc = { | |||
880 | 4, /* copy-add max cpy, same */ | 838 | 4, /* copy-add max cpy, same */ |
881 | 839 | ||
882 | /* addcopy */ | 840 | /* addcopy */ |
883 | { {6,163,3},{6,175,3},{6,187,3},{6,199,3},{6,211,3},{6,223,3},{4,235,1},{4,239,1},{4,243,1} }, | 841 | { {6,163,3},{6,175,3},{6,187,3},{6,199,3},{6,211,3},{6,223,3}, |
842 | {4,235,1},{4,239,1},{4,243,1} }, | ||
884 | /* copyadd */ | 843 | /* copyadd */ |
885 | { {4,247,1},{4,248,1},{4,249,1},{4,250,1},{4,251,1},{4,252,1},{4,253,1},{4,254,1},{4,255,1} }, | 844 | { {4,247,1},{4,248,1},{4,249,1},{4,250,1},{4,251,1},{4,252,1}, |
845 | {4,253,1},{4,254,1},{4,255,1} }, | ||
886 | }; | 846 | }; |
887 | 847 | ||
888 | /* Computes code table entries of TBL using the specified description. */ | 848 | /* Computes code table entries of TBL using the specified description. */ |
889 | static void | 849 | static void |
890 | xd3_build_code_table (const xd3_code_table_desc *desc, xd3_dinst *tbl) | 850 | xd3_build_code_table (const xd3_code_table_desc *desc, xd3_dinst *tbl) |
891 | { | 851 | { |
892 | usize_t size1, size2, mode; | 852 | uint8_t size1, size2; |
893 | usize_t cpy_modes = 2 + desc->near_modes + desc->same_modes; | 853 | uint8_t mode; |
854 | usize_t cpy_modes = 2U + desc->near_modes + desc->same_modes; | ||
894 | xd3_dinst *d = tbl; | 855 | xd3_dinst *d = tbl; |
895 | 856 | ||
896 | (d++)->type1 = XD3_RUN; | 857 | (d++)->type1 = XD3_RUN; |
@@ -906,7 +867,8 @@ xd3_build_code_table (const xd3_code_table_desc *desc, xd3_dinst *tbl) | |||
906 | { | 867 | { |
907 | (d++)->type1 = XD3_CPY + mode; | 868 | (d++)->type1 = XD3_CPY + mode; |
908 | 869 | ||
909 | for (size1 = MIN_MATCH; size1 < MIN_MATCH + desc->cpy_sizes; size1 += 1, d += 1) | 870 | for (size1 = MIN_MATCH; size1 < MIN_MATCH + desc->cpy_sizes; |
871 | size1 += 1, d += 1) | ||
910 | { | 872 | { |
911 | d->type1 = XD3_CPY + mode; | 873 | d->type1 = XD3_CPY + mode; |
912 | d->size1 = size1; | 874 | d->size1 = size1; |
@@ -998,7 +960,7 @@ xd3_choose_instruction (xd3_rinst *prev, xd3_rinst *inst) | |||
998 | 960 | ||
999 | default: | 961 | default: |
1000 | { | 962 | { |
1001 | int mode = inst->type - XD3_CPY; | 963 | uint8_t mode = inst->type - XD3_CPY; |
1002 | 964 | ||
1003 | XD3_ASSERT (inst->type >= XD3_CPY && inst->type < 12); | 965 | XD3_ASSERT (inst->type >= XD3_CPY && inst->type < 12); |
1004 | 966 | ||
@@ -1015,8 +977,9 @@ xd3_choose_instruction (xd3_rinst *prev, xd3_rinst *inst) | |||
1015 | if ( (inst->size <= 6) && | 977 | if ( (inst->size <= 6) && |
1016 | (mode <= 5) ) | 978 | (mode <= 5) ) |
1017 | { | 979 | { |
1018 | prev->code2 = 163 + (mode * 12) + (3 * (prev->size - 1)) + (inst->size - 4); | 980 | prev->code2 = (uint8_t)(163 + (mode * 12) + |
1019 | 981 | (3 * (prev->size - 1)) + | |
982 | (inst->size - 4)); | ||
1020 | XD3_ASSERT (prev->code2 <= 234); | 983 | XD3_ASSERT (prev->code2 <= 234); |
1021 | } | 984 | } |
1022 | else if ( (inst->size == 4) && | 985 | else if ( (inst->size == 4) && |
@@ -1077,10 +1040,10 @@ xd3_check_pow2 (xoff_t value, usize_t *logof) | |||
1077 | return XD3_INTERNAL; | 1040 | return XD3_INTERNAL; |
1078 | } | 1041 | } |
1079 | 1042 | ||
1080 | size_t | 1043 | usize_t |
1081 | xd3_pow2_roundup (size_t x) | 1044 | xd3_pow2_roundup (usize_t x) |
1082 | { | 1045 | { |
1083 | size_t i = 1; | 1046 | usize_t i = 1; |
1084 | while (x > i) { | 1047 | while (x > i) { |
1085 | i <<= 1U; | 1048 | i <<= 1U; |
1086 | } | 1049 | } |
@@ -1112,7 +1075,8 @@ xd3_round_blksize (usize_t sz, usize_t blksz) | |||
1112 | ***********************************************************************/ | 1075 | ***********************************************************************/ |
1113 | 1076 | ||
1114 | #define A32_BASE 65521L /* Largest prime smaller than 2^16 */ | 1077 | #define A32_BASE 65521L /* Largest prime smaller than 2^16 */ |
1115 | #define A32_NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ | 1078 | #define A32_NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 |
1079 | + (n+1)(BASE-1) <= 2^32-1 */ | ||
1116 | 1080 | ||
1117 | #define A32_DO1(buf,i) {s1 += buf[i]; s2 += s1;} | 1081 | #define A32_DO1(buf,i) {s1 += buf[i]; s2 += s1;} |
1118 | #define A32_DO2(buf,i) A32_DO1(buf,i); A32_DO1(buf,i+1); | 1082 | #define A32_DO2(buf,i) A32_DO1(buf,i); A32_DO1(buf,i+1); |
@@ -1120,11 +1084,10 @@ xd3_round_blksize (usize_t sz, usize_t blksz) | |||
1120 | #define A32_DO8(buf,i) A32_DO4(buf,i); A32_DO4(buf,i+4); | 1084 | #define A32_DO8(buf,i) A32_DO4(buf,i); A32_DO4(buf,i+4); |
1121 | #define A32_DO16(buf) A32_DO8(buf,0); A32_DO8(buf,8); | 1085 | #define A32_DO16(buf) A32_DO8(buf,0); A32_DO8(buf,8); |
1122 | 1086 | ||
1123 | static unsigned long adler32 (unsigned long adler, const uint8_t *buf, | 1087 | static uint32_t adler32 (uint32_t adler, const uint8_t *buf, usize_t len) |
1124 | usize_t len) | ||
1125 | { | 1088 | { |
1126 | unsigned long s1 = adler & 0xffff; | 1089 | uint32_t s1 = adler & 0xffffU; |
1127 | unsigned long s2 = (adler >> 16) & 0xffff; | 1090 | uint32_t s2 = (adler >> 16) & 0xffffU; |
1128 | int k; | 1091 | int k; |
1129 | 1092 | ||
1130 | while (len > 0) | 1093 | while (len > 0) |
@@ -1319,7 +1282,8 @@ xd3_encode_address (xd3_stream *stream, | |||
1319 | uint8_t* mode) | 1282 | uint8_t* mode) |
1320 | { | 1283 | { |
1321 | usize_t d, bestd; | 1284 | usize_t d, bestd; |
1322 | usize_t i, bestm, ret; | 1285 | usize_t i, bestm; |
1286 | int ret; | ||
1323 | xd3_addr_cache* acache = & stream->acache; | 1287 | xd3_addr_cache* acache = & stream->acache; |
1324 | 1288 | ||
1325 | #define SMALLEST_INT(x) do { if (((x) & ~127U) == 0) { goto good; } } while (0) | 1289 | #define SMALLEST_INT(x) do { if (((x) & ~127U) == 0) { goto good; } } while (0) |
@@ -1393,7 +1357,7 @@ xd3_encode_address (xd3_stream *stream, | |||
1393 | static int | 1357 | static int |
1394 | xd3_decode_address (xd3_stream *stream, usize_t here, | 1358 | xd3_decode_address (xd3_stream *stream, usize_t here, |
1395 | usize_t mode, const uint8_t **inpp, | 1359 | usize_t mode, const uint8_t **inpp, |
1396 | const uint8_t *max, uint32_t *valp) | 1360 | const uint8_t *max, usize_t *valp) |
1397 | { | 1361 | { |
1398 | int ret; | 1362 | int ret; |
1399 | usize_t same_start = 2 + stream->acache.s_near; | 1363 | usize_t same_start = 2 + stream->acache.s_near; |
@@ -1610,11 +1574,13 @@ xd3_free_stream (xd3_stream *stream) | |||
1610 | xd3_free (stream, tmp); | 1574 | xd3_free (stream, tmp); |
1611 | } | 1575 | } |
1612 | 1576 | ||
1577 | #if XD3_ENCODER | ||
1613 | xd3_free (stream, stream->large_table); | 1578 | xd3_free (stream, stream->large_table); |
1614 | xd3_free (stream, stream->small_table); | 1579 | xd3_free (stream, stream->small_table); |
1580 | xd3_free (stream, stream->large_hash.powers); | ||
1581 | xd3_free (stream, stream->small_hash.powers); | ||
1615 | xd3_free (stream, stream->small_prev); | 1582 | xd3_free (stream, stream->small_prev); |
1616 | 1583 | ||
1617 | #if XD3_ENCODER | ||
1618 | { | 1584 | { |
1619 | int i; | 1585 | int i; |
1620 | for (i = 0; i < ENC_SECTS; i += 1) | 1586 | for (i = 0; i < ENC_SECTS; i += 1) |
@@ -1882,7 +1848,7 @@ xd3_config_stream(xd3_stream *stream, | |||
1882 | inline | 1848 | inline |
1883 | xoff_t xd3_source_eof(const xd3_source *src) | 1849 | xoff_t xd3_source_eof(const xd3_source *src) |
1884 | { | 1850 | { |
1885 | xoff_t r = (src->blksize * src->max_blkno) + (xoff_t)src->onlastblk; | 1851 | xoff_t r = (src->blksize * src->max_blkno) + src->onlastblk; |
1886 | return r; | 1852 | return r; |
1887 | } | 1853 | } |
1888 | 1854 | ||
@@ -1916,11 +1882,11 @@ xd3_getblk (xd3_stream *stream, xoff_t blkno) | |||
1916 | ret = stream->getblk (stream, source, blkno); | 1882 | ret = stream->getblk (stream, source, blkno); |
1917 | if (ret != 0) | 1883 | if (ret != 0) |
1918 | { | 1884 | { |
1919 | IF_DEBUG1 (DP(RINT "[getblk] app error blkno %"Q"u: %s\n", | 1885 | IF_DEBUG1 (DP(RINT "[getblk] app error blkno %"Q": %s\n", |
1920 | blkno, xd3_strerror (ret))); | 1886 | blkno, xd3_strerror (ret))); |
1921 | return ret; | 1887 | return ret; |
1922 | } | 1888 | } |
1923 | IF_DEBUG2 (DP(RINT "[getblk] read source block %"Q"u onblk " | 1889 | IF_DEBUG2 (DP(RINT "[getblk] read source block %"Q" onblk " |
1924 | "%u blksize %u\n", blkno, source->onblk, source->blksize)); | 1890 | "%u blksize %u\n", blkno, source->onblk, source->blksize)); |
1925 | } | 1891 | } |
1926 | 1892 | ||
@@ -1936,8 +1902,8 @@ xd3_getblk (xd3_stream *stream, xoff_t blkno) | |||
1936 | { | 1902 | { |
1937 | source->frontier_blkno = blkno + 1; | 1903 | source->frontier_blkno = blkno + 1; |
1938 | 1904 | ||
1939 | IF_DEBUG2 (DP(RINT "[getblk] full source blkno %"Q"u: " | 1905 | IF_DEBUG2 (DP(RINT "[getblk] full source blkno %"Q": " |
1940 | "source length unknown %"Q"u\n", | 1906 | "source length unknown %"Q"\n", |
1941 | blkno, | 1907 | blkno, |
1942 | xd3_source_eof (source))); | 1908 | xd3_source_eof (source))); |
1943 | } | 1909 | } |
@@ -1953,7 +1919,7 @@ xd3_getblk (xd3_stream *stream, xoff_t blkno) | |||
1953 | if (!source->eof_known) | 1919 | if (!source->eof_known) |
1954 | { | 1920 | { |
1955 | IF_DEBUG2 (DP(RINT "[getblk] eof block has %d bytes; " | 1921 | IF_DEBUG2 (DP(RINT "[getblk] eof block has %d bytes; " |
1956 | "source length known %"Q"u\n", | 1922 | "source length known %"Q"\n", |
1957 | xd3_bytes_on_srcblk (source, blkno), | 1923 | xd3_bytes_on_srcblk (source, blkno), |
1958 | xd3_source_eof (source))); | 1924 | xd3_source_eof (source))); |
1959 | source->eof_known = 1; | 1925 | source->eof_known = 1; |
@@ -2001,7 +1967,7 @@ xd3_set_source (xd3_stream *stream, | |||
2001 | } | 1967 | } |
2002 | 1968 | ||
2003 | src->shiftby = shiftby; | 1969 | src->shiftby = shiftby; |
2004 | src->maskby = (1 << shiftby) - 1; | 1970 | src->maskby = (1ULL << shiftby) - 1ULL; |
2005 | 1971 | ||
2006 | if (xd3_check_pow2 (src->max_winsize, NULL) != 0) | 1972 | if (xd3_check_pow2 (src->max_winsize, NULL) != 0) |
2007 | { | 1973 | { |
@@ -2021,7 +1987,7 @@ xd3_set_source_and_size (xd3_stream *stream, | |||
2021 | if (ret == 0) | 1987 | if (ret == 0) |
2022 | { | 1988 | { |
2023 | stream->src->eof_known = 1; | 1989 | stream->src->eof_known = 1; |
2024 | IF_DEBUG2 (DP(RINT "[set source] size known %"Q"u\n", | 1990 | IF_DEBUG2 (DP(RINT "[set source] size known %"Q"\n", |
2025 | source_size)); | 1991 | source_size)); |
2026 | 1992 | ||
2027 | xd3_blksize_div(source_size, | 1993 | xd3_blksize_div(source_size, |
@@ -2200,22 +2166,22 @@ xd3_iopt_finish_encoding (xd3_stream *stream, xd3_rinst *inst) | |||
2200 | XD3_ASSERT (inst->addr >= src->srcbase); | 2166 | XD3_ASSERT (inst->addr >= src->srcbase); |
2201 | XD3_ASSERT (inst->addr + inst->size <= | 2167 | XD3_ASSERT (inst->addr + inst->size <= |
2202 | src->srcbase + src->srclen); | 2168 | src->srcbase + src->srclen); |
2203 | addr = (usize_t)(inst->addr - src->srcbase); | 2169 | addr = inst->addr - src->srcbase; |
2204 | stream->n_scpy += 1; | 2170 | stream->n_scpy += 1; |
2205 | stream->l_scpy += (xoff_t) inst->size; | 2171 | stream->l_scpy += inst->size; |
2206 | } | 2172 | } |
2207 | else | 2173 | else |
2208 | { | 2174 | { |
2209 | /* with source window: target copy address is offset | 2175 | /* with source window: target copy address is offset |
2210 | * by taroff. */ | 2176 | * by taroff. */ |
2211 | addr = stream->taroff + (usize_t) inst->addr; | 2177 | addr = stream->taroff + inst->addr; |
2212 | stream->n_tcpy += 1; | 2178 | stream->n_tcpy += 1; |
2213 | stream->l_tcpy += (xoff_t) inst->size; | 2179 | stream->l_tcpy += inst->size; |
2214 | } | 2180 | } |
2215 | } | 2181 | } |
2216 | else | 2182 | else |
2217 | { | 2183 | { |
2218 | addr = (usize_t) inst->addr; | 2184 | addr = inst->addr; |
2219 | stream->n_tcpy += 1; | 2185 | stream->n_tcpy += 1; |
2220 | stream->l_tcpy += inst->size; | 2186 | stream->l_tcpy += inst->size; |
2221 | } | 2187 | } |
@@ -2231,7 +2197,7 @@ xd3_iopt_finish_encoding (xd3_stream *stream, xd3_rinst *inst) | |||
2231 | 2197 | ||
2232 | IF_DEBUG2 ({ | 2198 | IF_DEBUG2 ({ |
2233 | static int cnt; | 2199 | static int cnt; |
2234 | DP(RINT "[iopt copy:%d] pos %"Q"u-%"Q"u addr %"Q"u-%"Q"u size %u\n", | 2200 | DP(RINT "[iopt copy:%d] pos %"Q"-%"Q" addr %"Q"-%"Q" size %u\n", |
2235 | cnt++, | 2201 | cnt++, |
2236 | stream->total_in + inst->pos, | 2202 | stream->total_in + inst->pos, |
2237 | stream->total_in + inst->pos + inst->size, | 2203 | stream->total_in + inst->pos + inst->size, |
@@ -2250,7 +2216,7 @@ xd3_iopt_finish_encoding (xd3_stream *stream, xd3_rinst *inst) | |||
2250 | 2216 | ||
2251 | IF_DEBUG2 ({ | 2217 | IF_DEBUG2 ({ |
2252 | static int cnt; | 2218 | static int cnt; |
2253 | DP(RINT "[iopt run:%d] pos %"Q"u size %u\n", cnt++, stream->total_in + inst->pos, inst->size); | 2219 | DP(RINT "[iopt run:%d] pos %"Q" size %u\n", cnt++, stream->total_in + inst->pos, inst->size); |
2254 | }); | 2220 | }); |
2255 | break; | 2221 | break; |
2256 | } | 2222 | } |
@@ -2264,7 +2230,7 @@ xd3_iopt_finish_encoding (xd3_stream *stream, xd3_rinst *inst) | |||
2264 | 2230 | ||
2265 | IF_DEBUG2 ({ | 2231 | IF_DEBUG2 ({ |
2266 | static int cnt; | 2232 | static int cnt; |
2267 | DP(RINT "[iopt add:%d] pos %"Q"u size %u\n", cnt++, stream->total_in + inst->pos, inst->size); | 2233 | DP(RINT "[iopt add:%d] pos %"Q" size %u\n", cnt++, stream->total_in + inst->pos, inst->size); |
2268 | }); | 2234 | }); |
2269 | 2235 | ||
2270 | break; | 2236 | break; |
@@ -2283,7 +2249,8 @@ xd3_iopt_finish_encoding (xd3_stream *stream, xd3_rinst *inst) | |||
2283 | { | 2249 | { |
2284 | if (stream->iout->code2 != 0) | 2250 | if (stream->iout->code2 != 0) |
2285 | { | 2251 | { |
2286 | if ((ret = xd3_emit_double (stream, stream->iout, inst, stream->iout->code2))) { return ret; } | 2252 | if ((ret = xd3_emit_double (stream, stream->iout, inst, |
2253 | stream->iout->code2))) { return ret; } | ||
2287 | 2254 | ||
2288 | xd3_iopt_free_nonadd (stream, stream->iout); | 2255 | xd3_iopt_free_nonadd (stream, stream->iout); |
2289 | xd3_iopt_free_nonadd (stream, inst); | 2256 | xd3_iopt_free_nonadd (stream, inst); |
@@ -2640,7 +2607,7 @@ xd3_iopt_last_matched (xd3_stream *stream) | |||
2640 | ***********************************************************/ | 2607 | ***********************************************************/ |
2641 | 2608 | ||
2642 | static int | 2609 | static int |
2643 | xd3_emit_single (xd3_stream *stream, xd3_rinst *single, usize_t code) | 2610 | xd3_emit_single (xd3_stream *stream, xd3_rinst *single, uint8_t code) |
2644 | { | 2611 | { |
2645 | int has_size = stream->code_table[code].size1 == 0; | 2612 | int has_size = stream->code_table[code].size1 == 0; |
2646 | int ret; | 2613 | int ret; |
@@ -2669,7 +2636,7 @@ xd3_emit_single (xd3_stream *stream, xd3_rinst *single, usize_t code) | |||
2669 | 2636 | ||
2670 | static int | 2637 | static int |
2671 | xd3_emit_double (xd3_stream *stream, xd3_rinst *first, | 2638 | xd3_emit_double (xd3_stream *stream, xd3_rinst *first, |
2672 | xd3_rinst *second, usize_t code) | 2639 | xd3_rinst *second, uint8_t code) |
2673 | { | 2640 | { |
2674 | int ret; | 2641 | int ret; |
2675 | 2642 | ||
@@ -2739,8 +2706,8 @@ xd3_emit_hdr (xd3_stream *stream) | |||
2739 | int use_secondary = stream->sec_type != NULL; | 2706 | int use_secondary = stream->sec_type != NULL; |
2740 | int use_adler32 = stream->flags & (XD3_ADLER32 | XD3_ADLER32_RECODE); | 2707 | int use_adler32 = stream->flags & (XD3_ADLER32 | XD3_ADLER32_RECODE); |
2741 | int vcd_source = xd3_encoder_used_source (stream); | 2708 | int vcd_source = xd3_encoder_used_source (stream); |
2742 | usize_t win_ind = 0; | 2709 | uint8_t win_ind = 0; |
2743 | usize_t del_ind = 0; | 2710 | uint8_t del_ind = 0; |
2744 | usize_t enc_len; | 2711 | usize_t enc_len; |
2745 | usize_t tgt_len; | 2712 | usize_t tgt_len; |
2746 | usize_t data_len; | 2713 | usize_t data_len; |
@@ -2749,7 +2716,7 @@ xd3_emit_hdr (xd3_stream *stream) | |||
2749 | 2716 | ||
2750 | if (stream->current_window == 0) | 2717 | if (stream->current_window == 0) |
2751 | { | 2718 | { |
2752 | usize_t hdr_ind = 0; | 2719 | uint8_t hdr_ind = 0; |
2753 | int use_appheader = stream->enc_appheader != NULL; | 2720 | int use_appheader = stream->enc_appheader != NULL; |
2754 | 2721 | ||
2755 | if (use_secondary) { hdr_ind |= VCD_SECONDARY; } | 2722 | if (use_secondary) { hdr_ind |= VCD_SECONDARY; } |
@@ -2847,7 +2814,7 @@ xd3_emit_hdr (xd3_stream *stream) | |||
2847 | inst_len = xd3_sizeof_output (INST_HEAD (stream)); | 2814 | inst_len = xd3_sizeof_output (INST_HEAD (stream)); |
2848 | addr_len = xd3_sizeof_output (ADDR_HEAD (stream)); | 2815 | addr_len = xd3_sizeof_output (ADDR_HEAD (stream)); |
2849 | 2816 | ||
2850 | /* The enc_len field is a redundency for future extensions.*/ | 2817 | /* The enc_len field is a redundency for future extensions. */ |
2851 | enc_len = (1 + (xd3_sizeof_size (tgt_len) + | 2818 | enc_len = (1 + (xd3_sizeof_size (tgt_len) + |
2852 | xd3_sizeof_size (data_len) + | 2819 | xd3_sizeof_size (data_len) + |
2853 | xd3_sizeof_size (inst_len) + | 2820 | xd3_sizeof_size (inst_len) + |
@@ -2988,6 +2955,7 @@ xd3_alloc_iopt (xd3_stream *stream, usize_t elts) | |||
2988 | static int | 2955 | static int |
2989 | xd3_encode_init (xd3_stream *stream, int full_init) | 2956 | xd3_encode_init (xd3_stream *stream, int full_init) |
2990 | { | 2957 | { |
2958 | int ret; | ||
2991 | int i; | 2959 | int i; |
2992 | 2960 | ||
2993 | if (full_init) | 2961 | if (full_init) |
@@ -3000,12 +2968,17 @@ xd3_encode_init (xd3_stream *stream, int full_init) | |||
3000 | * identical or short inputs require no table allocation. */ | 2968 | * identical or short inputs require no table allocation. */ |
3001 | if (large_comp) | 2969 | if (large_comp) |
3002 | { | 2970 | { |
2971 | /* TODO Need to check for overflow here. */ | ||
3003 | usize_t hash_values = stream->src->max_winsize / | 2972 | usize_t hash_values = stream->src->max_winsize / |
3004 | stream->smatcher.large_step; | 2973 | stream->smatcher.large_step; |
3005 | 2974 | ||
3006 | xd3_size_hashtable (stream, | 2975 | if ((ret = xd3_size_hashtable (stream, |
3007 | hash_values, | 2976 | hash_values, |
3008 | & stream->large_hash); | 2977 | stream->smatcher.large_look, |
2978 | & stream->large_hash))) | ||
2979 | { | ||
2980 | return ret; | ||
2981 | } | ||
3009 | } | 2982 | } |
3010 | 2983 | ||
3011 | if (small_comp) | 2984 | if (small_comp) |
@@ -3015,9 +2988,13 @@ xd3_encode_init (xd3_stream *stream, int full_init) | |||
3015 | * also sort of makes sense. @@@ */ | 2988 | * also sort of makes sense. @@@ */ |
3016 | usize_t hash_values = stream->winsize; | 2989 | usize_t hash_values = stream->winsize; |
3017 | 2990 | ||
3018 | xd3_size_hashtable (stream, | 2991 | if ((ret = xd3_size_hashtable (stream, |
3019 | hash_values, | 2992 | hash_values, |
3020 | & stream->small_hash); | 2993 | stream->smatcher.small_look, |
2994 | & stream->small_hash))) | ||
2995 | { | ||
2996 | return ret; | ||
2997 | } | ||
3021 | } | 2998 | } |
3022 | } | 2999 | } |
3023 | 3000 | ||
@@ -3166,7 +3143,7 @@ xd3_encode_input (xd3_stream *stream) | |||
3166 | 3143 | ||
3167 | stream->enc_state = ENC_SEARCH; | 3144 | stream->enc_state = ENC_SEARCH; |
3168 | 3145 | ||
3169 | IF_DEBUG2 (DP(RINT "[WINSTART:%"Q"u] input bytes %u offset %"Q"u\n", | 3146 | IF_DEBUG2 (DP(RINT "[WINSTART:%"Q"] input bytes %u offset %"Q"\n", |
3170 | stream->current_window, stream->avail_in, | 3147 | stream->current_window, stream->avail_in, |
3171 | stream->total_in)); | 3148 | stream->total_in)); |
3172 | return XD3_WINSTART; | 3149 | return XD3_WINSTART; |
@@ -3279,7 +3256,7 @@ xd3_encode_input (xd3_stream *stream) | |||
3279 | stream->enc_state = ENC_POSTOUT; | 3256 | stream->enc_state = ENC_POSTOUT; |
3280 | stream->next_out = stream->enc_current->base; | 3257 | stream->next_out = stream->enc_current->base; |
3281 | stream->avail_out = stream->enc_current->next; | 3258 | stream->avail_out = stream->enc_current->next; |
3282 | stream->total_out += (xoff_t) stream->avail_out; | 3259 | stream->total_out += stream->avail_out; |
3283 | 3260 | ||
3284 | /* If there is any output in this buffer, return it, otherwise | 3261 | /* If there is any output in this buffer, return it, otherwise |
3285 | * fall through to handle the next buffer or finish the window | 3262 | * fall through to handle the next buffer or finish the window |
@@ -3304,10 +3281,10 @@ xd3_encode_input (xd3_stream *stream) | |||
3304 | goto enc_output; | 3281 | goto enc_output; |
3305 | } | 3282 | } |
3306 | 3283 | ||
3307 | stream->total_in += (xoff_t) stream->avail_in; | 3284 | stream->total_in += stream->avail_in; |
3308 | stream->enc_state = ENC_POSTWIN; | 3285 | stream->enc_state = ENC_POSTWIN; |
3309 | 3286 | ||
3310 | IF_DEBUG2 (DP(RINT "[WINFINISH:%"Q"u] in=%"Q"u\n", | 3287 | IF_DEBUG2 (DP(RINT "[WINFINISH:%"Q"] in=%"Q"\n", |
3311 | stream->current_window, | 3288 | stream->current_window, |
3312 | stream->total_in)); | 3289 | stream->total_in)); |
3313 | return XD3_WINFINISH; | 3290 | return XD3_WINFINISH; |
@@ -3616,7 +3593,7 @@ xd3_string_match_init (xd3_stream *stream) | |||
3616 | return 0; | 3593 | return 0; |
3617 | } | 3594 | } |
3618 | 3595 | ||
3619 | #if XD3_USE_LARGEFILE64 | 3596 | #if XD3_USE_LARGEFILE64 && !XD3_USE_LARGESIZET |
3620 | /* This function handles the 32/64bit ambiguity -- file positions are 64bit | 3597 | /* This function handles the 32/64bit ambiguity -- file positions are 64bit |
3621 | * but the hash table for source-offsets is 32bit. */ | 3598 | * but the hash table for source-offsets is 32bit. */ |
3622 | static xoff_t | 3599 | static xoff_t |
@@ -3643,7 +3620,7 @@ xd3_source_cksum_offset(xd3_stream *stream, usize_t low) | |||
3643 | static xoff_t | 3620 | static xoff_t |
3644 | xd3_source_cksum_offset(xd3_stream *stream, usize_t low) | 3621 | xd3_source_cksum_offset(xd3_stream *stream, usize_t low) |
3645 | { | 3622 | { |
3646 | return (xoff_t) low; | 3623 | return low; |
3647 | } | 3624 | } |
3648 | #endif | 3625 | #endif |
3649 | 3626 | ||
@@ -3677,7 +3654,7 @@ xd3_srcwin_setup (xd3_stream *stream) | |||
3677 | * use smaller windows. */ | 3654 | * use smaller windows. */ |
3678 | length = stream->match_maxaddr - stream->match_minaddr; | 3655 | length = stream->match_maxaddr - stream->match_minaddr; |
3679 | 3656 | ||
3680 | x = (xoff_t) USIZE_T_MAX; | 3657 | x = USIZE_T_MAX; |
3681 | if (length > x) | 3658 | if (length > x) |
3682 | { | 3659 | { |
3683 | stream->msg = "source window length overflow (not 64bit)"; | 3660 | stream->msg = "source window length overflow (not 64bit)"; |
@@ -3696,20 +3673,20 @@ xd3_srcwin_setup (xd3_stream *stream) | |||
3696 | 3673 | ||
3697 | /* Otherwise, we have to make a guess. More copies may still be | 3674 | /* Otherwise, we have to make a guess. More copies may still be |
3698 | * issued, but we have to decide the source window base and length | 3675 | * issued, but we have to decide the source window base and length |
3699 | * now. */ | 3676 | * now. |
3677 | * TODO: This >> 2 is arbitrary--try other values. */ | ||
3700 | src->srcbase = stream->match_minaddr; | 3678 | src->srcbase = stream->match_minaddr; |
3701 | src->srclen = xd3_max ((usize_t) length, | 3679 | src->srclen = xd3_max ((usize_t) length, |
3702 | stream->avail_in + (stream->avail_in >> 2)); | 3680 | stream->avail_in + (stream->avail_in >> 2)); |
3703 | 3681 | ||
3704 | if (src->eof_known) | 3682 | if (src->eof_known) |
3705 | { | 3683 | { |
3706 | /* Note: if the source size is known, we must reduce srclen or | 3684 | /* Note: if the source size is known, we must reduce srclen or |
3707 | * code that expects to pass a single block w/ getblk == NULL | 3685 | * code that expects to pass a single block w/ getblk == NULL |
3708 | * will not function, as the code will return GETSRCBLK asking | 3686 | * will not function, as the code will return GETSRCBLK asking |
3709 | * for the second block. */ | 3687 | * for the second block. */ |
3710 | src->srclen = xd3_min (src->srclen, xd3_source_eof(src) - src->srcbase); | 3688 | src->srclen = xd3_min (src->srclen, xd3_source_eof(src) - src->srcbase); |
3711 | } | 3689 | } |
3712 | |||
3713 | IF_DEBUG1 (DP(RINT "[srcwin_setup_constrained] base %"Q"u len %u\n", | 3690 | IF_DEBUG1 (DP(RINT "[srcwin_setup_constrained] base %"Q"u len %u\n", |
3714 | src->srcbase, src->srclen)); | 3691 | src->srcbase, src->srclen)); |
3715 | 3692 | ||
@@ -3757,13 +3734,13 @@ xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos) | |||
3757 | * back further than the LRU cache maintaining FIFO discipline, (to | 3734 | * back further than the LRU cache maintaining FIFO discipline, (to |
3758 | * avoid seeking). */ | 3735 | * avoid seeking). */ |
3759 | frontier_pos = stream->src->frontier_blkno * stream->src->blksize; | 3736 | frontier_pos = stream->src->frontier_blkno * stream->src->blksize; |
3760 | IF_DEBUG2(DP(RINT "[match_setup] frontier_pos %"Q"u, srcpos %"Q"u, " | 3737 | IF_DEBUG2(DP(RINT "[match_setup] frontier_pos %"Q", srcpos %"Q", " |
3761 | "src->max_winsize %"Q"u\n", | 3738 | "src->max_winsize %"Q"\n", |
3762 | frontier_pos, srcpos, stream->src->max_winsize)); | 3739 | frontier_pos, srcpos, stream->src->max_winsize)); |
3763 | if (srcpos < frontier_pos && | 3740 | if (srcpos < frontier_pos && |
3764 | frontier_pos - srcpos > stream->src->max_winsize) { | 3741 | frontier_pos - srcpos > stream->src->max_winsize) { |
3765 | IF_DEBUG1(DP(RINT "[match_setup] rejected due to src->max_winsize " | 3742 | IF_DEBUG1(DP(RINT "[match_setup] rejected due to src->max_winsize " |
3766 | "distance eof=%"Q"u srcpos=%"Q"u maxsz=%"Q"u\n", | 3743 | "distance eof=%"Q" srcpos=%"Q" maxsz=%"Q"\n", |
3767 | xd3_source_eof (stream->src), | 3744 | xd3_source_eof (stream->src), |
3768 | srcpos, stream->src->max_winsize)); | 3745 | srcpos, stream->src->max_winsize)); |
3769 | goto bad; | 3746 | goto bad; |
@@ -3771,11 +3748,12 @@ xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos) | |||
3771 | 3748 | ||
3772 | /* Going backwards, the 1.5-pass algorithm allows some | 3749 | /* Going backwards, the 1.5-pass algorithm allows some |
3773 | * already-matched input may be covered by a longer source match. | 3750 | * already-matched input may be covered by a longer source match. |
3774 | * The greedy algorithm does not allow this. */ | 3751 | * The greedy algorithm does not allow this. |
3752 | * TODO: Measure this. */ | ||
3775 | if (stream->flags & XD3_BEGREEDY) | 3753 | if (stream->flags & XD3_BEGREEDY) |
3776 | { | 3754 | { |
3777 | /* The greedy algorithm allows backward matching to the last | 3755 | /* The greedy algorithm allows backward matching to the last |
3778 | matched position. */ | 3756 | * matched position. */ |
3779 | greedy_or_not = xd3_iopt_last_matched (stream); | 3757 | greedy_or_not = xd3_iopt_last_matched (stream); |
3780 | } | 3758 | } |
3781 | else | 3759 | else |
@@ -3804,7 +3782,8 @@ xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos) | |||
3804 | * 0--src->size. We compare the usize_t | 3782 | * 0--src->size. We compare the usize_t |
3805 | * match_maxfwd/match_maxback against the xoff_t | 3783 | * match_maxfwd/match_maxback against the xoff_t |
3806 | * src->size/srcpos values and take the min. */ | 3784 | * src->size/srcpos values and take the min. */ |
3807 | if (srcpos < (xoff_t) stream->match_maxback) | 3785 | /* TODO #if XD3_USE_LARGESIZET ? */ |
3786 | if (srcpos < stream->match_maxback) | ||
3808 | { | 3787 | { |
3809 | stream->match_maxback = (usize_t) srcpos; | 3788 | stream->match_maxback = (usize_t) srcpos; |
3810 | } | 3789 | } |
@@ -3813,14 +3792,14 @@ xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos) | |||
3813 | { | 3792 | { |
3814 | xoff_t srcavail = xd3_source_eof (stream->src) - srcpos; | 3793 | xoff_t srcavail = xd3_source_eof (stream->src) - srcpos; |
3815 | 3794 | ||
3816 | if (srcavail < (xoff_t) stream->match_maxfwd) | 3795 | if (srcavail < stream->match_maxfwd) |
3817 | { | 3796 | { |
3818 | stream->match_maxfwd = (usize_t) srcavail; | 3797 | stream->match_maxfwd = (usize_t) srcavail; |
3819 | } | 3798 | } |
3820 | } | 3799 | } |
3821 | 3800 | ||
3822 | IF_DEBUG2(DP(RINT | 3801 | IF_DEBUG2(DP(RINT |
3823 | "[match_setup] srcpos %"Q"u (tgtpos %"Q"u) " | 3802 | "[match_setup] srcpos %"Q" (tgtpos %"Q") " |
3824 | "unrestricted maxback %u maxfwd %u\n", | 3803 | "unrestricted maxback %u maxfwd %u\n", |
3825 | srcpos, | 3804 | srcpos, |
3826 | stream->total_in + stream->input_position, | 3805 | stream->total_in + stream->input_position, |
@@ -3834,7 +3813,7 @@ xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos) | |||
3834 | 3813 | ||
3835 | /* Restricted case: fail if the srcpos lies outside the source window */ | 3814 | /* Restricted case: fail if the srcpos lies outside the source window */ |
3836 | if ((srcpos < src->srcbase) || | 3815 | if ((srcpos < src->srcbase) || |
3837 | (srcpos > (src->srcbase + (xoff_t) src->srclen))) | 3816 | (srcpos > (src->srcbase + src->srclen))) |
3838 | { | 3817 | { |
3839 | IF_DEBUG1(DP(RINT "[match_setup] restricted source window failure\n")); | 3818 | IF_DEBUG1(DP(RINT "[match_setup] restricted source window failure\n")); |
3840 | goto bad; | 3819 | goto bad; |
@@ -3849,14 +3828,14 @@ xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos) | |||
3849 | stream->match_maxback = srcavail; | 3828 | stream->match_maxback = srcavail; |
3850 | } | 3829 | } |
3851 | 3830 | ||
3852 | srcavail = (usize_t) (src->srcbase + (xoff_t) src->srclen - srcpos); | 3831 | srcavail = src->srcbase + src->srclen - srcpos; |
3853 | if (srcavail < stream->match_maxfwd) | 3832 | if (srcavail < stream->match_maxfwd) |
3854 | { | 3833 | { |
3855 | stream->match_maxfwd = srcavail; | 3834 | stream->match_maxfwd = srcavail; |
3856 | } | 3835 | } |
3857 | 3836 | ||
3858 | IF_DEBUG1(DP(RINT | 3837 | IF_DEBUG1(DP(RINT |
3859 | "[match_setup] srcpos %"Q"u (tgtpos %"Q"u) " | 3838 | "[match_setup] srcpos %"Q" (tgtpos %"Q") " |
3860 | "restricted maxback %u maxfwd %u\n", | 3839 | "restricted maxback %u maxfwd %u\n", |
3861 | srcpos, | 3840 | srcpos, |
3862 | stream->total_in + stream->input_position, | 3841 | stream->total_in + stream->input_position, |
@@ -3876,19 +3855,19 @@ xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos) | |||
3876 | return 1; | 3855 | return 1; |
3877 | } | 3856 | } |
3878 | 3857 | ||
3879 | static inline int | 3858 | static inline usize_t |
3880 | xd3_forward_match(const uint8_t *s1c, const uint8_t *s2c, int n) | 3859 | xd3_forward_match(const uint8_t *s1c, const uint8_t *s2c, usize_t n) |
3881 | { | 3860 | { |
3882 | int i = 0; | 3861 | usize_t i = 0; |
3883 | #if UNALIGNED_OK | 3862 | #if UNALIGNED_OK |
3884 | int nint = n / sizeof(int); | 3863 | usize_t nint = n / sizeof(int); |
3885 | 3864 | ||
3886 | if (nint >> 3) | 3865 | if (nint >> 3) |
3887 | { | 3866 | { |
3888 | int j = 0; | 3867 | usize_t j = 0; |
3889 | const int *s1 = (const int*)s1c; | 3868 | const int *s1 = (const int*)s1c; |
3890 | const int *s2 = (const int*)s2c; | 3869 | const int *s2 = (const int*)s2c; |
3891 | int nint_8 = nint - 8; | 3870 | usize_t nint_8 = nint - 8; |
3892 | 3871 | ||
3893 | while (i <= nint_8 && | 3872 | while (i <= nint_8 && |
3894 | s1[i++] == s2[j++] && | 3873 | s1[i++] == s2[j++] && |
@@ -3935,7 +3914,7 @@ xd3_source_extend_match (xd3_stream *stream) | |||
3935 | usize_t tryrem; /* tryrem is the number of matchable bytes */ | 3914 | usize_t tryrem; /* tryrem is the number of matchable bytes */ |
3936 | usize_t matched; | 3915 | usize_t matched; |
3937 | 3916 | ||
3938 | IF_DEBUG2(DP(RINT "[extend match] srcpos %"Q"u\n", | 3917 | IF_DEBUG2(DP(RINT "[extend match] srcpos %"Q"\n", |
3939 | stream->match_srcpos)); | 3918 | stream->match_srcpos)); |
3940 | 3919 | ||
3941 | XD3_ASSERT (src != NULL); | 3920 | XD3_ASSERT (src != NULL); |
@@ -3973,7 +3952,7 @@ xd3_source_extend_match (xd3_stream *stream) | |||
3973 | 3952 | ||
3974 | tryrem = xd3_min (tryoff, stream->match_maxback - stream->match_back); | 3953 | tryrem = xd3_min (tryoff, stream->match_maxback - stream->match_back); |
3975 | 3954 | ||
3976 | IF_DEBUG2(DP(RINT "[maxback] maxback %u trysrc %"Q"u/%u tgt %u tryrem %u\n", | 3955 | IF_DEBUG2(DP(RINT "[maxback] maxback %u trysrc %"Q"/%u tgt %u tryrem %u\n", |
3977 | stream->match_maxback, tryblk, tryoff, streamoff, tryrem)); | 3956 | stream->match_maxback, tryblk, tryoff, streamoff, tryrem)); |
3978 | 3957 | ||
3979 | /* TODO: This code can be optimized similar to xd3_match_forward() */ | 3958 | /* TODO: This code can be optimized similar to xd3_match_forward() */ |
@@ -4094,7 +4073,7 @@ xd3_source_extend_match (xd3_stream *stream) | |||
4094 | 4073 | ||
4095 | IF_DEBUG2 ({ | 4074 | IF_DEBUG2 ({ |
4096 | static int x = 0; | 4075 | static int x = 0; |
4097 | DP(RINT "[source match:%d] <inp %"Q"u %"Q"u> <src %"Q"u %"Q"u> (%s) [ %u bytes ]\n", | 4076 | DP(RINT "[source match:%d] <inp %"Q" %"Q"> <src %"Q" %"Q"> (%s) [ %u bytes ]\n", |
4098 | x++, | 4077 | x++, |
4099 | stream->total_in + target_position, | 4078 | stream->total_in + target_position, |
4100 | stream->total_in + target_position + match_length, | 4079 | stream->total_in + target_position + match_length, |
@@ -4300,7 +4279,7 @@ xd3_smatch (xd3_stream *stream, | |||
4300 | static void | 4279 | static void |
4301 | xd3_verify_small_state (xd3_stream *stream, | 4280 | xd3_verify_small_state (xd3_stream *stream, |
4302 | const uint8_t *inp, | 4281 | const uint8_t *inp, |
4303 | uint32_t x_cksum) | 4282 | uint32_t x_cksum) |
4304 | { | 4283 | { |
4305 | uint32_t state; | 4284 | uint32_t state; |
4306 | uint32_t cksum = xd3_scksum (&state, inp, stream->smatcher.small_look); | 4285 | uint32_t cksum = xd3_scksum (&state, inp, stream->smatcher.small_look); |
@@ -4311,9 +4290,9 @@ xd3_verify_small_state (xd3_stream *stream, | |||
4311 | static void | 4290 | static void |
4312 | xd3_verify_large_state (xd3_stream *stream, | 4291 | xd3_verify_large_state (xd3_stream *stream, |
4313 | const uint8_t *inp, | 4292 | const uint8_t *inp, |
4314 | uint32_t x_cksum) | 4293 | usize_t x_cksum) |
4315 | { | 4294 | { |
4316 | uint32_t cksum = xd3_lcksum (inp, stream->smatcher.large_look); | 4295 | usize_t cksum = xd3_large_cksum (&stream->large_hash, inp, stream->smatcher.large_look); |
4317 | XD3_ASSERT (cksum == x_cksum); | 4296 | XD3_ASSERT (cksum == x_cksum); |
4318 | } | 4297 | } |
4319 | static void | 4298 | static void |
@@ -4421,13 +4400,13 @@ xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point) | |||
4421 | ret = XD3_INTERNAL; | 4400 | ret = XD3_INTERNAL; |
4422 | } | 4401 | } |
4423 | IF_DEBUG1 (DP(RINT | 4402 | IF_DEBUG1 (DP(RINT |
4424 | "[srcwin_move_point] async getblk return for %"Q"u\n", | 4403 | "[srcwin_move_point] async getblk return for %"Q"\n", |
4425 | blkno)); | 4404 | blkno)); |
4426 | return ret; | 4405 | return ret; |
4427 | } | 4406 | } |
4428 | 4407 | ||
4429 | IF_DEBUG1 (DP(RINT | 4408 | IF_DEBUG1 (DP(RINT |
4430 | "[srcwin_move_point] T=%"Q"u{%"Q"u} S=%"Q"u EOF=%"Q"u %s\n", | 4409 | "[srcwin_move_point] T=%"Q"{%"Q"} S=%"Q" EOF=%"Q" %s\n", |
4431 | stream->total_in + stream->input_position, | 4410 | stream->total_in + stream->input_position, |
4432 | logical_input_cksum_pos, | 4411 | logical_input_cksum_pos, |
4433 | stream->srcwin_cksum_pos, | 4412 | stream->srcwin_cksum_pos, |
@@ -4457,8 +4436,12 @@ xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point) | |||
4457 | 4436 | ||
4458 | do | 4437 | do |
4459 | { | 4438 | { |
4460 | uint32_t cksum = xd3_lcksum (stream->src->curblk + blkpos, | 4439 | /* TODO: This would be significantly faster if the compiler |
4461 | stream->smatcher.large_look); | 4440 | * knew stream->smatcher.large_look (which the template for |
4441 | * xd3_string_match_* allows). */ | ||
4442 | usize_t cksum = xd3_large_cksum (&stream->large_hash, | ||
4443 | stream->src->curblk + blkpos, | ||
4444 | stream->smatcher.large_look); | ||
4462 | usize_t hval = xd3_checksum_hash (& stream->large_hash, cksum); | 4445 | usize_t hval = xd3_checksum_hash (& stream->large_hash, cksum); |
4463 | 4446 | ||
4464 | stream->large_table[hval] = | 4447 | stream->large_table[hval] = |
@@ -4475,8 +4458,8 @@ xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point) | |||
4475 | } | 4458 | } |
4476 | 4459 | ||
4477 | IF_DEBUG1 (DP(RINT | 4460 | IF_DEBUG1 (DP(RINT |
4478 | "[srcwin_move_point] exited loop T=%"Q"u{%"Q"u} " | 4461 | "[srcwin_move_point] exited loop T=%"Q"{%"Q"} " |
4479 | "S=%"Q"u EOF=%"Q"u %s\n", | 4462 | "S=%"Q" EOF=%"Q" %s\n", |
4480 | stream->total_in + stream->input_position, | 4463 | stream->total_in + stream->input_position, |
4481 | logical_input_cksum_pos, | 4464 | logical_input_cksum_pos, |
4482 | stream->srcwin_cksum_pos, | 4465 | stream->srcwin_cksum_pos, |
@@ -4550,7 +4533,7 @@ XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) | |||
4550 | const uint8_t *inp; | 4533 | const uint8_t *inp; |
4551 | uint32_t scksum = 0; | 4534 | uint32_t scksum = 0; |
4552 | uint32_t scksum_state = 0; | 4535 | uint32_t scksum_state = 0; |
4553 | uint32_t lcksum = 0; | 4536 | usize_t lcksum = 0; |
4554 | usize_t sinx; | 4537 | usize_t sinx; |
4555 | usize_t linx; | 4538 | usize_t linx; |
4556 | uint8_t run_c; | 4539 | uint8_t run_c; |
@@ -4620,7 +4603,7 @@ XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) | |||
4620 | return ret; | 4603 | return ret; |
4621 | } | 4604 | } |
4622 | 4605 | ||
4623 | lcksum = xd3_lcksum (inp, LLOOK); | 4606 | lcksum = xd3_large_cksum (&stream->large_hash, inp, LLOOK); |
4624 | } | 4607 | } |
4625 | 4608 | ||
4626 | /* TRYLAZYLEN: True if a certain length match should be followed by | 4609 | /* TRYLAZYLEN: True if a certain length match should be followed by |
@@ -4796,7 +4779,7 @@ XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) | |||
4796 | 4779 | ||
4797 | if (DO_LARGE && (stream->input_position + LLOOK < stream->avail_in)) | 4780 | if (DO_LARGE && (stream->input_position + LLOOK < stream->avail_in)) |
4798 | { | 4781 | { |
4799 | lcksum = xd3_large_cksum_update (lcksum, inp, LLOOK); | 4782 | lcksum = xd3_large_cksum_update (&stream->large_hash, lcksum, inp, LLOOK); |
4800 | } | 4783 | } |
4801 | } | 4784 | } |
4802 | 4785 | ||