diff options
Diffstat (limited to 'xdelta3')
-rw-r--r-- | xdelta3/Makefile | 10 | ||||
-rw-r--r-- | xdelta3/setup.py | 1 | ||||
-rw-r--r-- | xdelta3/xdelta3-main.h | 184 | ||||
-rwxr-xr-x | xdelta3/xdelta3-regtest.py | 40 | ||||
-rw-r--r-- | xdelta3/xdelta3-test.h | 14 | ||||
-rwxr-xr-x | xdelta3/xdelta3-test.py | 12 | ||||
-rw-r--r-- | xdelta3/xdelta3.c | 111 | ||||
-rw-r--r-- | xdelta3/xdelta3.h | 4 |
8 files changed, 250 insertions, 126 deletions
diff --git a/xdelta3/Makefile b/xdelta3/Makefile index 21e088a..aa35a4a 100644 --- a/xdelta3/Makefile +++ b/xdelta3/Makefile | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | UNAME = $(shell uname) | 4 | UNAME = $(shell uname) |
5 | CYGWIN = $(findstring CYGWIN, $(UNAME)) | 5 | CYGWIN = $(findstring CYGWIN, $(UNAME)) |
6 | DARWIN = $(findstring Darwin, $(UNAME)) | ||
6 | PYVER = 2.5 | 7 | PYVER = 2.5 |
7 | 8 | ||
8 | ifeq ("$(CYGWIN)", "") | 9 | ifeq ("$(CYGWIN)", "") |
@@ -50,6 +51,7 @@ PYTHON = python | |||
50 | 51 | ||
51 | WIXDIR = "/cygdrive/c/Program Files/wix2.0.4820" | 52 | WIXDIR = "/cygdrive/c/Program Files/wix2.0.4820" |
52 | 53 | ||
54 | # -arch x86_64 | ||
53 | CFLAGS= -Wall -Wshadow -fno-builtin | 55 | CFLAGS= -Wall -Wshadow -fno-builtin |
54 | 56 | ||
55 | # $Format: "REL=$Xdelta3Version$" $ | 57 | # $Format: "REL=$Xdelta3Version$" $ |
@@ -67,7 +69,7 @@ EXTRA = Makefile COPYING linkxd3lib.c badcopy.c xdelta3.swig \ | |||
67 | xdelta3.py xdelta3_wrap.c xdelta3.wxs xdelta3.wxi \ | 69 | xdelta3.py xdelta3_wrap.c xdelta3.wxs xdelta3.wxi \ |
68 | README readme.txt | 70 | README readme.txt |
69 | 71 | ||
70 | SWIG_FLAGS = -DXD3_DEBUG=0 \ | 72 | SWIG_FLAGS = -DXD3_DEBUG=1 \ |
71 | -DEXTERNAL_COMPRESSION=0 \ | 73 | -DEXTERNAL_COMPRESSION=0 \ |
72 | -DXD3_USE_LARGEFILE64=1 \ | 74 | -DXD3_USE_LARGEFILE64=1 \ |
73 | -DGENERIC_ENCODE_TABLES=1 \ | 75 | -DGENERIC_ENCODE_TABLES=1 \ |
@@ -199,11 +201,17 @@ xdelta3module.dll: xdelta3_wrap.o xdelta3.o | |||
199 | -o xdelta3module.dll | 201 | -o xdelta3module.dll |
200 | cp $(SWIGTGT) /usr/lib/python$(PYVER)/site-packages | 202 | cp $(SWIGTGT) /usr/lib/python$(PYVER)/site-packages |
201 | 203 | ||
204 | ifeq ("$(DARWIN)", "") | ||
202 | xdelta3module.so: xdelta3_wrap.o xdelta3.o | 205 | xdelta3module.so: xdelta3_wrap.o xdelta3.o |
203 | ld -shared xdelta3.o xdelta3_wrap.o \ | 206 | ld -shared xdelta3.o xdelta3_wrap.o \ |
204 | -o xdelta3module.so \ | 207 | -o xdelta3module.so \ |
205 | /usr/lib/libpython$(PYVER).so \ | 208 | /usr/lib/libpython$(PYVER).so \ |
206 | -lc | 209 | -lc |
210 | else | ||
211 | xdelta3module.so: xdelta3_wrap.o xdelta3.o | ||
212 | gcc -Wl,-F. -bundle -undefined dynamic_lookup $(CFLAGS) \ | ||
213 | xdelta3.o xdelta3_wrap.o -o xdelta3module.so | ||
214 | endif | ||
207 | 215 | ||
208 | xdelta3-decoder: $(SOURCES) | 216 | xdelta3-decoder: $(SOURCES) |
209 | $(CC) -O3 -Wall -Wshadow xdelta3.c \ | 217 | $(CC) -O3 -Wall -Wshadow xdelta3.c \ |
diff --git a/xdelta3/setup.py b/xdelta3/setup.py index b2c9022..edcb1fd 100644 --- a/xdelta3/setup.py +++ b/xdelta3/setup.py | |||
@@ -46,6 +46,7 @@ xdelta3_ext = Extension('xdelta3main', | |||
46 | extra_compile_args = [ '-O3', | 46 | extra_compile_args = [ '-O3', |
47 | '-g', | 47 | '-g', |
48 | '-fno-builtin', | 48 | '-fno-builtin', |
49 | # '-arch', 'x86_64', | ||
49 | ]) | 50 | ]) |
50 | 51 | ||
51 | # $Format: "REL='$Xdelta3Version$'" $ | 52 | # $Format: "REL='$Xdelta3Version$'" $ |
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h index 8848ed4..db4c011 100644 --- a/xdelta3/xdelta3-main.h +++ b/xdelta3/xdelta3-main.h | |||
@@ -1538,7 +1538,7 @@ main_recode_func (xd3_stream* stream, main_file *ofile) | |||
1538 | option_appheader != NULL) | 1538 | option_appheader != NULL) |
1539 | { | 1539 | { |
1540 | xd3_set_appheader (recode_stream, option_appheader, | 1540 | xd3_set_appheader (recode_stream, option_appheader, |
1541 | strlen (option_appheader)); | 1541 | strlen ((char*) option_appheader)); |
1542 | } | 1542 | } |
1543 | else if (option_use_appheader != 0 && | 1543 | else if (option_use_appheader != 0 && |
1544 | option_appheader == NULL) | 1544 | option_appheader == NULL) |
@@ -1619,7 +1619,7 @@ main_init_recode_stream (void) | |||
1619 | 1619 | ||
1620 | if ((ret = main_set_secondary_flags (&recode_config)) || | 1620 | if ((ret = main_set_secondary_flags (&recode_config)) || |
1621 | (ret = xd3_config_stream (recode_stream, &recode_config)) || | 1621 | (ret = xd3_config_stream (recode_stream, &recode_config)) || |
1622 | (ret = xd3_encode_init_buffers (recode_stream))) | 1622 | (ret = xd3_encode_init_partial (recode_stream))) |
1623 | { | 1623 | { |
1624 | XPR(NT XD3_LIB_ERRMSG (recode_stream, ret)); | 1624 | XPR(NT XD3_LIB_ERRMSG (recode_stream, ret)); |
1625 | xd3_free_stream (recode_stream); | 1625 | xd3_free_stream (recode_stream); |
@@ -1706,47 +1706,141 @@ main_merge_func (xd3_stream* stream, main_file *no_write) | |||
1706 | return 0; | 1706 | return 0; |
1707 | } | 1707 | } |
1708 | 1708 | ||
1709 | |||
1710 | #define MERGE_IN_PROGRESS 0 | ||
1709 | #if MERGE_IN_PROGRESS | 1711 | #if MERGE_IN_PROGRESS |
1710 | /* This is called after all windows have been read, as a final step in | 1712 | /* This is called after all windows have been read, as a final step in |
1711 | * main_input(). This is only called for the final merge step. */ | 1713 | * main_input(). This is only called for the final merge step. */ |
1712 | static int | 1714 | static int |
1713 | main_merge_output (xd3_stream *stream) | 1715 | main_merge_output (xd3_stream *stream, main_file *ofile) |
1714 | { | 1716 | { |
1715 | int inst_pos = 0; | 1717 | int ret; |
1718 | usize_t inst_pos = 0; | ||
1716 | xoff_t output_pos = 0; | 1719 | xoff_t output_pos = 0; |
1717 | usize_t window_pos = 0; | 1720 | xd3_source recode_source; |
1721 | |||
1722 | /* Enter the ENC_INPUT state and bypass the next_in == NULL test | ||
1723 | * and (leftover) input buffering logic. */ | ||
1724 | XD3_ASSERT(recode_stream->enc_state == ENC_INIT); | ||
1725 | recode_stream->enc_state = ENC_INPUT; | ||
1726 | recode_stream->next_in = main_bdata; | ||
1727 | recode_stream->flags |= XD3_FLUSH; | ||
1718 | 1728 | ||
1719 | while (output_pos < option_winsize) | 1729 | while (inst_pos < stream->whole_target_instlen) |
1720 | { | 1730 | { |
1721 | xd3_winst *inst = &stream->whole_target_inst[inst_pos]; | 1731 | xoff_t window_srcmin = XOFF_T_MAX; |
1722 | usize_t take = min(inst->size, option_winsize - output_pos); | 1732 | xoff_t window_srcmax = 0; |
1733 | usize_t window_pos = 0; | ||
1723 | 1734 | ||
1724 | switch (inst->type) | 1735 | XD3_ASSERT (recode_stream->enc_state == ENC_INPUT); |
1725 | { | 1736 | |
1726 | case XD3_RUN: | 1737 | if ((ret = xd3_encode_input (recode_stream)) != XD3_WINSTART) |
1727 | if ((ret = xd3_emit_run (recode_stream, window_pos, take, | 1738 | { |
1728 | stream->whole_target_adds[inst->addr]))) | 1739 | XPR(NT "invalid merge state: %s\n", xd3_mainerror (ret)); |
1729 | { | 1740 | return XD3_INVALID; |
1730 | return ret; | 1741 | } |
1731 | } | 1742 | |
1732 | break; | 1743 | /* TODO: The inner loop termination condition can be used to |
1733 | 1744 | * change window sizes, however keeping the last delta in the | |
1734 | case XD3_ADD: | 1745 | * chain's window size allows re-using its adler32 checksums. |
1735 | /* Adds are implicit, put them into the input buffer. */ | 1746 | * For now this will change window size and not use adler32. */ |
1736 | memcpy (main_bdata, stream->whole_target_adds + inst->addr, take); | 1747 | while (window_pos < option_winsize && |
1737 | break; | 1748 | inst_pos < stream->whole_target_instlen) |
1738 | 1749 | { | |
1739 | default: /* XD3_COPY + mode */ | 1750 | xd3_winst *inst = &stream->whole_target_inst[inst_pos]; |
1740 | if ((ret = xd3_found_match (stream, window_pos, take, inst->addr, | 1751 | usize_t take = min(inst->size, option_winsize - window_pos); |
1741 | IS_SOURCE))) | ||
1742 | { | ||
1743 | return ret; | ||
1744 | } | ||
1745 | break; | ||
1746 | } | ||
1747 | 1752 | ||
1748 | //xd3_avail_input (recode_stream, main_bdata, | 1753 | switch (inst->type) |
1754 | { | ||
1755 | case XD3_RUN: | ||
1756 | if ((ret = xd3_emit_run (recode_stream, window_pos, take, | ||
1757 | stream->whole_target_adds[inst->addr]))) | ||
1758 | { | ||
1759 | return ret; | ||
1760 | } | ||
1761 | break; | ||
1762 | |||
1763 | case XD3_ADD: | ||
1764 | /* Adds are implicit, put them into the input buffer. */ | ||
1765 | memcpy (main_bdata + window_pos, | ||
1766 | stream->whole_target_adds + inst->addr, take); | ||
1767 | break; | ||
1768 | |||
1769 | default: /* XD3_COPY + copy mode */ | ||
1770 | window_srcmin = min(window_srcmin, inst->addr); | ||
1771 | window_srcmax = max(window_srcmax, inst->addr + take); | ||
1772 | if ((ret = xd3_found_match (recode_stream, window_pos, take, inst->addr, | ||
1773 | inst->mode == VCD_SOURCE))) | ||
1774 | { | ||
1775 | return ret; | ||
1776 | } | ||
1777 | break; | ||
1778 | } | ||
1779 | |||
1780 | window_pos += take; | ||
1781 | output_pos += take; | ||
1782 | |||
1783 | if (take == inst->size) | ||
1784 | { | ||
1785 | inst_pos += 1; | ||
1786 | } | ||
1787 | else | ||
1788 | { | ||
1789 | /* Modify the instruction for the next pass. */ | ||
1790 | /* TODO: this seems to be broken, as initial testing indicates. */ | ||
1791 | if (inst->type != XD3_RUN) | ||
1792 | { | ||
1793 | inst->addr += take; | ||
1794 | } | ||
1795 | inst->size -= take; | ||
1796 | } | ||
1797 | } | ||
1798 | |||
1799 | xd3_avail_input (recode_stream, main_bdata, window_pos); | ||
1800 | |||
1801 | recode_stream->enc_state = ENC_INSTR; | ||
1802 | recode_stream->srcwin_decided = 1; | ||
1803 | recode_stream->src = &recode_source; | ||
1804 | recode_source.srclen = window_srcmax - window_srcmin; | ||
1805 | recode_source.srcbase = window_srcmin; | ||
1806 | recode_stream->taroff = recode_source.srclen; | ||
1807 | |||
1808 | for (;;) | ||
1809 | { | ||
1810 | switch ((ret = xd3_encode_input (recode_stream))) | ||
1811 | { | ||
1812 | case XD3_INPUT: { | ||
1813 | goto done_window; | ||
1814 | } | ||
1815 | case XD3_OUTPUT: { | ||
1816 | /* main_file_write below */ | ||
1817 | break; | ||
1818 | } | ||
1819 | case XD3_GOTHEADER: | ||
1820 | case XD3_WINSTART: | ||
1821 | case XD3_WINFINISH: { | ||
1822 | /* ignore */ | ||
1823 | continue; | ||
1824 | } | ||
1825 | case XD3_GETSRCBLK: | ||
1826 | case 0: { | ||
1827 | return XD3_INTERNAL; | ||
1828 | } | ||
1829 | default: | ||
1830 | return ret; | ||
1831 | } | ||
1832 | |||
1833 | if ((ret = main_write_output(recode_stream, ofile))) | ||
1834 | { | ||
1835 | return ret; | ||
1836 | } | ||
1837 | |||
1838 | xd3_consume_output (recode_stream); | ||
1839 | } | ||
1840 | done_window: | ||
1841 | (void) 0; | ||
1749 | } | 1842 | } |
1843 | |||
1750 | return 0; | 1844 | return 0; |
1751 | } | 1845 | } |
1752 | #endif | 1846 | #endif |
@@ -3158,7 +3252,7 @@ main_input (xd3_cmd cmd, | |||
3158 | 3252 | ||
3159 | /* Check if the user expected a source to be required although | 3253 | /* Check if the user expected a source to be required although |
3160 | * it was not. */ | 3254 | * it was not. */ |
3161 | if (have_src && ! need_src && ! option_quiet) | 3255 | if (have_src && ! need_src && option_verbose) |
3162 | { | 3256 | { |
3163 | XPR(NT "warning: output window %"Q"u does not " | 3257 | XPR(NT "warning: output window %"Q"u does not " |
3164 | "copy source\n", stream.current_window); | 3258 | "copy source\n", stream.current_window); |
@@ -3244,7 +3338,7 @@ main_input (xd3_cmd cmd, | |||
3244 | main_file_isopen (sfile)) | 3338 | main_file_isopen (sfile)) |
3245 | { | 3339 | { |
3246 | /* Warn when no source copies are found */ | 3340 | /* Warn when no source copies are found */ |
3247 | if (! xd3_encoder_used_source (& stream)) | 3341 | if (option_verbose && ! xd3_encoder_used_source (& stream)) |
3248 | { | 3342 | { |
3249 | XPR(NT "warning: input window %"Q"u..%"Q"u has " | 3343 | XPR(NT "warning: input window %"Q"u..%"Q"u has " |
3250 | "no source copies\n", | 3344 | "no source copies\n", |
@@ -3321,6 +3415,14 @@ done: | |||
3321 | main_file_close (sfile); | 3415 | main_file_close (sfile); |
3322 | } | 3416 | } |
3323 | 3417 | ||
3418 | #if MERGE_IN_PROGRESS | ||
3419 | if (cmd == CMD_MERGE && | ||
3420 | (ret = main_merge_output (& stream, ofile))) | ||
3421 | { | ||
3422 | return EXIT_FAILURE; | ||
3423 | } | ||
3424 | #endif | ||
3425 | |||
3324 | /* If output file is not open yet because of delayed-open, it means | 3426 | /* If output file is not open yet because of delayed-open, it means |
3325 | * we never encountered a window in the delta, but it could have had | 3427 | * we never encountered a window in the delta, but it could have had |
3326 | * a VCDIFF header? TODO: solve this elsewhere. For now, it prints | 3428 | * a VCDIFF header? TODO: solve this elsewhere. For now, it prints |
@@ -3350,14 +3452,6 @@ done: | |||
3350 | } | 3452 | } |
3351 | #endif | 3453 | #endif |
3352 | 3454 | ||
3353 | #if MERGE_IN_PROGRESS | ||
3354 | if (cmd == CMD_MERGE && | ||
3355 | (ret = main_merge_output (& stream))) | ||
3356 | { | ||
3357 | return EXIT_FAILURE; | ||
3358 | } | ||
3359 | #endif | ||
3360 | |||
3361 | if ((ret = xd3_close_stream (& stream))) | 3455 | if ((ret = xd3_close_stream (& stream))) |
3362 | { | 3456 | { |
3363 | XPR(NT XD3_LIB_ERRMSG (& stream, ret)); | 3457 | XPR(NT XD3_LIB_ERRMSG (& stream, ret)); |
@@ -3659,8 +3753,10 @@ main (int argc, char **argv) | |||
3659 | else if (strcmp (my_optstr, "printdelta") == 0) | 3753 | else if (strcmp (my_optstr, "printdelta") == 0) |
3660 | { cmd = CMD_PRINTDELTA; } | 3754 | { cmd = CMD_PRINTDELTA; } |
3661 | else if (strcmp (my_optstr, "recode") == 0) { cmd = CMD_RECODE; } | 3755 | else if (strcmp (my_optstr, "recode") == 0) { cmd = CMD_RECODE; } |
3756 | #if MERGE_IN_PROGRESS | ||
3662 | else if (strcmp (my_optstr, "merge") == 0) { cmd = CMD_MERGE; } | 3757 | else if (strcmp (my_optstr, "merge") == 0) { cmd = CMD_MERGE; } |
3663 | #endif | 3758 | #endif |
3759 | #endif | ||
3664 | 3760 | ||
3665 | /* If no option was found and still no command, let the default | 3761 | /* If no option was found and still no command, let the default |
3666 | * command be encode. The remaining args are treated as | 3762 | * command be encode. The remaining args are treated as |
@@ -3778,6 +3874,7 @@ main (int argc, char **argv) | |||
3778 | 3874 | ||
3779 | sfilename = my_optarg; | 3875 | sfilename = my_optarg; |
3780 | break; | 3876 | break; |
3877 | #if MERGE_IN_PROGRESS | ||
3781 | case 'm': | 3878 | case 'm': |
3782 | if ((merge = (main_merge*) | 3879 | if ((merge = (main_merge*) |
3783 | main_malloc (sizeof (main_merge))) == NULL) | 3880 | main_malloc (sizeof (main_merge))) == NULL) |
@@ -3787,7 +3884,7 @@ main (int argc, char **argv) | |||
3787 | main_merge_list_push_back (& merge_order, merge); | 3884 | main_merge_list_push_back (& merge_order, merge); |
3788 | merge->filename = my_optarg; | 3885 | merge->filename = my_optarg; |
3789 | break; | 3886 | break; |
3790 | 3887 | #endif | |
3791 | case 'V': | 3888 | case 'V': |
3792 | ret = main_version (); goto exit; | 3889 | ret = main_version (); goto exit; |
3793 | default: | 3890 | default: |
@@ -3902,7 +3999,6 @@ main (int argc, char **argv) | |||
3902 | 3999 | ||
3903 | while (! main_merge_list_empty (& merge_order)) | 4000 | while (! main_merge_list_empty (& merge_order)) |
3904 | { | 4001 | { |
3905 | /* TODO: More merge cleanup, once implemented. */ | ||
3906 | merge = main_merge_list_pop_front (& merge_order); | 4002 | merge = main_merge_list_pop_front (& merge_order); |
3907 | main_free (merge); | 4003 | main_free (merge); |
3908 | } | 4004 | } |
diff --git a/xdelta3/xdelta3-regtest.py b/xdelta3/xdelta3-regtest.py index e86c621..f9a11bd 100755 --- a/xdelta3/xdelta3-regtest.py +++ b/xdelta3/xdelta3-regtest.py | |||
@@ -1,6 +1,6 @@ | |||
1 | #!/usr/bin/python2.5 | 1 | #!/usr/bin/python2.5 |
2 | # xdelta 3 - delta compression tools and library | 2 | # xdelta 3 - delta compression tools and library |
3 | # Copyright (C) 2003, 2006, 2007. Joshua P. MacDonald | 3 | # Copyright (C) 2003, 2006, 2007, 2008. Joshua P. MacDonald |
4 | # | 4 | # |
5 | # This program is free software; you can redistribute it and/or modify | 5 | # This program is free software; you can redistribute it and/or modify |
6 | # it under the terms of the GNU General Public License as published by | 6 | # it under the terms of the GNU General Public License as published by |
@@ -19,7 +19,6 @@ | |||
19 | # TODO: test 1.5 vs. greedy | 19 | # TODO: test 1.5 vs. greedy |
20 | 20 | ||
21 | import os, sys, math, re, time, types, array, random | 21 | import os, sys, math, re, time, types, array, random |
22 | import xdelta3main | ||
23 | import xdelta3 | 22 | import xdelta3 |
24 | 23 | ||
25 | #RCSDIR = '/mnt/polaroid/Polaroid/orbit_linux/home/jmacd/PRCS' | 24 | #RCSDIR = '/mnt/polaroid/Polaroid/orbit_linux/home/jmacd/PRCS' |
@@ -27,7 +26,10 @@ import xdelta3 | |||
27 | #SAMPLEDIR = "/tmp/WESNOTH_tmp/diff" | 26 | #SAMPLEDIR = "/tmp/WESNOTH_tmp/diff" |
28 | 27 | ||
29 | #RCSDIR = 'G:/jmacd/PRCS_copy' | 28 | #RCSDIR = 'G:/jmacd/PRCS_copy' |
30 | SAMPLEDIR = "C:/sample_data/Wesnoth/tar" | 29 | #SAMPLEDIR = "C:/sample_data/Wesnoth/tar" |
30 | |||
31 | #RCSDIR = '/Users/jmacd/src/ftp.kernel.org/pub/scm/linux/kernel/bkcvs/linux-2.4/net/x25' | ||
32 | RCSDIR = '/Users/jmacd/src/ftp.kernel.org' | ||
31 | 33 | ||
32 | # | 34 | # |
33 | MIN_SIZE = 0 | 35 | MIN_SIZE = 0 |
@@ -38,8 +40,6 @@ SKIP_TRIALS = 2 | |||
38 | MIN_TRIALS = 3 | 40 | MIN_TRIALS = 3 |
39 | MAX_TRIALS = 15 | 41 | MAX_TRIALS = 15 |
40 | 42 | ||
41 | SKIP_DECODE = 1 | ||
42 | |||
43 | # 10 = fast 1.5 = slow | 43 | # 10 = fast 1.5 = slow |
44 | MIN_STDDEV_PCT = 1.5 | 44 | MIN_STDDEV_PCT = 1.5 |
45 | 45 | ||
@@ -57,7 +57,7 @@ MAX_RUN = 1000 * 1000 * 10 | |||
57 | 57 | ||
58 | # Testwide defaults | 58 | # Testwide defaults |
59 | ALL_ARGS = [ | 59 | ALL_ARGS = [ |
60 | # -v | 60 | '-vv' |
61 | ] | 61 | ] |
62 | 62 | ||
63 | # The first 7 args go to -C | 63 | # The first 7 args go to -C |
@@ -231,11 +231,6 @@ class TimedTest: | |||
231 | lambda x: x.Encode(self.target, self.source, DFILE)) | 231 | lambda x: x.Encode(self.target, self.source, DFILE)) |
232 | self.encode_size = runnable.EncodeSize(DFILE) | 232 | self.encode_size = runnable.EncodeSize(DFILE) |
233 | 233 | ||
234 | if SKIP_DECODE: | ||
235 | self.decode_time = StatList([1, 1], 'not decoded') | ||
236 | return | ||
237 | #end | ||
238 | |||
239 | self.decode_time = self.DoTest(RFILE, | 234 | self.decode_time = self.DoTest(RFILE, |
240 | lambda x: x.Decode(DFILE, self.source, RFILE), | 235 | lambda x: x.Decode(DFILE, self.source, RFILE), |
241 | ) | 236 | ) |
@@ -404,9 +399,10 @@ class Xdelta3Runner: | |||
404 | 399 | ||
405 | def Main(self, args): | 400 | def Main(self, args): |
406 | try: | 401 | try: |
407 | xdelta3main.main(args) | 402 | #print 'Run %s' % (' '.join(args)) |
403 | xdelta3.xd3_main_cmdline(args) | ||
408 | except Exception, e: | 404 | except Exception, e: |
409 | raise CommandError(args, "xdelta3.main exception") | 405 | raise CommandError(args, "xdelta3.main exception: %s" % e) |
410 | #end | 406 | #end |
411 | #end | 407 | #end |
412 | #end | 408 | #end |
@@ -904,10 +900,7 @@ class RandomTest: | |||
904 | #end | 900 | #end |
905 | 901 | ||
906 | def __str__(self): | 902 | def __str__(self): |
907 | decodestr = '' | 903 | decodestr = ' %.6f' % self.decodetime |
908 | if not SKIP_DECODE: | ||
909 | decodestr = ' %.6f' % self.decodetime | ||
910 | #end | ||
911 | return 'time %.6f%s size %d%s << %s >>%s' % ( | 904 | return 'time %.6f%s size %d%s << %s >>%s' % ( |
912 | self.time(), ((self.time_pos != None) and (" (%s)" % self.time_pos) or ""), | 905 | self.time(), ((self.time_pos != None) and (" (%s)" % self.time_pos) or ""), |
913 | self.size(), ((self.size_pos != None) and (" (%s)" % self.size_pos) or ""), | 906 | self.size(), ((self.size_pos != None) and (" (%s)" % self.size_pos) or ""), |
@@ -1202,19 +1195,20 @@ if __name__ == "__main__": | |||
1202 | RunCommand(['rm', '-rf', TMPDIR]) | 1195 | RunCommand(['rm', '-rf', TMPDIR]) |
1203 | os.mkdir(TMPDIR) | 1196 | os.mkdir(TMPDIR) |
1204 | 1197 | ||
1205 | #rcsf = GetTestRcsFiles() | 1198 | rcsf = GetTestRcsFiles() |
1206 | #generator = rcsf.Generator() | 1199 | #generator = rcsf.Generator() |
1207 | 1200 | ||
1208 | sample = SampleDataTest([SAMPLEDIR]) | 1201 | #sample = SampleDataTest([SAMPLEDIR]) |
1209 | generator = sample.Generator() | 1202 | #generator = sample.Generator() |
1210 | 1203 | ||
1211 | rand = random.Random(135135135135135) | 1204 | #rand = random.Random(135135135135135) |
1212 | RunTestLoop(rand, generator, TEST_ROUNDS) | 1205 | #RunTestLoop(rand, generator, TEST_ROUNDS) |
1213 | 1206 | ||
1214 | #RunSpeedTest() | 1207 | #RunSpeedTest() |
1215 | 1208 | ||
1216 | #x3r = rcsf.AllPairsByDate(Xdelta3RunClass(['-9'])) | 1209 | #x3r = rcsf.AllPairsByDate(Xdelta3RunClass(['-9'])) |
1217 | #x3r = rcsf.AllPairsByDate(Xdelta3RunClass(['-9', '-S', 'djw'])) | 1210 | x3r = rcsf.AllPairsByDate(Xdelta3RunClass(['-9', '-S', 'djw'])) |
1211 | x3r = rcsf.AllPairsByDate(Xdelta3RunClass(['-1', '-S', 'djw'])) | ||
1218 | #x3r = rcsf.AllPairsByDate(Xdelta3RunClass(['-9', '-T'])) | 1212 | #x3r = rcsf.AllPairsByDate(Xdelta3RunClass(['-9', '-T'])) |
1219 | 1213 | ||
1220 | #x1r = rcsf.AllPairsByDate(Xdelta1RunClass()) | 1214 | #x1r = rcsf.AllPairsByDate(Xdelta1RunClass()) |
diff --git a/xdelta3/xdelta3-test.h b/xdelta3/xdelta3-test.h index 281d1b6..5389d57 100644 --- a/xdelta3/xdelta3-test.h +++ b/xdelta3/xdelta3-test.h | |||
@@ -576,7 +576,7 @@ static int | |||
576 | test_forward_match (xd3_stream *stream, int unused) | 576 | test_forward_match (xd3_stream *stream, int unused) |
577 | { | 577 | { |
578 | int i; | 578 | int i; |
579 | char buf1[256], buf2[256]; | 579 | uint8_t buf1[256], buf2[256]; |
580 | 580 | ||
581 | memset(buf1, 0, 256); | 581 | memset(buf1, 0, 256); |
582 | memset(buf2, 0, 256); | 582 | memset(buf2, 0, 256); |
@@ -615,7 +615,7 @@ test_address_cache (xd3_stream *stream, int unused) | |||
615 | stream->acache.s_near = stream->code_table_desc->near_modes; | 615 | stream->acache.s_near = stream->code_table_desc->near_modes; |
616 | stream->acache.s_same = stream->code_table_desc->same_modes; | 616 | stream->acache.s_same = stream->code_table_desc->same_modes; |
617 | 617 | ||
618 | if ((ret = xd3_encode_init (stream))) { return ret; } | 618 | if ((ret = xd3_encode_init_partial (stream))) { return ret; } |
619 | 619 | ||
620 | addrs = xd3_alloc (stream, sizeof (usize_t), ADDR_CACHE_ROUNDS); | 620 | addrs = xd3_alloc (stream, sizeof (usize_t), ADDR_CACHE_ROUNDS); |
621 | modes = xd3_alloc (stream, sizeof (uint8_t), ADDR_CACHE_ROUNDS); | 621 | modes = xd3_alloc (stream, sizeof (uint8_t), ADDR_CACHE_ROUNDS); |
@@ -758,7 +758,7 @@ test_compress_text (xd3_stream *stream, | |||
758 | 758 | ||
759 | (*encoded_size) = 0; | 759 | (*encoded_size) = 0; |
760 | 760 | ||
761 | xd3_set_appheader (stream, test_apphead, strlen (test_apphead)); | 761 | xd3_set_appheader (stream, test_apphead, strlen ((char*) test_apphead)); |
762 | 762 | ||
763 | if ((ret = xd3_encode_stream (stream, test_text, sizeof (test_text), | 763 | if ((ret = xd3_encode_stream (stream, test_text, sizeof (test_text), |
764 | encoded, encoded_size, 4*sizeof (test_text)))) { goto fail; } | 764 | encoded, encoded_size, 4*sizeof (test_text)))) { goto fail; } |
@@ -830,8 +830,8 @@ test_decompress_text (xd3_stream *stream, uint8_t *enc, usize_t enc_size, usize_ | |||
830 | 830 | ||
831 | if ((ret = xd3_get_appheader (stream, & apphead, & apphead_size))) { goto fail; } | 831 | if ((ret = xd3_get_appheader (stream, & apphead, & apphead_size))) { goto fail; } |
832 | 832 | ||
833 | if (apphead_size != strlen (test_apphead) || | 833 | if (apphead_size != strlen ((char*) test_apphead) || |
834 | memcmp (apphead, test_apphead, strlen (test_apphead)) != 0) | 834 | memcmp (apphead, test_apphead, strlen ((char*) test_apphead)) != 0) |
835 | { | 835 | { |
836 | stream->msg = "incorrect appheader"; | 836 | stream->msg = "incorrect appheader"; |
837 | ret = XD3_INTERNAL; | 837 | ret = XD3_INTERNAL; |
@@ -2459,7 +2459,7 @@ test_string_matching (xd3_stream *stream, int ignore) | |||
2459 | config.smatcher_soft.long_enough = 10; | 2459 | config.smatcher_soft.long_enough = 10; |
2460 | 2460 | ||
2461 | if ((ret = xd3_config_stream (stream, & config))) { return ret; } | 2461 | if ((ret = xd3_config_stream (stream, & config))) { return ret; } |
2462 | if ((ret = xd3_encode_init (stream))) { return ret; } | 2462 | if ((ret = xd3_encode_init_full (stream))) { return ret; } |
2463 | 2463 | ||
2464 | xd3_avail_input (stream, (uint8_t*)test->input, len); | 2464 | xd3_avail_input (stream, (uint8_t*)test->input, len); |
2465 | 2465 | ||
@@ -2686,7 +2686,7 @@ xd3_selftest (void) | |||
2686 | #ifndef WIN32 | 2686 | #ifndef WIN32 |
2687 | if (getuid() == 0) | 2687 | if (getuid() == 0) |
2688 | { | 2688 | { |
2689 | DP(RINT "This test should not be run as root.\n"); | 2689 | DP(RINT "xdelta3: This test should not be run as root.\n"); |
2690 | ret = XD3_INVALID; | 2690 | ret = XD3_INVALID; |
2691 | goto failure; | 2691 | goto failure; |
2692 | } | 2692 | } |
diff --git a/xdelta3/xdelta3-test.py b/xdelta3/xdelta3-test.py index 2c37030..7fcc3d5 100755 --- a/xdelta3/xdelta3-test.py +++ b/xdelta3/xdelta3-test.py | |||
@@ -1,4 +1,4 @@ | |||
1 | #!/usr/bin/python2.4 | 1 | #!/usr/bin/python2.5 |
2 | # xdelta 3 - delta compression tools and library | 2 | # xdelta 3 - delta compression tools and library |
3 | # Copyright (C) 2003, 2006, 2007. Joshua P. MacDonald | 3 | # Copyright (C) 2003, 2006, 2007. Joshua P. MacDonald |
4 | # | 4 | # |
@@ -142,6 +142,14 @@ assert result1 == 0 and result9 == 0 | |||
142 | assert len(level1) > len(level9) | 142 | assert len(level1) > len(level9) |
143 | 143 | ||
144 | # | 144 | # |
145 | # | 145 | # Issue 65 |
146 | print 'encode: 65 ...' | ||
147 | source = 'Hello World' | ||
148 | target = 'Hello everyone' | ||
149 | result, patch = xdelta3.xd3_encode_memory(target, source, len(target)) | ||
150 | assert result != 0 | ||
151 | |||
152 | result, patch = xdelta3.xd3_encode_memory(target, source, 2 * len(target)) | ||
153 | assert result == 0 | ||
146 | 154 | ||
147 | print 'PASS' | 155 | print 'PASS' |
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index 1800c90..7e798bd 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -1908,6 +1908,16 @@ xd3_sizeof_uint64_t (uint64_t num) | |||
1908 | static int | 1908 | static int |
1909 | xd3_alloc_cache (xd3_stream *stream) | 1909 | xd3_alloc_cache (xd3_stream *stream) |
1910 | { | 1910 | { |
1911 | if (stream->acache.near_array != NULL) | ||
1912 | { | ||
1913 | xd3_free (stream, stream->acache.near_array); | ||
1914 | } | ||
1915 | |||
1916 | if (stream->acache.same_array != NULL) | ||
1917 | { | ||
1918 | xd3_free (stream, stream->acache.same_array); | ||
1919 | } | ||
1920 | |||
1911 | if (((stream->acache.s_near > 0) && | 1921 | if (((stream->acache.s_near > 0) && |
1912 | (stream->acache.near_array = (usize_t*) | 1922 | (stream->acache.near_array = (usize_t*) |
1913 | xd3_alloc (stream, stream->acache.s_near, sizeof (usize_t))) | 1923 | xd3_alloc (stream, stream->acache.s_near, sizeof (usize_t))) |
@@ -2087,6 +2097,8 @@ xd3_alloc (xd3_stream *stream, | |||
2087 | if (a != NULL) | 2097 | if (a != NULL) |
2088 | { | 2098 | { |
2089 | IF_DEBUG (stream->alloc_cnt += 1); | 2099 | IF_DEBUG (stream->alloc_cnt += 1); |
2100 | IF_DEBUG1 (DP(RINT "[stream %p malloc] size %u ptr %p\n", | ||
2101 | stream, elts * size, a)); | ||
2090 | } | 2102 | } |
2091 | else | 2103 | else |
2092 | { | 2104 | { |
@@ -2104,6 +2116,8 @@ xd3_free (xd3_stream *stream, | |||
2104 | { | 2116 | { |
2105 | IF_DEBUG (stream->free_cnt += 1); | 2117 | IF_DEBUG (stream->free_cnt += 1); |
2106 | XD3_ASSERT (stream->free_cnt <= stream->alloc_cnt); | 2118 | XD3_ASSERT (stream->free_cnt <= stream->alloc_cnt); |
2119 | IF_DEBUG1 (DP(RINT "[stream %p free] %p\n", | ||
2120 | stream, ptr)); | ||
2107 | stream->free (stream->opaque, ptr); | 2121 | stream->free (stream->opaque, ptr); |
2108 | } | 2122 | } |
2109 | } | 2123 | } |
@@ -2781,10 +2795,11 @@ xd3_iopt_finish_encoding (xd3_stream *stream, xd3_rinst *inst) | |||
2781 | stream->l_tcpy += inst->size; | 2795 | stream->l_tcpy += inst->size; |
2782 | } | 2796 | } |
2783 | 2797 | ||
2784 | XD3_ASSERT (inst->size >= MIN_MATCH); | 2798 | /* Note: used to assert inst->size >= MIN_MATCH, but not true |
2785 | 2799 | * for merge operations & identical match heuristics. */ | |
2786 | /* the "here" position is always offset by taroff */ | 2800 | /* the "here" position is always offset by taroff */ |
2787 | if ((ret = xd3_encode_address (stream, addr, inst->pos + stream->taroff, & inst->type))) | 2801 | if ((ret = xd3_encode_address (stream, addr, inst->pos + stream->taroff, |
2802 | & inst->type))) | ||
2788 | { | 2803 | { |
2789 | return ret; | 2804 | return ret; |
2790 | } | 2805 | } |
@@ -3262,8 +3277,6 @@ xd3_emit_run (xd3_stream *stream, usize_t pos, usize_t size, uint8_t run_c) | |||
3262 | xd3_rinst* ri; | 3277 | xd3_rinst* ri; |
3263 | int ret; | 3278 | int ret; |
3264 | 3279 | ||
3265 | XD3_ASSERT (pos + size <= stream->avail_in); | ||
3266 | |||
3267 | if ((ret = xd3_iopt_get_slot (stream, & ri))) { return ret; } | 3280 | if ((ret = xd3_iopt_get_slot (stream, & ri))) { return ret; } |
3268 | 3281 | ||
3269 | ri->type = XD3_RUN; | 3282 | ri->type = XD3_RUN; |
@@ -3283,8 +3296,6 @@ xd3_found_match (xd3_stream *stream, usize_t pos, | |||
3283 | xd3_rinst* ri; | 3296 | xd3_rinst* ri; |
3284 | int ret; | 3297 | int ret; |
3285 | 3298 | ||
3286 | XD3_ASSERT (pos + size <= stream->avail_in); | ||
3287 | |||
3288 | if ((ret = xd3_iopt_get_slot (stream, & ri))) { return ret; } | 3299 | if ((ret = xd3_iopt_get_slot (stream, & ri))) { return ret; } |
3289 | 3300 | ||
3290 | ri->type = XD3_CPY; | 3301 | ri->type = XD3_CPY; |
@@ -3574,12 +3585,43 @@ xd3_alloc_iopt (xd3_stream *stream, int elts) | |||
3574 | return 0; | 3585 | return 0; |
3575 | } | 3586 | } |
3576 | 3587 | ||
3577 | /* This function allocates the encoder output buffers. */ | 3588 | /* This function allocates all memory initially used by the encoder. */ |
3578 | static int | 3589 | static int |
3579 | xd3_encode_init_buffers (xd3_stream *stream) | 3590 | xd3_encode_init (xd3_stream *stream, int full_init) |
3580 | { | 3591 | { |
3581 | int i; | 3592 | int i; |
3582 | 3593 | ||
3594 | if (full_init) | ||
3595 | { | ||
3596 | int large_comp = (stream->src != NULL); | ||
3597 | int small_comp = ! (stream->flags & XD3_NOCOMPRESS); | ||
3598 | |||
3599 | /* Memory allocations for checksum tables are delayed until | ||
3600 | * xd3_string_match_init in the first call to string_match--that way | ||
3601 | * identical or short inputs require no table allocation. */ | ||
3602 | if (large_comp) | ||
3603 | { | ||
3604 | usize_t hash_values = (stream->srcwin_maxsz / stream->smatcher.large_step); | ||
3605 | |||
3606 | xd3_size_hashtable (stream, | ||
3607 | hash_values, | ||
3608 | & stream->large_hash); | ||
3609 | } | ||
3610 | |||
3611 | if (small_comp) | ||
3612 | { | ||
3613 | /* TODO: This is under devel: used to have min(sprevsz) here, which sort | ||
3614 | * of makes sense, but observed fast performance w/ larger tables, which | ||
3615 | * also sort of makes sense. @@@ */ | ||
3616 | usize_t hash_values = stream->winsize; | ||
3617 | |||
3618 | xd3_size_hashtable (stream, | ||
3619 | hash_values, | ||
3620 | & stream->small_hash); | ||
3621 | } | ||
3622 | } | ||
3623 | |||
3624 | /* data buffers */ | ||
3583 | for (i = 0; i < ENC_SECTS; i += 1) | 3625 | for (i = 0; i < ENC_SECTS; i += 1) |
3584 | { | 3626 | { |
3585 | if ((stream->enc_heads[i] = | 3627 | if ((stream->enc_heads[i] = |
@@ -3590,43 +3632,6 @@ xd3_encode_init_buffers (xd3_stream *stream) | |||
3590 | } | 3632 | } |
3591 | } | 3633 | } |
3592 | 3634 | ||
3593 | return 0; | ||
3594 | } | ||
3595 | |||
3596 | /* This function allocates all memory initially used by the encoder. */ | ||
3597 | int | ||
3598 | xd3_encode_init (xd3_stream *stream) | ||
3599 | { | ||
3600 | int large_comp = (stream->src != NULL); | ||
3601 | int small_comp = ! (stream->flags & XD3_NOCOMPRESS); | ||
3602 | |||
3603 | /* Memory allocations for checksum tables are delayed until | ||
3604 | * xd3_string_match_init in the first call to string_match--that way | ||
3605 | * identical or short inputs require no table allocation. */ | ||
3606 | if (large_comp) | ||
3607 | { | ||
3608 | usize_t hash_values = (stream->srcwin_maxsz / stream->smatcher.large_step); | ||
3609 | |||
3610 | xd3_size_hashtable (stream, | ||
3611 | hash_values, | ||
3612 | & stream->large_hash); | ||
3613 | } | ||
3614 | |||
3615 | if (small_comp) | ||
3616 | { | ||
3617 | /* TODO: This is under devel: used to have min(sprevsz) here, which sort | ||
3618 | * of makes sense, but observed fast performance w/ larger tables, which | ||
3619 | * also sort of makes sense. @@@ */ | ||
3620 | usize_t hash_values = stream->winsize; | ||
3621 | |||
3622 | xd3_size_hashtable (stream, | ||
3623 | hash_values, | ||
3624 | & stream->small_hash); | ||
3625 | } | ||
3626 | |||
3627 | /* data buffers */ | ||
3628 | if (xd3_encode_init_buffers(stream) != 0) { goto fail; } | ||
3629 | |||
3630 | /* iopt buffer */ | 3635 | /* iopt buffer */ |
3631 | xd3_rlist_init (& stream->iopt_used); | 3636 | xd3_rlist_init (& stream->iopt_used); |
3632 | xd3_rlist_init (& stream->iopt_free); | 3637 | xd3_rlist_init (& stream->iopt_free); |
@@ -3648,6 +3653,18 @@ xd3_encode_init (xd3_stream *stream) | |||
3648 | return ENOMEM; | 3653 | return ENOMEM; |
3649 | } | 3654 | } |
3650 | 3655 | ||
3656 | int | ||
3657 | xd3_encode_init_full (xd3_stream *stream) | ||
3658 | { | ||
3659 | return xd3_encode_init (stream, 1); | ||
3660 | } | ||
3661 | |||
3662 | int | ||
3663 | xd3_encode_init_partial (xd3_stream *stream) | ||
3664 | { | ||
3665 | return xd3_encode_init (stream, 0); | ||
3666 | } | ||
3667 | |||
3651 | /* Called after the ENC_POSTOUT state, this puts the output buffers | 3668 | /* Called after the ENC_POSTOUT state, this puts the output buffers |
3652 | * back into separate lists and re-initializes some variables. (The | 3669 | * back into separate lists and re-initializes some variables. (The |
3653 | * output lists were spliced together during the ENC_FLUSH state.) */ | 3670 | * output lists were spliced together during the ENC_FLUSH state.) */ |
@@ -3708,7 +3725,7 @@ xd3_encode_input (xd3_stream *stream) | |||
3708 | { | 3725 | { |
3709 | case ENC_INIT: | 3726 | case ENC_INIT: |
3710 | /* Only reached on first time through: memory setup. */ | 3727 | /* Only reached on first time through: memory setup. */ |
3711 | if ((ret = xd3_encode_init (stream))) { return ret; } | 3728 | if ((ret = xd3_encode_init_full (stream))) { return ret; } |
3712 | 3729 | ||
3713 | stream->enc_state = ENC_INPUT; | 3730 | stream->enc_state = ENC_INPUT; |
3714 | 3731 | ||
diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h index 4d04b49..9b009f1 100644 --- a/xdelta3/xdelta3.h +++ b/xdelta3/xdelta3.h | |||
@@ -1159,13 +1159,13 @@ int xd3_decoder_needs_source (xd3_stream *stream); | |||
1159 | /* To generate a VCDIFF encoded delta with xd3_encode_init() from | 1159 | /* To generate a VCDIFF encoded delta with xd3_encode_init() from |
1160 | * another format, use: | 1160 | * another format, use: |
1161 | * | 1161 | * |
1162 | * xd3_encode_init() -- initialze encoder state | 1162 | * xd3_encode_init_partial() -- initialze encoder state (w/o hash tables) |
1163 | * xd3_init_cache() -- reset VCDIFF address cache | 1163 | * xd3_init_cache() -- reset VCDIFF address cache |
1164 | * xd3_found_match() -- to report a copy instruction | 1164 | * xd3_found_match() -- to report a copy instruction |
1165 | * | 1165 | * |
1166 | * set stream->enc_state to ENC_INSTR and call xd3_encode_input as usual. | 1166 | * set stream->enc_state to ENC_INSTR and call xd3_encode_input as usual. |
1167 | */ | 1167 | */ |
1168 | int xd3_encode_init (xd3_stream *stream); | 1168 | int xd3_encode_init_partial (xd3_stream *stream); |
1169 | void xd3_init_cache (xd3_addr_cache* acache); | 1169 | void xd3_init_cache (xd3_addr_cache* acache); |
1170 | int xd3_found_match (xd3_stream *stream, | 1170 | int xd3_found_match (xd3_stream *stream, |
1171 | usize_t pos, usize_t size, | 1171 | usize_t pos, usize_t size, |