summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjosh.macdonald <jmacd@users.noreply.github.com>2007-11-11 07:59:13 +0000
committerjosh.macdonald <jmacd@users.noreply.github.com>2007-11-11 07:59:13 +0000
commita4b5480a34e217e93e147f460b47e27741d809c1 (patch)
treeea759058caece01d1d09697c392f3a6d20c28bc5
parent9c137e5d088878e6867b5de40ddefa30a7afa59c (diff)
Compile with g++ 3.4.4 and add C++ checksum_test.cc
-rw-r--r--xdelta3/Makefile2
-rwxr-xr-xxdelta3/examples/Makefile7
-rw-r--r--xdelta3/examples/checksum_test.cc79
-rw-r--r--xdelta3/examples/speed_test.c38
-rw-r--r--xdelta3/examples/test.h40
-rw-r--r--xdelta3/xdelta3-cfgs.h10
-rw-r--r--xdelta3/xdelta3-decode.h10
-rw-r--r--xdelta3/xdelta3-hash.h237
-rw-r--r--xdelta3/xdelta3-main.h50
-rw-r--r--xdelta3/xdelta3.c354
10 files changed, 482 insertions, 345 deletions
diff --git a/xdelta3/Makefile b/xdelta3/Makefile
index 9c8b79e..a4c7281 100644
--- a/xdelta3/Makefile
+++ b/xdelta3/Makefile
@@ -5,6 +5,7 @@ SOURCES = xdelta3-cfgs.h \
5 xdelta3-decode.h \ 5 xdelta3-decode.h \
6 xdelta3-djw.h \ 6 xdelta3-djw.h \
7 xdelta3-fgk.h \ 7 xdelta3-fgk.h \
8 xdelta3-hash.h \
8 xdelta3-list.h \ 9 xdelta3-list.h \
9 xdelta3-main.h \ 10 xdelta3-main.h \
10 xdelta3-python.h \ 11 xdelta3-python.h \
@@ -49,6 +50,7 @@ EXTRA = Makefile COPYING linkxd3lib.c badcopy.c xdelta3.swig \
49 examples/Makefile examples/small_page_test.c \ 50 examples/Makefile examples/small_page_test.c \
50 examples/README examples/encode_decode_test.c \ 51 examples/README examples/encode_decode_test.c \
51 examples/compare_test.c examples/speed_test.c \ 52 examples/compare_test.c examples/speed_test.c \
53 examples/test.h examples/checksum_test.c \
52 xdelta3.py xdelta3_wrap.c xdelta3.wxs xdelta3.wxi \ 54 xdelta3.py xdelta3_wrap.c xdelta3.wxs xdelta3.wxi \
53 README readme.txt 55 README readme.txt
54 56
diff --git a/xdelta3/examples/Makefile b/xdelta3/examples/Makefile
index 0e1825d..abdb6be 100755
--- a/xdelta3/examples/Makefile
+++ b/xdelta3/examples/Makefile
@@ -4,9 +4,9 @@ CFLAGS = -O3 -Wall -I.. -DXD3_DEBUG=0 -fno-builtin
4 4
5SOURCES = small_page_test.c encode_decode_test.c speed_test.c 5SOURCES = small_page_test.c encode_decode_test.c speed_test.c
6 6
7DEPS = ../*.h ../*.c 7DEPS = ../*.h ../*.c *.h
8 8
9TARGETS = small_page_test encode_decode_test speed_test32 speed_test64 compare_test 9TARGETS = small_page_test encode_decode_test speed_test32 speed_test64 compare_test checksum_test
10 10
11all: $(TARGETS) 11all: $(TARGETS)
12 12
@@ -25,5 +25,8 @@ speed_test64: speed_test.c $(DEPS)
25compare_test: compare_test.c 25compare_test: compare_test.c
26 $(CC) $(CFLAGS) compare_test.c -o compare_test 26 $(CC) $(CFLAGS) compare_test.c -o compare_test
27 27
28checksum_test: checksum_test.cc
29 $(CXX) $(CFLAGS) checksum_test.cc -o checksum_test
30
28clean: 31clean:
29 rm -f *.exe *.stackdump $(TARGETS) 32 rm -f *.exe *.stackdump $(TARGETS)
diff --git a/xdelta3/examples/checksum_test.cc b/xdelta3/examples/checksum_test.cc
new file mode 100644
index 0000000..821291a
--- /dev/null
+++ b/xdelta3/examples/checksum_test.cc
@@ -0,0 +1,79 @@
1/* Copyright (C) 2007 Josh MacDonald */
2
3extern "C" {
4#include "test.h"
5#include <assert.h>
6}
7
8// template <typename T, int Cklen>
9// struct cksum_params {
10// typedef T cksum_type;
11// enum { cklen = Cklen };
12// };
13
14template <int Cklen>
15struct rabin_karp {
16 enum { cklen = Cklen, };
17};
18
19template<typename T>
20struct test_result {
21
22 int n_data;
23
24 test_result()
25 : n_data(0) {
26 }
27
28 void print() {
29 fprintf(stderr, "cklen %u: %u results\n", T::cklen, n_data);
30 }
31
32 void add(uint8_t* ptr) {
33 n_data++;
34 }
35};
36
37typedef rabin_karp<4> small_cksum;
38typedef rabin_karp<9> large_cksum;
39
40template<typename T>
41void test(uint8_t* buf, usize_t buf_len) {
42 test_result<T> result;
43
44 for (usize_t i = 0; i < buf_len - T::cklen; i++) {
45 result.add(buf + i);
46 }
47
48 result.print();
49}
50
51int main(int argc, char** argv) {
52 int i;
53 uint8_t *buf = NULL;
54 usize_t buf_len = 0;
55 int ret;
56
57 if (argc <= 1) {
58 fprintf(stderr, "usage: %s file ...", argv[0]);
59 return 1;
60 }
61
62 for (i = 1; i < argc; i++) {
63 if ((ret = read_whole_file(argv[i],
64 & buf,
65 & buf_len))) {
66 return 1;
67 }
68
69 fprintf(stderr, "file %s is %u bytes\n", argv[i], buf_len);
70
71 test<small_cksum>(buf, buf_len);
72 test<large_cksum>(buf, buf_len);
73
74 free(buf);
75 buf = NULL;
76 }
77
78 return 0;
79}
diff --git a/xdelta3/examples/speed_test.c b/xdelta3/examples/speed_test.c
index dea6621..532be17 100644
--- a/xdelta3/examples/speed_test.c
+++ b/xdelta3/examples/speed_test.c
@@ -1,9 +1,6 @@
1/* Copyright (C) 2007 Josh MacDonald */ 1/* Copyright (C) 2007 Josh MacDonald */
2 2
3#define NOT_MAIN 1 3#include "test.h"
4
5#include "xdelta3.h"
6#include "xdelta3.c"
7 4
8usize_t bench_speed(const uint8_t *from_buf, const size_t from_len, 5usize_t bench_speed(const uint8_t *from_buf, const size_t from_len,
9 const uint8_t *to_buf, const size_t to_len, 6 const uint8_t *to_buf, const size_t to_len,
@@ -19,39 +16,6 @@ usize_t bench_speed(const uint8_t *from_buf, const size_t from_len,
19 return delta_size; 16 return delta_size;
20} 17}
21 18
22int read_whole_file(const char *name,
23 uint8_t **buf_ptr,
24 size_t *buf_len) {
25 main_file file;
26 int ret;
27 xoff_t len;
28 size_t nread;
29 main_file_init(&file);
30 file.filename = name;
31 ret = main_file_open(&file, name, XO_READ);
32 if (ret != 0) {
33 goto exit;
34 }
35 ret = main_file_stat(&file, &len, 1);
36 if (ret != 0) {
37 goto exit;
38 }
39
40 (*buf_len) = (size_t)len;
41 (*buf_ptr) = main_malloc(*buf_len);
42 ret = main_file_read(&file, *buf_ptr, *buf_len, &nread,
43 "read failed");
44 if (ret == 0 && *buf_len == nread) {
45 ret = 0;
46 } else {
47 fprintf(stderr, "invalid read\n");
48 ret = XD3_INTERNAL;
49 }
50 exit:
51 main_file_cleanup(&file);
52 return ret;
53}
54
55int main(int argc, char **argv) { 19int main(int argc, char **argv) {
56 int repeat, level; 20 int repeat, level;
57 char *from, *to; 21 char *from, *to;
diff --git a/xdelta3/examples/test.h b/xdelta3/examples/test.h
new file mode 100644
index 0000000..f6dd7e5
--- /dev/null
+++ b/xdelta3/examples/test.h
@@ -0,0 +1,40 @@
1/* Copyright (C) 2007 Josh MacDonald */
2
3#define NOT_MAIN 1
4
5#include "xdelta3.h"
6#include "xdelta3.c"
7
8static int read_whole_file(const char *name,
9 uint8_t **buf_ptr,
10 size_t *buf_len) {
11 main_file file;
12 int ret;
13 xoff_t len;
14 size_t nread;
15 main_file_init(&file);
16 file.filename = name;
17 ret = main_file_open(&file, name, XO_READ);
18 if (ret != 0) {
19 goto exit;
20 }
21 ret = main_file_stat(&file, &len, 1);
22 if (ret != 0) {
23 goto exit;
24 }
25
26 (*buf_len) = (size_t)len;
27 (*buf_ptr) = (uint8_t*) main_malloc(*buf_len);
28 ret = main_file_read(&file, *buf_ptr, *buf_len, &nread,
29 "read failed");
30 if (ret == 0 && *buf_len == nread) {
31 ret = 0;
32 } else {
33 fprintf(stderr, "invalid read\n");
34 ret = XD3_INTERNAL;
35 }
36 exit:
37 main_file_cleanup(&file);
38 return ret;
39}
40
diff --git a/xdelta3/xdelta3-cfgs.h b/xdelta3/xdelta3-cfgs.h
index 39fca3b..b13f7b0 100644
--- a/xdelta3/xdelta3-cfgs.h
+++ b/xdelta3/xdelta3-cfgs.h
@@ -54,7 +54,7 @@
54#define TEMPLATE fastest 54#define TEMPLATE fastest
55#define LLOOK 9 55#define LLOOK 9
56#define LSTEP 26 56#define LSTEP 26
57#define SLOOK 4 57#define SLOOK 4U
58#define SCHAIN 1 58#define SCHAIN 1
59#define SLCHAIN 1 59#define SLCHAIN 1
60#define MAXLAZY 6 60#define MAXLAZY 6
@@ -79,7 +79,7 @@
79#define TEMPLATE faster 79#define TEMPLATE faster
80#define LLOOK 9 80#define LLOOK 9
81#define LSTEP 15 81#define LSTEP 15
82#define SLOOK 4 82#define SLOOK 4U
83#define SCHAIN 1 83#define SCHAIN 1
84#define SLCHAIN 1 84#define SLCHAIN 1
85#define MAXLAZY 18 85#define MAXLAZY 18
@@ -104,7 +104,7 @@
104#define TEMPLATE fast 104#define TEMPLATE fast
105#define LLOOK 9 105#define LLOOK 9
106#define LSTEP 8 106#define LSTEP 8
107#define SLOOK 4 107#define SLOOK 4U
108#define SCHAIN 4 108#define SCHAIN 4
109#define SLCHAIN 1 109#define SLCHAIN 1
110#define MAXLAZY 18 110#define MAXLAZY 18
@@ -129,7 +129,7 @@
129#define TEMPLATE slow 129#define TEMPLATE slow
130#define LLOOK 9 130#define LLOOK 9
131#define LSTEP 2 131#define LSTEP 2
132#define SLOOK 4 132#define SLOOK 4U
133#define SCHAIN 44 133#define SCHAIN 44
134#define SLCHAIN 13 134#define SLCHAIN 13
135#define MAXLAZY 90 135#define MAXLAZY 90
@@ -154,7 +154,7 @@
154#define TEMPLATE default 154#define TEMPLATE default
155#define LLOOK 9 155#define LLOOK 9
156#define LSTEP 3 156#define LSTEP 3
157#define SLOOK 4 157#define SLOOK 4U
158#define SCHAIN 8 158#define SCHAIN 8
159#define SLCHAIN 2 159#define SLCHAIN 2
160#define MAXLAZY 36 160#define MAXLAZY 36
diff --git a/xdelta3/xdelta3-decode.h b/xdelta3/xdelta3-decode.h
index 0b49fb9..8e3e799 100644
--- a/xdelta3/xdelta3-decode.h
+++ b/xdelta3/xdelta3-decode.h
@@ -85,7 +85,7 @@ xd3_decode_setup_buffers (xd3_stream *stream)
85 85
86 stream->space_out = xd3_round_blksize (stream->dec_tgtlen, XD3_ALLOCSIZE); 86 stream->space_out = xd3_round_blksize (stream->dec_tgtlen, XD3_ALLOCSIZE);
87 87
88 if ((stream->dec_buffer = xd3_alloc (stream, stream->space_out, 1)) == NULL) 88 if ((stream->dec_buffer = (uint8_t*) xd3_alloc (stream, stream->space_out, 1)) == NULL)
89 { 89 {
90 return ENOMEM; 90 return ENOMEM;
91 } 91 }
@@ -118,7 +118,7 @@ xd3_decode_allocate (xd3_stream *stream,
118 { 118 {
119 *buf_alloc = xd3_round_blksize (size, XD3_ALLOCSIZE); 119 *buf_alloc = xd3_round_blksize (size, XD3_ALLOCSIZE);
120 120
121 if ((*buf_ptr = xd3_alloc (stream, *buf_alloc, 1)) == NULL) 121 if ((*buf_ptr = (uint8_t*) xd3_alloc (stream, *buf_alloc, 1)) == NULL)
122 { 122 {
123 return ENOMEM; 123 return ENOMEM;
124 } 124 }
@@ -805,7 +805,8 @@ xd3_decode_input (xd3_stream *stream)
805 { 805 {
806 /* Get the code table data. */ 806 /* Get the code table data. */
807 if ((stream->dec_codetbl == NULL) && 807 if ((stream->dec_codetbl == NULL) &&
808 (stream->dec_codetbl = xd3_alloc (stream, stream->dec_codetblsz, 1)) == NULL) { return ENOMEM; } 808 (stream->dec_codetbl =
809 (uint8_t*) xd3_alloc (stream, stream->dec_codetblsz, 1)) == NULL) { return ENOMEM; }
809 810
810 if ((ret = xd3_decode_bytes (stream, stream->dec_codetbl, & stream->dec_codetblbytes, stream->dec_codetblsz))) 811 if ((ret = xd3_decode_bytes (stream, stream->dec_codetbl, & stream->dec_codetblbytes, stream->dec_codetblsz)))
811 { 812 {
@@ -840,7 +841,8 @@ xd3_decode_input (xd3_stream *stream)
840 /* Note: we add an additional byte for padding, to allow 841 /* Note: we add an additional byte for padding, to allow
841 0-termination. */ 842 0-termination. */
842 if ((stream->dec_appheader == NULL) && 843 if ((stream->dec_appheader == NULL) &&
843 (stream->dec_appheader = xd3_alloc (stream, stream->dec_appheadsz+1, 1)) == NULL) { return ENOMEM; } 844 (stream->dec_appheader =
845 (uint8_t*) xd3_alloc (stream, stream->dec_appheadsz+1, 1)) == NULL) { return ENOMEM; }
844 846
845 stream->dec_appheader[stream->dec_appheadsz] = 0; 847 stream->dec_appheader[stream->dec_appheadsz] = 0;
846 848
diff --git a/xdelta3/xdelta3-hash.h b/xdelta3/xdelta3-hash.h
new file mode 100644
index 0000000..a1cc9d8
--- /dev/null
+++ b/xdelta3/xdelta3-hash.h
@@ -0,0 +1,237 @@
1/* xdelta 3 - delta compression tools and library
2 * Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007. Joshua P. MacDonald
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19/* To know more about Xdelta, start by reading xdelta3.c. If you are
20 * ready to use the API, continue reading here. There are two
21 * interfaces -- xd3_encode_input and xd3_decode_input -- plus a dozen
22 * or so related calls. This interface is styled after Zlib. */
23
24#ifndef _XDELTA3_HASH_H_
25#define _XDELTA3_HASH_H_
26
27#if XD3_DEBUG
28#define SMALL_HASH_DEBUG1(s,inp) \
29 usize_t debug_hval = xd3_checksum_hash (& (s)->small_hash, \
30 xd3_scksum ((inp), (s)->smatcher.small_look))
31#define SMALL_HASH_DEBUG2(s,inp) \
32 XD3_ASSERT (debug_hval == xd3_checksum_hash (& (s)->small_hash, \
33 xd3_scksum ((inp), (s)->smatcher.small_look)))
34#else
35#define SMALL_HASH_DEBUG1(s,inp)
36#define SMALL_HASH_DEBUG2(s,inp)
37#endif /* XD3_DEBUG */
38
39/* Update the run-length state */
40#define NEXTRUN(c) do { if ((c) == run_c) { run_l += 1; } \
41 else { run_c = (c); run_l = 1; } } while (0)
42
43/* Update the checksum state. */
44#define OLD_LARGE_CKSUM 1
45#if OLD_LARGE_CKSUM
46#define LARGE_CKSUM_UPDATE(cksum,base,look) \
47 do { \
48 uint32_t old_c = PERMUTE((base)[0]); \
49 uint32_t new_c = PERMUTE((base)[(look)]); \
50 uint32_t low = (((cksum) & 0xffff) - old_c + new_c) & 0xffff; \
51 uint32_t high = (((cksum) >> 16) - (old_c * (look)) + low) & 0xffff; \
52 (cksum) = (high << 16) | low; \
53 } while (0)
54#else
55#define LARGE_CKSUM_UPDATE(cksum,base,look) \
56 do { \
57 // linear congruential generators of different
58 // sizes and good lattice structure
59 } while (1)
60#endif
61
62/* Multiply and add hash function */
63#if ARITH_SMALL_CKSUM
64#define SMALL_CKSUM_UPDATE(cksum,base,look) (cksum) = ((*(unsigned long*)(base+1)) * 71143)
65#else
66#define SMALL_CKSUM_UPDATE LARGE_CKSUM_UPDATE
67#endif
68
69/***********************************************************************
70 Permute stuff
71 ***********************************************************************/
72
73#if HASH_PERMUTE == 0
74#define PERMUTE(x) (x)
75#else
76#define PERMUTE(x) (__single_hash[(uint)x])
77
78static const uint16_t __single_hash[256] =
79{
80 /* Random numbers generated using SLIB's pseudo-random number generator. This hashes
81 * the input alphabet. */
82 0xbcd1, 0xbb65, 0x42c2, 0xdffe, 0x9666, 0x431b, 0x8504, 0xeb46,
83 0x6379, 0xd460, 0xcf14, 0x53cf, 0xdb51, 0xdb08, 0x12c8, 0xf602,
84 0xe766, 0x2394, 0x250d, 0xdcbb, 0xa678, 0x02af, 0xa5c6, 0x7ea6,
85 0xb645, 0xcb4d, 0xc44b, 0xe5dc, 0x9fe6, 0x5b5c, 0x35f5, 0x701a,
86 0x220f, 0x6c38, 0x1a56, 0x4ca3, 0xffc6, 0xb152, 0x8d61, 0x7a58,
87 0x9025, 0x8b3d, 0xbf0f, 0x95a3, 0xe5f4, 0xc127, 0x3bed, 0x320b,
88 0xb7f3, 0x6054, 0x333c, 0xd383, 0x8154, 0x5242, 0x4e0d, 0x0a94,
89 0x7028, 0x8689, 0x3a22, 0x0980, 0x1847, 0xb0f1, 0x9b5c, 0x4176,
90 0xb858, 0xd542, 0x1f6c, 0x2497, 0x6a5a, 0x9fa9, 0x8c5a, 0x7743,
91 0xa8a9, 0x9a02, 0x4918, 0x438c, 0xc388, 0x9e2b, 0x4cad, 0x01b6,
92 0xab19, 0xf777, 0x365f, 0x1eb2, 0x091e, 0x7bf8, 0x7a8e, 0x5227,
93 0xeab1, 0x2074, 0x4523, 0xe781, 0x01a3, 0x163d, 0x3b2e, 0x287d,
94 0x5e7f, 0xa063, 0xb134, 0x8fae, 0x5e8e, 0xb7b7, 0x4548, 0x1f5a,
95 0xfa56, 0x7a24, 0x900f, 0x42dc, 0xcc69, 0x02a0, 0x0b22, 0xdb31,
96 0x71fe, 0x0c7d, 0x1732, 0x1159, 0xcb09, 0xe1d2, 0x1351, 0x52e9,
97 0xf536, 0x5a4f, 0xc316, 0x6bf9, 0x8994, 0xb774, 0x5f3e, 0xf6d6,
98 0x3a61, 0xf82c, 0xcc22, 0x9d06, 0x299c, 0x09e5, 0x1eec, 0x514f,
99 0x8d53, 0xa650, 0x5c6e, 0xc577, 0x7958, 0x71ac, 0x8916, 0x9b4f,
100 0x2c09, 0x5211, 0xf6d8, 0xcaaa, 0xf7ef, 0x287f, 0x7a94, 0xab49,
101 0xfa2c, 0x7222, 0xe457, 0xd71a, 0x00c3, 0x1a76, 0xe98c, 0xc037,
102 0x8208, 0x5c2d, 0xdfda, 0xe5f5, 0x0b45, 0x15ce, 0x8a7e, 0xfcad,
103 0xaa2d, 0x4b5c, 0xd42e, 0xb251, 0x907e, 0x9a47, 0xc9a6, 0xd93f,
104 0x085e, 0x35ce, 0xa153, 0x7e7b, 0x9f0b, 0x25aa, 0x5d9f, 0xc04d,
105 0x8a0e, 0x2875, 0x4a1c, 0x295f, 0x1393, 0xf760, 0x9178, 0x0f5b,
106 0xfa7d, 0x83b4, 0x2082, 0x721d, 0x6462, 0x0368, 0x67e2, 0x8624,
107 0x194d, 0x22f6, 0x78fb, 0x6791, 0xb238, 0xb332, 0x7276, 0xf272,
108 0x47ec, 0x4504, 0xa961, 0x9fc8, 0x3fdc, 0xb413, 0x007a, 0x0806,
109 0x7458, 0x95c6, 0xccaa, 0x18d6, 0xe2ae, 0x1b06, 0xf3f6, 0x5050,
110 0xc8e8, 0xf4ac, 0xc04c, 0xf41c, 0x992f, 0xae44, 0x5f1b, 0x1113,
111 0x1738, 0xd9a8, 0x19ea, 0x2d33, 0x9698, 0x2fe9, 0x323f, 0xcde2,
112 0x6d71, 0xe37d, 0xb697, 0x2c4f, 0x4373, 0x9102, 0x075d, 0x8e25,
113 0x1672, 0xec28, 0x6acb, 0x86cc, 0x186e, 0x9414, 0xd674, 0xd1a5
114};
115#endif
116
117/***********************************************************************
118 Ctable stuff
119 ***********************************************************************/
120
121#if HASH_PRIME
122static const usize_t __primes[] =
123{
124 11, 19, 37, 73, 109,
125 163, 251, 367, 557, 823,
126 1237, 1861, 2777, 4177, 6247,
127 9371, 14057, 21089, 31627, 47431,
128 71143, 106721, 160073, 240101, 360163,
129 540217, 810343, 1215497, 1823231, 2734867,
130 4102283, 6153409, 9230113, 13845163, 20767711,
131 31151543, 46727321, 70090921, 105136301, 157704401,
132 236556601, 354834919, 532252367, 798378509, 1197567719,
133 1796351503
134};
135
136static const usize_t __nprimes = SIZEOF_ARRAY (__primes);
137#endif
138
139static inline usize_t
140xd3_checksum_hash (const xd3_hash_cfg *cfg, const usize_t cksum)
141{
142#if HASH_PRIME
143 /* If the table is prime compute the modulus. */
144 return (cksum % cfg->size);
145#else
146 /* If the table is power-of-two compute the mask.*/
147 return (cksum ^ (cksum >> cfg->shift)) & cfg->mask;
148#endif
149}
150
151/***********************************************************************
152 Cksum function
153 ***********************************************************************/
154
155static inline uint32_t
156xd3_lcksum (const uint8_t *seg, const int ln)
157{
158 int i = 0;
159 uint32_t low = 0;
160 uint32_t high = 0;
161
162 for (; i < ln; i += 1)
163 {
164 low += PERMUTE(*seg++);
165 high += low;
166 }
167
168 return ((high & 0xffff) << 16) | (low & 0xffff);
169}
170
171#if ARITH_SMALL_CKSUM
172static inline usize_t
173xd3_scksum (const uint8_t *seg, const int ln)
174{
175 usize_t c;
176 /* The -1 is because UPDATE operates on seg[1..ln] */
177 SMALL_CKSUM_UPDATE (c,(seg-1),ln);
178 return c;
179}
180#else
181#define xd3_scksum(seg,ln) xd3_lcksum(seg,ln)
182#endif
183
184#if XD3_ENCODER
185#if !HASH_PRIME
186static usize_t
187xd3_size_log2 (usize_t slots)
188{
189 int bits = 28; /* This should not be an unreasonable limit. */
190 int i;
191
192 for (i = 3; i <= bits; i += 1)
193 {
194 if (slots < (1U << i))
195 {
196 bits = i-1;
197 break;
198 }
199 }
200
201 return bits;
202}
203#endif
204#endif
205
206static void
207xd3_size_hashtable (xd3_stream *stream,
208 usize_t slots,
209 xd3_hash_cfg *cfg)
210{
211 /* initialize ctable: the number of hash buckets is computed from the table of primes or
212 * the nearest power-of-two, in both cases rounding down in favor of using less
213 * memory. */
214
215#if HASH_PRIME
216 usize_t i;
217
218 cfg->size = __primes[__nprimes-1];
219
220 for (i = 1; i < __nprimes; i += 1)
221 {
222 if (slots < __primes[i])
223 {
224 cfg->size = __primes[i-1];
225 break;
226 }
227 }
228#else
229 int bits = xd3_size_log2 (slots);
230
231 cfg->size = (1 << bits);
232 cfg->mask = (cfg->size - 1);
233 cfg->shift = min (32 - bits, 16);
234#endif
235}
236
237#endif
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h
index 23133a3..5c02a75 100644
--- a/xdelta3/xdelta3-main.h
+++ b/xdelta3/xdelta3-main.h
@@ -227,7 +227,7 @@ struct _main_extcomp
227 227
228 const char *ident; 228 const char *ident;
229 const char *magic; 229 const char *magic;
230 int magic_size; 230 usize_t magic_size;
231 int flags; 231 int flags;
232}; 232};
233 233
@@ -300,7 +300,7 @@ static uint8_t* appheader_used = NULL;
300static uint8_t* main_bdata = NULL; 300static uint8_t* main_bdata = NULL;
301 301
302/* The LRU: obviously this is shared by all callers. */ 302/* The LRU: obviously this is shared by all callers. */
303static int lru_size = 0; 303static usize_t lru_size = 0;
304static main_blklru *lru = NULL; /* array of lru_size elts */ 304static main_blklru *lru = NULL; /* array of lru_size elts */
305static main_blklru_list lru_list; 305static main_blklru_list lru_list;
306static main_blklru_list lru_free; 306static main_blklru_list lru_free;
@@ -550,7 +550,7 @@ static char*
550main_format_bcnt (xoff_t r, char *buf) 550main_format_bcnt (xoff_t r, char *buf)
551{ 551{
552 static const char* fmts[] = { "B", "KB", "MB", "GB" }; 552 static const char* fmts[] = { "B", "KB", "MB", "GB" };
553 int i; 553 usize_t i;
554 554
555 for (i = 0; i < SIZEOF_ARRAY(fmts); i += 1) 555 for (i = 0; i < SIZEOF_ARRAY(fmts); i += 1)
556 { 556 {
@@ -977,7 +977,7 @@ main_file_seek (main_file *xfile, xoff_t pos)
977 if (fseek (xfile->file, pos, SEEK_SET) != 0) { ret = get_errno (); } 977 if (fseek (xfile->file, pos, SEEK_SET) != 0) { ret = get_errno (); }
978 978
979#elif XD3_POSIX 979#elif XD3_POSIX
980 if (lseek (xfile->file, pos, SEEK_SET) != pos) { ret = get_errno (); } 980 if ((xoff_t) lseek (xfile->file, pos, SEEK_SET) != pos) { ret = get_errno (); }
981 981
982#elif XD3_WIN32 982#elif XD3_WIN32
983 LARGE_INTEGER move, out; 983 LARGE_INTEGER move, out;
@@ -1725,10 +1725,10 @@ main_decompress_input_check (main_file *ifile,
1725 usize_t input_size, 1725 usize_t input_size,
1726 usize_t *nread) 1726 usize_t *nread)
1727{ 1727{
1728 int i;
1729 int ret; 1728 int ret;
1729 usize_t i;
1730 usize_t check_nread;
1730 uint8_t check_buf[XD3_ALLOCSIZE]; 1731 uint8_t check_buf[XD3_ALLOCSIZE];
1731 usize_t check_nread;
1732 1732
1733 if ((ret = main_file_read (ifile, check_buf, min (input_size, XD3_ALLOCSIZE), & check_nread, "input read failed"))) 1733 if ((ret = main_file_read (ifile, check_buf, min (input_size, XD3_ALLOCSIZE), & check_nread, "input read failed")))
1734 { 1734 {
@@ -1794,7 +1794,8 @@ main_decompress_source (main_file *sfile, xd3_source *source)
1794 1794
1795 /* Make a template for mkstmp() */ 1795 /* Make a template for mkstmp() */
1796 if (tmpdir == NULL) { tmpdir = "/tmp"; } 1796 if (tmpdir == NULL) { tmpdir = "/tmp"; }
1797 if ((tmpname = main_malloc (strlen (tmpdir) + sizeof (tmpl) + 1)) == NULL) { return ENOMEM; } 1797 if ((tmpname =
1798 (char*) main_malloc (strlen (tmpdir) + sizeof (tmpl) + 1)) == NULL) { return ENOMEM; }
1798 sprintf (tmpname, "%s%s", tmpdir, tmpl); 1799 sprintf (tmpname, "%s%s", tmpdir, tmpl);
1799 1800
1800 XD3_ASSERT (ext_tmpfile == NULL); 1801 XD3_ASSERT (ext_tmpfile == NULL);
@@ -1960,7 +1961,7 @@ main_recompress_output (main_file *ofile)
1960static const main_extcomp* 1961static const main_extcomp*
1961main_ident_compressor (const char *ident) 1962main_ident_compressor (const char *ident)
1962{ 1963{
1963 int i; 1964 usize_t i;
1964 1965
1965 for (i = 0; i < SIZEOF_ARRAY (extcomp_types); i += 1) 1966 for (i = 0; i < SIZEOF_ARRAY (extcomp_types); i += 1)
1966 { 1967 {
@@ -2059,7 +2060,7 @@ main_set_appheader (xd3_stream *stream, main_file *input, main_file *sfile)
2059 sname = scomp = ""; 2060 sname = scomp = "";
2060 } 2061 }
2061 2062
2062 if ((appheader_used = main_malloc (len)) == NULL) 2063 if ((appheader_used = (uint8_t*) main_malloc (len)) == NULL)
2063 { 2064 {
2064 return ENOMEM; 2065 return ENOMEM;
2065 } 2066 }
@@ -2103,7 +2104,7 @@ main_get_appheader_params (main_file *file, char **parsed, int output, const cha
2103 int dlen = last_slash - other->filename; 2104 int dlen = last_slash - other->filename;
2104 2105
2105 XD3_ASSERT(file->filename_copy == NULL); 2106 XD3_ASSERT(file->filename_copy == NULL);
2106 file->filename_copy = main_malloc(dlen + 2 + strlen(file->filename)); 2107 file->filename_copy = (char*) main_malloc(dlen + 2 + strlen(file->filename));
2107 2108
2108 strncpy(file->filename_copy, other->filename, dlen); 2109 strncpy(file->filename_copy, other->filename, dlen);
2109 file->filename_copy[dlen] = '/'; 2110 file->filename_copy[dlen] = '/';
@@ -2264,7 +2265,8 @@ main_open_output (xd3_stream *stream, main_file *ofile)
2264static int 2265static int
2265main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *source) 2266main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *source)
2266{ 2267{
2267 int ret = 0, i; 2268 int ret = 0;
2269 usize_t i;
2268 uint8_t *tmp_buf = NULL; 2270 uint8_t *tmp_buf = NULL;
2269 2271
2270 /* Open it, check for seekability, set required xd3_source fields. */ 2272 /* Open it, check for seekability, set required xd3_source fields. */
@@ -2296,7 +2298,7 @@ main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *sour
2296 if (IS_ENCODE (cmd)) 2298 if (IS_ENCODE (cmd))
2297 { 2299 {
2298 usize_t nread; 2300 usize_t nread;
2299 tmp_buf = main_malloc(XD3_ALLOCSIZE); 2301 tmp_buf = (uint8_t*) main_malloc (XD3_ALLOCSIZE);
2300 2302
2301 if ((ret = main_file_read (sfile, tmp_buf, XD3_ALLOCSIZE, 2303 if ((ret = main_file_read (sfile, tmp_buf, XD3_ALLOCSIZE,
2302 & nread, "source read failed"))) 2304 & nread, "source read failed")))
@@ -2386,7 +2388,7 @@ main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *sour
2386 XPR(NT "source block size: %u\n", source->blksize); 2388 XPR(NT "source block size: %u\n", source->blksize);
2387 } 2389 }
2388 2390
2389 if ((lru = main_malloc (sizeof (main_blklru) * lru_size)) == NULL) 2391 if ((lru = (main_blklru*) main_malloc (sizeof (main_blklru) * lru_size)) == NULL)
2390 { 2392 {
2391 ret = ENOMEM; 2393 ret = ENOMEM;
2392 goto error; 2394 goto error;
@@ -2396,7 +2398,7 @@ main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *sour
2396 { 2398 {
2397 lru[i].blkno = (xoff_t) -1; 2399 lru[i].blkno = (xoff_t) -1;
2398 2400
2399 if ((lru[i].blk = main_malloc (source->blksize)) == NULL) 2401 if ((lru[i].blk = (uint8_t*) main_malloc (source->blksize)) == NULL)
2400 { 2402 {
2401 ret = ENOMEM; 2403 ret = ENOMEM;
2402 goto error; 2404 goto error;
@@ -2454,13 +2456,13 @@ main_getblk_func (xd3_stream *stream,
2454 xd3_source *source, 2456 xd3_source *source,
2455 xoff_t blkno) 2457 xoff_t blkno)
2456{ 2458{
2457 xoff_t pos = blkno * source->blksize; 2459 int ret;
2458 main_file *sfile = (main_file*) source->ioh; 2460 xoff_t pos = blkno * source->blksize;
2461 main_file *sfile = (main_file*) source->ioh;
2459 main_blklru *blru = NULL; 2462 main_blklru *blru = NULL;
2460 usize_t onblk = xd3_bytes_on_srcblk_fast (source, blkno); 2463 usize_t onblk = xd3_bytes_on_srcblk_fast (source, blkno);
2461 usize_t nread; 2464 usize_t nread;
2462 int ret; 2465 usize_t i;
2463 int i;
2464 2466
2465 if (allow_fake_source) 2467 if (allow_fake_source)
2466 { 2468 {
@@ -2728,7 +2730,7 @@ main_input (xd3_cmd cmd,
2728 2730
2729 main_set_winsize (ifile); 2731 main_set_winsize (ifile);
2730 2732
2731 if ((main_bdata = main_malloc (option_winsize)) == NULL) 2733 if ((main_bdata = (uint8_t*) main_malloc (option_winsize)) == NULL)
2732 { 2734 {
2733 return EXIT_FAILURE; 2735 return EXIT_FAILURE;
2734 } 2736 }
@@ -3048,7 +3050,7 @@ done:
3048static void 3050static void
3049main_cleanup (void) 3051main_cleanup (void)
3050{ 3052{
3051 int i; 3053 usize_t i;
3052 3054
3053 if (appheader_used != NULL && 3055 if (appheader_used != NULL &&
3054 appheader_used != option_appheader) 3056 appheader_used != option_appheader)
@@ -3105,7 +3107,7 @@ setup_environment (int argc,
3105 return; 3107 return;
3106 } 3108 }
3107 3109
3108 (*env_free) = main_malloc(strlen(v) + 1); 3110 (*env_free) = (char*) main_malloc(strlen(v) + 1);
3109 strcpy(*env_free, v); 3111 strcpy(*env_free, v);
3110 3112
3111 /* Space needed for extra args, at least # of spaces */ 3113 /* Space needed for extra args, at least # of spaces */
@@ -3116,7 +3118,7 @@ setup_environment (int argc,
3116 } 3118 }
3117 } 3119 }
3118 3120
3119 (*argv_free) = main_malloc(sizeof(char*) * (n + 1)); 3121 (*argv_free) = (char**) main_malloc(sizeof(char*) * (n + 1));
3120 (*argv_out) = (*argv_free); 3122 (*argv_out) = (*argv_free);
3121 (*argv_out)[0] = argv[0]; 3123 (*argv_out)[0] = argv[0];
3122 (*argv_out)[n] = NULL; 3124 (*argv_out)[n] = NULL;
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c
index cf2d224..0f739f2 100644
--- a/xdelta3/xdelta3.c
+++ b/xdelta3/xdelta3.c
@@ -455,55 +455,6 @@ XD3_MAKELIST(xd3_rlist, xd3_rinst, link);
455#define IF_BUILD_DEFAULT(x) 455#define IF_BUILD_DEFAULT(x)
456#endif 456#endif
457 457
458IF_BUILD_SOFT(static const xd3_smatcher __smatcher_soft;)
459IF_BUILD_FAST(static const xd3_smatcher __smatcher_fast;)
460IF_BUILD_SLOW(static const xd3_smatcher __smatcher_slow;)
461IF_BUILD_FASTER(static const xd3_smatcher __smatcher_faster;)
462IF_BUILD_FASTEST(static const xd3_smatcher __smatcher_fastest;)
463IF_BUILD_DEFAULT(static const xd3_smatcher __smatcher_default;)
464
465#if XD3_DEBUG
466#define SMALL_HASH_DEBUG1(s,inp) \
467 usize_t debug_hval = xd3_checksum_hash (& (s)->small_hash, \
468 xd3_scksum ((inp), (s)->smatcher.small_look))
469#define SMALL_HASH_DEBUG2(s,inp) \
470 XD3_ASSERT (debug_hval == xd3_checksum_hash (& (s)->small_hash, \
471 xd3_scksum ((inp), (s)->smatcher.small_look)))
472#else
473#define SMALL_HASH_DEBUG1(s,inp)
474#define SMALL_HASH_DEBUG2(s,inp)
475#endif /* XD3_DEBUG */
476
477/* Update the run-length state */
478#define NEXTRUN(c) do { if ((c) == run_c) { run_l += 1; } \
479 else { run_c = (c); run_l = 1; } } while (0)
480
481/* Update the checksum state. */
482#define OLD_LARGE_CKSUM 1
483#if OLD_LARGE_CKSUM
484#define LARGE_CKSUM_UPDATE(cksum,base,look) \
485 do { \
486 uint32_t old_c = PERMUTE((base)[0]); \
487 uint32_t new_c = PERMUTE((base)[(look)]); \
488 uint32_t low = (((cksum) & 0xffff) - old_c + new_c) & 0xffff; \
489 uint32_t high = (((cksum) >> 16) - (old_c * (look)) + low) & 0xffff; \
490 (cksum) = (high << 16) | low; \
491 } while (0)
492#else
493#define LARGE_CKSUM_UPDATE(cksum,base,look) \
494 do { \
495 // linear congruential generators of different
496 // sizes and good lattice structure
497 } while (1)
498#endif
499
500/* Multiply and add hash function */
501#if ARITH_SMALL_CKSUM
502#define SMALL_CKSUM_UPDATE(cksum,base,look) (cksum) = ((*(unsigned long*)(base+1)) * 71143)
503#else
504#define SMALL_CKSUM_UPDATE LARGE_CKSUM_UPDATE
505#endif
506
507/* Consume N bytes of input, only used by the decoder. */ 458/* Consume N bytes of input, only used by the decoder. */
508#define DECODE_INPUT(n) \ 459#define DECODE_INPUT(n) \
509 do { \ 460 do { \
@@ -571,6 +522,37 @@ static int xd3_srcwin_setup (xd3_stream *stream);
571static usize_t xd3_iopt_last_matched (xd3_stream *stream); 522static usize_t xd3_iopt_last_matched (xd3_stream *stream);
572static int xd3_emit_uint32_t (xd3_stream *stream, xd3_output **output, uint32_t num); 523static int xd3_emit_uint32_t (xd3_stream *stream, xd3_output **output, uint32_t num);
573 524
525static usize_t xd3_smatch (xd3_stream *stream,
526 usize_t base,
527 usize_t scksum,
528 usize_t *match_offset);
529static int xd3_string_match_init (xd3_stream *stream);
530static usize_t xd3_scksum (const uint8_t *seg, const int ln);
531static int xd3_comprun (const uint8_t *seg, int slook, uint8_t *run_cp);
532static int xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point);
533
534static int xd3_emit_run (xd3_stream *stream, usize_t pos, usize_t size, uint8_t run_c);
535static usize_t xd3_checksum_hash (const xd3_hash_cfg *cfg, const usize_t cksum);
536static xoff_t xd3_source_cksum_offset(xd3_stream *stream, usize_t low);
537static void xd3_scksum_insert (xd3_stream *stream,
538 usize_t inx,
539 usize_t scksum,
540 usize_t pos);
541
542
543#if XD3_DEBUG
544static void xd3_verify_run_state (xd3_stream *stream,
545 const uint8_t *inp,
546 int x_run_l,
547 uint8_t x_run_c);
548static void xd3_verify_large_state (xd3_stream *stream,
549 const uint8_t *inp,
550 uint32_t x_cksum);
551static void xd3_verify_small_state (xd3_stream *stream,
552 const uint8_t *inp,
553 uint32_t x_cksum);
554
555#endif /* XD3_DEBUG */
574#endif /* XD3_ENCODER */ 556#endif /* XD3_ENCODER */
575 557
576static int xd3_decode_allocate (xd3_stream *stream, usize_t size, 558static int xd3_decode_allocate (xd3_stream *stream, usize_t size,
@@ -734,6 +716,13 @@ static const xd3_sec_type djw_sec_type;
734 716
735/***********************************************************************/ 717/***********************************************************************/
736 718
719#include "xdelta3-hash.h"
720
721/* Process template passes - this includes xdelta3.c several times. */
722#define __XDELTA3_C_TEMPLATE_PASS__
723#include "xdelta3-cfgs.h"
724#undef __XDELTA3_C_TEMPLATE_PASS__
725
737/* Process the inline pass. */ 726/* Process the inline pass. */
738#define __XDELTA3_C_INLINE_PASS__ 727#define __XDELTA3_C_INLINE_PASS__
739#include "xdelta3.c" 728#include "xdelta3.c"
@@ -774,11 +763,6 @@ static const xd3_sec_type djw_sec_type =
774}; 763};
775#endif 764#endif
776 765
777/* Process template passes - this includes xdelta3.c several times. */
778#define __XDELTA3_C_TEMPLATE_PASS__
779#include "xdelta3-cfgs.h"
780#undef __XDELTA3_C_TEMPLATE_PASS__
781
782#if XD3_MAIN || PYTHON_MODULE || SWIG_MODULE || NOT_MAIN 766#if XD3_MAIN || PYTHON_MODULE || SWIG_MODULE || NOT_MAIN
783#include "xdelta3-main.h" 767#include "xdelta3-main.h"
784#endif 768#endif
@@ -859,13 +843,19 @@ struct _xd3_code_table_desc
859 uint8_t same_modes; /* Number of same copy modes (default 3) */ 843 uint8_t same_modes; /* Number of same copy modes (default 3) */
860 uint8_t cpy_sizes; /* Number of immediate-size single copies (default 15) */ 844 uint8_t cpy_sizes; /* Number of immediate-size single copies (default 15) */
861 845
862 uint8_t addcopy_add_max; /* Maximum add size for an add-copy double instruction, all modes (default 4) */ 846 uint8_t addcopy_add_max; /* Maximum add size for an add-copy double instruction,
863 uint8_t addcopy_near_cpy_max; /* Maximum cpy size for an add-copy double instruction, up through VCD_NEAR modes (default 6) */ 847 all modes (default 4) */
864 uint8_t addcopy_same_cpy_max; /* Maximum cpy size for an add-copy double instruction, VCD_SAME modes (default 4) */ 848 uint8_t addcopy_near_cpy_max; /* Maximum cpy size for an add-copy double instruction,
849 up through VCD_NEAR modes (default 6) */
850 uint8_t addcopy_same_cpy_max; /* Maximum cpy size for an add-copy double instruction,
851 VCD_SAME modes (default 4) */
865 852
866 uint8_t copyadd_add_max; /* Maximum add size for a copy-add double instruction, all modes (default 1) */ 853 uint8_t copyadd_add_max; /* Maximum add size for a copy-add double instruction,
867 uint8_t copyadd_near_cpy_max; /* Maximum cpy size for a copy-add double instruction, up through VCD_NEAR modes (default 4) */ 854 all modes (default 1) */
868 uint8_t copyadd_same_cpy_max; /* Maximum cpy size for a copy-add double instruction, VCD_SAME modes (default 4) */ 855 uint8_t copyadd_near_cpy_max; /* Maximum cpy size for a copy-add double instruction,
856 up through VCD_NEAR modes (default 4) */
857 uint8_t copyadd_same_cpy_max; /* Maximum cpy size for a copy-add double instruction,
858 VCD_SAME modes (default 4) */
869 859
870 xd3_code_table_sizes addcopy_max_sizes[MAX_MODES]; 860 xd3_code_table_sizes addcopy_max_sizes[MAX_MODES];
871 xd3_code_table_sizes copyadd_max_sizes[MAX_MODES]; 861 xd3_code_table_sizes copyadd_max_sizes[MAX_MODES];
@@ -940,8 +930,8 @@ static const xd3_code_table_desc __alternate_code_table_desc = {
940static void 930static void
941xd3_build_code_table (const xd3_code_table_desc *desc, xd3_dinst *tbl) 931xd3_build_code_table (const xd3_code_table_desc *desc, xd3_dinst *tbl)
942{ 932{
943 int size1, size2, mode; 933 usize_t size1, size2, mode;
944 int cpy_modes = 2 + desc->near_modes + desc->same_modes; 934 usize_t cpy_modes = 2 + desc->near_modes + desc->same_modes;
945 xd3_dinst *d = tbl; 935 xd3_dinst *d = tbl;
946 936
947 (d++)->type1 = XD3_RUN; 937 (d++)->type1 = XD3_RUN;
@@ -968,7 +958,7 @@ xd3_build_code_table (const xd3_code_table_desc *desc, xd3_dinst *tbl)
968 { 958 {
969 for (size1 = 1; size1 <= desc->addcopy_add_max; size1 += 1) 959 for (size1 = 1; size1 <= desc->addcopy_add_max; size1 += 1)
970 { 960 {
971 int max = (mode < 2 + desc->near_modes) ? 961 usize_t max = (mode < 2U + desc->near_modes) ?
972 desc->addcopy_near_cpy_max : 962 desc->addcopy_near_cpy_max :
973 desc->addcopy_same_cpy_max; 963 desc->addcopy_same_cpy_max;
974 964
@@ -984,7 +974,7 @@ xd3_build_code_table (const xd3_code_table_desc *desc, xd3_dinst *tbl)
984 974
985 for (mode = 0; mode < cpy_modes; mode += 1) 975 for (mode = 0; mode < cpy_modes; mode += 1)
986 { 976 {
987 int max = (mode < 2 + desc->near_modes) ? 977 usize_t max = (mode < 2U + desc->near_modes) ?
988 desc->copyadd_near_cpy_max : 978 desc->copyadd_near_cpy_max :
989 desc->copyadd_same_cpy_max; 979 desc->copyadd_same_cpy_max;
990 980
@@ -1371,7 +1361,8 @@ xd3_apply_table_string (xd3_stream *stream, const uint8_t *code_string)
1371 int modes = TOTAL_MODES (stream); 1361 int modes = TOTAL_MODES (stream);
1372 xd3_dinst *code_table; 1362 xd3_dinst *code_table;
1373 1363
1374 if ((code_table = stream->code_table_alloc = xd3_alloc (stream, sizeof (xd3_dinst), 256)) == NULL) 1364 if ((code_table = stream->code_table_alloc =
1365 (xd3_dinst*) xd3_alloc (stream, sizeof (xd3_dinst), 256)) == NULL)
1375 { 1366 {
1376 return ENOMEM; 1367 return ENOMEM;
1377 } 1368 }
@@ -1493,91 +1484,7 @@ xd3_apply_table_encoding (xd3_stream *in_stream, const uint8_t *data, usize_t si
1493 return ret; 1484 return ret;
1494} 1485}
1495 1486
1496/*********************************************************************** 1487/***********************************************************************/
1497 Permute stuff
1498 ***********************************************************************/
1499
1500#if HASH_PERMUTE == 0
1501#define PERMUTE(x) (x)
1502#else
1503#define PERMUTE(x) (__single_hash[(uint)x])
1504
1505static const uint16_t __single_hash[256] =
1506{
1507 /* Random numbers generated using SLIB's pseudo-random number generator. This hashes
1508 * the input alphabet. */
1509 0xbcd1, 0xbb65, 0x42c2, 0xdffe, 0x9666, 0x431b, 0x8504, 0xeb46,
1510 0x6379, 0xd460, 0xcf14, 0x53cf, 0xdb51, 0xdb08, 0x12c8, 0xf602,
1511 0xe766, 0x2394, 0x250d, 0xdcbb, 0xa678, 0x02af, 0xa5c6, 0x7ea6,
1512 0xb645, 0xcb4d, 0xc44b, 0xe5dc, 0x9fe6, 0x5b5c, 0x35f5, 0x701a,
1513 0x220f, 0x6c38, 0x1a56, 0x4ca3, 0xffc6, 0xb152, 0x8d61, 0x7a58,
1514 0x9025, 0x8b3d, 0xbf0f, 0x95a3, 0xe5f4, 0xc127, 0x3bed, 0x320b,
1515 0xb7f3, 0x6054, 0x333c, 0xd383, 0x8154, 0x5242, 0x4e0d, 0x0a94,
1516 0x7028, 0x8689, 0x3a22, 0x0980, 0x1847, 0xb0f1, 0x9b5c, 0x4176,
1517 0xb858, 0xd542, 0x1f6c, 0x2497, 0x6a5a, 0x9fa9, 0x8c5a, 0x7743,
1518 0xa8a9, 0x9a02, 0x4918, 0x438c, 0xc388, 0x9e2b, 0x4cad, 0x01b6,
1519 0xab19, 0xf777, 0x365f, 0x1eb2, 0x091e, 0x7bf8, 0x7a8e, 0x5227,
1520 0xeab1, 0x2074, 0x4523, 0xe781, 0x01a3, 0x163d, 0x3b2e, 0x287d,
1521 0x5e7f, 0xa063, 0xb134, 0x8fae, 0x5e8e, 0xb7b7, 0x4548, 0x1f5a,
1522 0xfa56, 0x7a24, 0x900f, 0x42dc, 0xcc69, 0x02a0, 0x0b22, 0xdb31,
1523 0x71fe, 0x0c7d, 0x1732, 0x1159, 0xcb09, 0xe1d2, 0x1351, 0x52e9,
1524 0xf536, 0x5a4f, 0xc316, 0x6bf9, 0x8994, 0xb774, 0x5f3e, 0xf6d6,
1525 0x3a61, 0xf82c, 0xcc22, 0x9d06, 0x299c, 0x09e5, 0x1eec, 0x514f,
1526 0x8d53, 0xa650, 0x5c6e, 0xc577, 0x7958, 0x71ac, 0x8916, 0x9b4f,
1527 0x2c09, 0x5211, 0xf6d8, 0xcaaa, 0xf7ef, 0x287f, 0x7a94, 0xab49,
1528 0xfa2c, 0x7222, 0xe457, 0xd71a, 0x00c3, 0x1a76, 0xe98c, 0xc037,
1529 0x8208, 0x5c2d, 0xdfda, 0xe5f5, 0x0b45, 0x15ce, 0x8a7e, 0xfcad,
1530 0xaa2d, 0x4b5c, 0xd42e, 0xb251, 0x907e, 0x9a47, 0xc9a6, 0xd93f,
1531 0x085e, 0x35ce, 0xa153, 0x7e7b, 0x9f0b, 0x25aa, 0x5d9f, 0xc04d,
1532 0x8a0e, 0x2875, 0x4a1c, 0x295f, 0x1393, 0xf760, 0x9178, 0x0f5b,
1533 0xfa7d, 0x83b4, 0x2082, 0x721d, 0x6462, 0x0368, 0x67e2, 0x8624,
1534 0x194d, 0x22f6, 0x78fb, 0x6791, 0xb238, 0xb332, 0x7276, 0xf272,
1535 0x47ec, 0x4504, 0xa961, 0x9fc8, 0x3fdc, 0xb413, 0x007a, 0x0806,
1536 0x7458, 0x95c6, 0xccaa, 0x18d6, 0xe2ae, 0x1b06, 0xf3f6, 0x5050,
1537 0xc8e8, 0xf4ac, 0xc04c, 0xf41c, 0x992f, 0xae44, 0x5f1b, 0x1113,
1538 0x1738, 0xd9a8, 0x19ea, 0x2d33, 0x9698, 0x2fe9, 0x323f, 0xcde2,
1539 0x6d71, 0xe37d, 0xb697, 0x2c4f, 0x4373, 0x9102, 0x075d, 0x8e25,
1540 0x1672, 0xec28, 0x6acb, 0x86cc, 0x186e, 0x9414, 0xd674, 0xd1a5
1541};
1542#endif
1543
1544/***********************************************************************
1545 Ctable stuff
1546 ***********************************************************************/
1547
1548#if HASH_PRIME
1549static const usize_t __primes[] =
1550{
1551 11, 19, 37, 73, 109,
1552 163, 251, 367, 557, 823,
1553 1237, 1861, 2777, 4177, 6247,
1554 9371, 14057, 21089, 31627, 47431,
1555 71143, 106721, 160073, 240101, 360163,
1556 540217, 810343, 1215497, 1823231, 2734867,
1557 4102283, 6153409, 9230113, 13845163, 20767711,
1558 31151543, 46727321, 70090921, 105136301, 157704401,
1559 236556601, 354834919, 532252367, 798378509, 1197567719,
1560 1796351503
1561};
1562
1563static const usize_t __nprimes = SIZEOF_ARRAY (__primes);
1564#endif
1565
1566static inline uint32_t
1567xd3_checksum_hash (const xd3_hash_cfg *cfg, const uint32_t cksum)
1568{
1569#if HASH_PRIME
1570 /* If the table is prime compute the modulus. */
1571 return (cksum % cfg->size);
1572#else
1573 /* If the table is power-of-two compute the mask.*/
1574 return (cksum ^ (cksum >> cfg->shift)) & cfg->mask;
1575#endif
1576}
1577
1578/***********************************************************************
1579 Create the hash table.
1580 ***********************************************************************/
1581 1488
1582static inline void 1489static inline void
1583xd3_swap_uint8p (uint8_t** p1, uint8_t** p2) 1490xd3_swap_uint8p (uint8_t** p1, uint8_t** p2)
@@ -1621,11 +1528,9 @@ xd3_check_pow2 (usize_t value, usize_t *logof)
1621static usize_t 1528static usize_t
1622xd3_pow2_roundup (usize_t x) 1529xd3_pow2_roundup (usize_t x)
1623{ 1530{
1624 int i = 1; 1531 usize_t i = 1;
1625 int s = 0;
1626 while (x > i) { 1532 while (x > i) {
1627 i <<= 1; 1533 i <<= 1;
1628 s++;
1629 } 1534 }
1630 return i; 1535 return i;
1631} 1536}
@@ -1640,106 +1545,6 @@ xd3_round_blksize (usize_t sz, usize_t blksz)
1640 return mod ? (sz + (blksz - mod)) : sz; 1545 return mod ? (sz + (blksz - mod)) : sz;
1641} 1546}
1642 1547
1643#if XD3_ENCODER
1644#if !HASH_PRIME
1645static usize_t
1646xd3_size_log2 (usize_t slots)
1647{
1648 int bits = 28; /* This should not be an unreasonable limit. */
1649 int i;
1650
1651 for (i = 3; i <= bits; i += 1)
1652 {
1653 if (slots < (1 << i))
1654 {
1655 bits = i-1;
1656 break;
1657 }
1658 }
1659
1660 return bits;
1661}
1662#endif
1663
1664static void
1665xd3_size_hashtable (xd3_stream *stream,
1666 usize_t slots,
1667 xd3_hash_cfg *cfg)
1668{
1669 /* initialize ctable: the number of hash buckets is computed from the table of primes or
1670 * the nearest power-of-two, in both cases rounding down in favor of using less
1671 * memory. */
1672
1673#if HASH_PRIME
1674 usize_t i;
1675
1676 cfg->size = __primes[__nprimes-1];
1677
1678 for (i = 1; i < __nprimes; i += 1)
1679 {
1680 if (slots < __primes[i])
1681 {
1682 cfg->size = __primes[i-1];
1683 break;
1684 }
1685 }
1686#else
1687 int bits = xd3_size_log2 (slots);
1688
1689 cfg->size = (1 << bits);
1690 cfg->mask = (cfg->size - 1);
1691 cfg->shift = min (32 - bits, 16);
1692#endif
1693}
1694#endif
1695
1696/***********************************************************************
1697 Cksum function
1698 ***********************************************************************/
1699
1700#if OLD_LARGE_CKSUM
1701static inline uint32_t
1702xd3_lcksum (const uint8_t *seg, const int ln)
1703{
1704 int i = 0;
1705 uint32_t low = 0;
1706 uint32_t high = 0;
1707
1708 for (; i < ln; i += 1)
1709 {
1710 low += PERMUTE(*seg++);
1711 high += low;
1712 }
1713
1714 return ((high & 0xffff) << 16) | (low & 0xffff);
1715}
1716#else
1717static inline int
1718xd3_lcksum (const uint8_t *seg, const int ln)
1719{
1720 int i;
1721 int x = 0;
1722 for (i = 0; i < ln; ++i)
1723 {
1724 x = (x * 103) + *seg++;
1725 }
1726 return x;
1727}
1728#endif
1729
1730#if ARITH_SMALL_CKSUM
1731static inline usize_t
1732xd3_scksum (const uint8_t *seg, const int ln)
1733{
1734 usize_t c;
1735 /* The -1 is because UPDATE operates on seg[1..ln] */
1736 SMALL_CKSUM_UPDATE (c,(seg-1),ln);
1737 return c;
1738}
1739#else
1740#define xd3_scksum(seg,ln) xd3_lcksum(seg,ln)
1741#endif
1742
1743/*********************************************************************** 1548/***********************************************************************
1744 Adler32 stream function: code copied from Zlib, defined in RFC1950 1549 Adler32 stream function: code copied from Zlib, defined in RFC1950
1745 ***********************************************************************/ 1550 ***********************************************************************/
@@ -1792,7 +1597,7 @@ static unsigned long adler32 (unsigned long adler, const uint8_t *buf, usize_t l
1792 Run-length function 1597 Run-length function
1793 ***********************************************************************/ 1598 ***********************************************************************/
1794 1599
1795static inline int 1600static int
1796xd3_comprun (const uint8_t *seg, int slook, uint8_t *run_cp) 1601xd3_comprun (const uint8_t *seg, int slook, uint8_t *run_cp)
1797{ 1602{
1798 int i; 1603 int i;
@@ -2076,10 +1881,10 @@ static int
2076xd3_alloc_cache (xd3_stream *stream) 1881xd3_alloc_cache (xd3_stream *stream)
2077{ 1882{
2078 if (((stream->acache.s_near > 0) && 1883 if (((stream->acache.s_near > 0) &&
2079 (stream->acache.near_array = 1884 (stream->acache.near_array = (usize_t*)
2080 xd3_alloc (stream, stream->acache.s_near, sizeof (usize_t))) == NULL) || 1885 xd3_alloc (stream, stream->acache.s_near, sizeof (usize_t))) == NULL) ||
2081 ((stream->acache.s_same > 0) && 1886 ((stream->acache.s_same > 0) &&
2082 (stream->acache.same_array = 1887 (stream->acache.same_array = (usize_t*)
2083 xd3_alloc (stream, stream->acache.s_same * 256, sizeof (usize_t))) == NULL)) 1888 xd3_alloc (stream, stream->acache.s_same * 256, sizeof (usize_t))) == NULL))
2084 { 1889 {
2085 return ENOMEM; 1890 return ENOMEM;
@@ -2124,7 +1929,7 @@ static int
2124xd3_encode_address (xd3_stream *stream, usize_t addr, usize_t here, uint8_t* mode) 1929xd3_encode_address (xd3_stream *stream, usize_t addr, usize_t here, uint8_t* mode)
2125{ 1930{
2126 usize_t d, bestd; 1931 usize_t d, bestd;
2127 int i, bestm, ret; 1932 usize_t i, bestm, ret;
2128 xd3_addr_cache* acache = & stream->acache; 1933 xd3_addr_cache* acache = & stream->acache;
2129 1934
2130#define SMALLEST_INT(x) do { if (((x) & ~127) == 0) { goto good; } } while (0) 1935#define SMALLEST_INT(x) do { if (((x) & ~127) == 0) { goto good; } } while (0)
@@ -2300,12 +2105,12 @@ xd3_alloc_output (xd3_stream *stream,
2300 } 2105 }
2301 else 2106 else
2302 { 2107 {
2303 if ((output = xd3_alloc (stream, 1, sizeof (xd3_output))) == NULL) 2108 if ((output = (xd3_output*) xd3_alloc (stream, 1, sizeof (xd3_output))) == NULL)
2304 { 2109 {
2305 return NULL; 2110 return NULL;
2306 } 2111 }
2307 2112
2308 if ((base = xd3_alloc (stream, XD3_ALLOCSIZE, sizeof (uint8_t))) == NULL) 2113 if ((base = (uint8_t*) xd3_alloc (stream, XD3_ALLOCSIZE, sizeof (uint8_t))) == NULL)
2309 { 2114 {
2310 xd3_free (stream, output); 2115 xd3_free (stream, output);
2311 return NULL; 2116 return NULL;
@@ -3395,7 +3200,7 @@ xd3_emit_double (xd3_stream *stream, xd3_rinst *first, xd3_rinst *second, uint c
3395 3200
3396/* This enters a potential run instruction into the iopt buffer. The position argument is 3201/* This enters a potential run instruction into the iopt buffer. The position argument is
3397 * relative to the target window. */ 3202 * relative to the target window. */
3398static inline int 3203static int
3399xd3_emit_run (xd3_stream *stream, usize_t pos, usize_t size, uint8_t run_c) 3204xd3_emit_run (xd3_stream *stream, usize_t pos, usize_t size, uint8_t run_c)
3400{ 3205{
3401 xd3_rinst* ri; 3206 xd3_rinst* ri;
@@ -3604,7 +3409,8 @@ xd3_encode_buffer_leftover (xd3_stream *stream)
3604 usize_t room; 3409 usize_t room;
3605 3410
3606 /* Allocate the buffer. */ 3411 /* Allocate the buffer. */
3607 if (stream->buf_in == NULL && (stream->buf_in = xd3_alloc (stream, stream->winsize, 1)) == NULL) 3412 if (stream->buf_in == NULL &&
3413 (stream->buf_in = (uint8_t*) xd3_alloc (stream, stream->winsize, 1)) == NULL)
3608 { 3414 {
3609 return ENOMEM; 3415 return ENOMEM;
3610 } 3416 }
@@ -3659,10 +3465,11 @@ static int
3659xd3_alloc_iopt (xd3_stream *stream, int elts) 3465xd3_alloc_iopt (xd3_stream *stream, int elts)
3660{ 3466{
3661 int i; 3467 int i;
3662 xd3_iopt_buflist* last = xd3_alloc (stream, sizeof (xd3_iopt_buflist), 1); 3468 xd3_iopt_buflist* last =
3469 (xd3_iopt_buflist*) xd3_alloc (stream, sizeof (xd3_iopt_buflist), 1);
3663 3470
3664 if (last == NULL || 3471 if (last == NULL ||
3665 (last->buffer = xd3_alloc (stream, sizeof (xd3_rinst), elts)) == NULL) 3472 (last->buffer = (xd3_rinst*) xd3_alloc (stream, sizeof (xd3_rinst), elts)) == NULL)
3666 { 3473 {
3667 return ENOMEM; 3474 return ENOMEM;
3668 } 3475 }
@@ -4238,7 +4045,8 @@ xd3_string_match_init (xd3_stream *stream)
4238 4045
4239 if (DO_LARGE && stream->large_table == NULL) 4046 if (DO_LARGE && stream->large_table == NULL)
4240 { 4047 {
4241 if ((stream->large_table = xd3_alloc0 (stream, stream->large_hash.size, sizeof (usize_t))) == NULL) 4048 if ((stream->large_table =
4049 (usize_t*) xd3_alloc0 (stream, stream->large_hash.size, sizeof (usize_t))) == NULL)
4242 { 4050 {
4243 return ENOMEM; 4051 return ENOMEM;
4244 } 4052 }
@@ -4262,9 +4070,9 @@ xd3_string_match_init (xd3_stream *stream)
4262 return 0; 4070 return 0;
4263 } 4071 }
4264 4072
4265 if ((stream->small_table = xd3_alloc0 (stream, 4073 if ((stream->small_table = (usize_t*) xd3_alloc0 (stream,
4266 stream->small_hash.size, 4074 stream->small_hash.size,
4267 sizeof (usize_t))) == NULL) 4075 sizeof (usize_t))) == NULL)
4268 { 4076 {
4269 return ENOMEM; 4077 return ENOMEM;
4270 } 4078 }
@@ -4273,9 +4081,9 @@ xd3_string_match_init (xd3_stream *stream)
4273 if (stream->smatcher.small_lchain > 1 || 4081 if (stream->smatcher.small_lchain > 1 ||
4274 stream->smatcher.small_chain > 1) 4082 stream->smatcher.small_chain > 1)
4275 { 4083 {
4276 if ((stream->small_prev = xd3_alloc (stream, 4084 if ((stream->small_prev = (xd3_slist*) xd3_alloc (stream,
4277 stream->sprevsz, 4085 stream->sprevsz,
4278 sizeof (xd3_slist))) == NULL) 4086 sizeof (xd3_slist))) == NULL)
4279 { 4087 {
4280 return ENOMEM; 4088 return ENOMEM;
4281 } 4089 }
@@ -4530,7 +4338,7 @@ static inline usize_t
4530xd3_forward_match(const uint8_t *s1c, 4338xd3_forward_match(const uint8_t *s1c,
4531 const uint8_t *s2c, 4339 const uint8_t *s2c,
4532 usize_t n) { 4340 usize_t n) {
4533 int i = 0; 4341 usize_t i = 0;
4534 while (i < n && s1c[i] == s2c[i]) 4342 while (i < n && s1c[i] == s2c[i])
4535 { 4343 {
4536 i++; 4344 i++;
@@ -5020,7 +4828,7 @@ xd3_srcwin_move_point (xd3_stream *stream, usize_t *next_move_point)
5020 oldpos = blkrem; 4828 oldpos = blkrem;
5021 blkpos = xd3_bytes_on_srcblk_fast (stream->src, blkno); 4829 blkpos = xd3_bytes_on_srcblk_fast (stream->src, blkno);
5022 4830
5023 if (oldpos + stream->smatcher.large_look > blkpos) 4831 if (oldpos + stream->smatcher.large_look > (usize_t) blkpos)
5024 { 4832 {
5025 stream->srcwin_cksum_pos = (blkno + 1) * stream->src->blksize; 4833 stream->srcwin_cksum_pos = (blkno + 1) * stream->src->blksize;
5026 continue; 4834 continue;
@@ -5130,7 +4938,7 @@ XD3_TEMPLATE(xd3_string_match_) (xd3_stream *stream)
5130 usize_t sinx; 4938 usize_t sinx;
5131 usize_t linx; 4939 usize_t linx;
5132 uint8_t run_c; 4940 uint8_t run_c;
5133 int run_l; 4941 size_t run_l;
5134 int ret; 4942 int ret;
5135 usize_t match_length; 4943 usize_t match_length;
5136 usize_t match_offset = 0; 4944 usize_t match_offset = 0;