summaryrefslogtreecommitdiff
path: root/xdelta3/xdelta3.c
diff options
context:
space:
mode:
authorjosh.macdonald <jmacd@users.noreply.github.com>2007-10-28 22:20:26 +0000
committerjosh.macdonald <jmacd@users.noreply.github.com>2007-10-28 22:20:26 +0000
commit93250631824866baa87bfa7aac463258250fa6b1 (patch)
tree8d4583cf77c9cccc6fbab287d273b63691648896 /xdelta3/xdelta3.c
parent49327439297ae6239f30dc77abf90e86352b7b7e (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.c372
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
309typedef enum { 309typedef 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
361XD3_MAKELIST(xd3_rlist, xd3_rinst, link); 361XD3_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
542static void* xd3_alloc0 (xd3_stream *stream, 542static void* xd3_alloc0 (xd3_stream *stream,
@@ -565,6 +565,7 @@ static int xd3_emit_double (xd3_stream *stream, xd3_rinst *first, xd3_ri
565static int xd3_emit_single (xd3_stream *stream, xd3_rinst *single, uint code); 565static int xd3_emit_single (xd3_stream *stream, xd3_rinst *single, uint code);
566 566
567static usize_t xd3_sizeof_output (xd3_output *output); 567static usize_t xd3_sizeof_output (xd3_output *output);
568static void xd3_encode_reset (xd3_stream *stream);
568 569
569static int xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos); 570static int xd3_source_match_setup (xd3_stream *stream, xoff_t srcpos);
570static int xd3_source_extend_match (xd3_stream *stream); 571static 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,
588static int xd3_selftest (void); 589static 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. */
975static void 977static void
976xd3_choose_instruction (const xd3_code_table_desc *desc, xd3_rinst *prev, xd3_rinst *inst) 978xd3_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. */
1131static const uint8_t __alternate_code_table_compressed[178] = 1137static 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,
11330x01,0x03,0x00,0x01,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, 11390x01,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. */
1216static int 1222static int
1217xd3_compute_alternate_table_encoding (xd3_stream *stream, const uint8_t **data, usize_t *size) 1223xd3_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
1473static const usize_t __primes[] = 1479static 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
1506static inline void 1512static inline void
1507xd3_swap_uint8p (uint8_t** p1, uint8_t** p2) 1513xd3_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
1613static inline uint32_t 1619static 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
1707static inline int 1713static inline int
1708xd3_comprun (const uint8_t *seg, int slook, uint8_t *run_cp) 1714xd3_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
1728static int 1734static int
1729xd3_decode_byte (xd3_stream *stream, uint *val) 1735xd3_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
1987static int 1993static int
1988xd3_alloc_cache (xd3_stream *stream) 1994xd3_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
2142static void* 2148static 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
2394int 2400int
2395xd3_config_stream(xd3_stream *stream, 2401xd3_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. */
2573static int 2580static int
2574xd3_getblk (xd3_stream *stream/*, xd3_source *source*/, xoff_t blkno) 2581xd3_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
2619int 2627int
2620xd3_set_source (xd3_stream *stream, 2628xd3_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
2685int 2709int
2686xd3_get_appheader (xd3_stream *stream, 2710xd3_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
2712void 2736void
@@ -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
3468static int 3492static int
3469xd3_encode_buffer_leftover (xd3_stream *stream) 3493xd3_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
4760static int XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream);
4761
4762static 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 */
4783static int 4778static int
4784XD3_TEMPLATE(xd3_srcwin_move_point_) (xd3_stream *stream, usize_t *next_move_point) 4779xd3_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
4932static int XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream);
4933
4934static 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
4912static int 4945static int
4913XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream) 4946XD3_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 {