diff options
author | josh.macdonald <jmacd@users.noreply.github.com> | 2007-09-12 07:36:37 +0000 |
---|---|---|
committer | josh.macdonald <jmacd@users.noreply.github.com> | 2007-09-12 07:36:37 +0000 |
commit | a5cf569debedee47fbe8d4f3b96a200cf677c623 (patch) | |
tree | 9934771e706e2d6de26df31b5547de8f0c22836a /xdelta3 | |
parent | a69974bdf9f5b2248829ddefabf91c87256cbdce (diff) |
Add "xdelta3 recode" function, which is currently outputing incorrect
VCDIFF windows.
Diffstat (limited to 'xdelta3')
-rw-r--r-- | xdelta3/xdelta3-decode.h | 22 | ||||
-rw-r--r-- | xdelta3/xdelta3-main.h | 142 | ||||
-rw-r--r-- | xdelta3/xdelta3-second.h | 2 | ||||
-rw-r--r-- | xdelta3/xdelta3.c | 90 | ||||
-rw-r--r-- | xdelta3/xdelta3.h | 36 |
5 files changed, 226 insertions, 66 deletions
diff --git a/xdelta3/xdelta3-decode.h b/xdelta3/xdelta3-decode.h index 34c0fea..fd41675 100644 --- a/xdelta3/xdelta3-decode.h +++ b/xdelta3/xdelta3-decode.h | |||
@@ -99,22 +99,20 @@ xd3_decode_setup_buffers (xd3_stream *stream) | |||
99 | static int | 99 | static int |
100 | xd3_decode_allocate (xd3_stream *stream, | 100 | xd3_decode_allocate (xd3_stream *stream, |
101 | usize_t size, | 101 | usize_t size, |
102 | uint8_t **copied1, | 102 | uint8_t **buf_ptr, |
103 | usize_t *alloc1, | 103 | usize_t *buf_alloc) |
104 | uint8_t **copied2, | ||
105 | usize_t *alloc2) | ||
106 | { | 104 | { |
107 | if (*copied1 != NULL && *alloc1 < size) | 105 | if (*buf_ptr != NULL && *buf_alloc < size) |
108 | { | 106 | { |
109 | xd3_free (stream, *copied1); | 107 | xd3_free (stream, *buf_ptr); |
110 | *copied1 = NULL; | 108 | *buf_ptr = NULL; |
111 | } | 109 | } |
112 | 110 | ||
113 | if (*copied1 == NULL) | 111 | if (*buf_ptr == NULL) |
114 | { | 112 | { |
115 | *alloc1 = xd3_round_blksize (size, XD3_ALLOCSIZE); | 113 | *buf_alloc = xd3_round_blksize (size, XD3_ALLOCSIZE); |
116 | 114 | ||
117 | if ((*copied1 = xd3_alloc (stream, *alloc1, 1)) == NULL) | 115 | if ((*buf_ptr = xd3_alloc (stream, *buf_alloc, 1)) == NULL) |
118 | { | 116 | { |
119 | return ENOMEM; | 117 | return ENOMEM; |
120 | } | 118 | } |
@@ -161,9 +159,7 @@ xd3_decode_section (xd3_stream *stream, | |||
161 | if ((ret = xd3_decode_allocate (stream, | 159 | if ((ret = xd3_decode_allocate (stream, |
162 | section->size, | 160 | section->size, |
163 | & section->copied1, | 161 | & section->copied1, |
164 | & section->alloc1, | 162 | & section->alloc1))) { return ret; } |
165 | & section->copied2, | ||
166 | & section->alloc2))) { return ret; } | ||
167 | 163 | ||
168 | section->buf = section->copied1; | 164 | section->buf = section->copied1; |
169 | } | 165 | } |
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h index 09a801a..57ad3d2 100644 --- a/xdelta3/xdelta3-main.h +++ b/xdelta3/xdelta3-main.h | |||
@@ -159,6 +159,7 @@ typedef enum | |||
159 | CMD_PRINTHDR, | 159 | CMD_PRINTHDR, |
160 | CMD_PRINTHDRS, | 160 | CMD_PRINTHDRS, |
161 | CMD_PRINTDELTA, | 161 | CMD_PRINTDELTA, |
162 | CMD_RECODE, | ||
162 | #if XD3_ENCODER | 163 | #if XD3_ENCODER |
163 | CMD_ENCODE, | 164 | CMD_ENCODE, |
164 | #endif | 165 | #endif |
@@ -304,6 +305,9 @@ static int lru_filled = 0; | |||
304 | /* Hacks for VCDIFF tools */ | 305 | /* Hacks for VCDIFF tools */ |
305 | static int allow_fake_source = 0; | 306 | static int allow_fake_source = 0; |
306 | 307 | ||
308 | /* State for xdelta3 recode */ | ||
309 | static xd3_stream *recode_stream = NULL; | ||
310 | |||
307 | /* This array of compressor types is compiled even if EXTERNAL_COMPRESSION is false just so | 311 | /* This array of compressor types is compiled even if EXTERNAL_COMPRESSION is false just so |
308 | * the program knows the mapping of IDENT->NAME. */ | 312 | * the program knows the mapping of IDENT->NAME. */ |
309 | static main_extcomp extcomp_types[] = | 313 | static main_extcomp extcomp_types[] = |
@@ -982,7 +986,7 @@ main_file_seek (main_file *xfile, xoff_t pos) | |||
982 | 986 | ||
983 | /* The following macros let VCDIFF printing something printf-like with | 987 | /* The following macros let VCDIFF printing something printf-like with |
984 | * main_file_write(), e.g.,: | 988 | * main_file_write(), e.g.,: |
985 | * | 989 | * |
986 | * VC(UT "trying to be portable: %d\n", x)VE; | 990 | * VC(UT "trying to be portable: %d\n", x)VE; |
987 | */ | 991 | */ |
988 | #define SNPRINTF_BUFSIZE 1024 | 992 | #define SNPRINTF_BUFSIZE 1024 |
@@ -1220,6 +1224,97 @@ main_print_func (xd3_stream* stream, main_file *xfile) | |||
1220 | 1224 | ||
1221 | return ret; | 1225 | return ret; |
1222 | } | 1226 | } |
1227 | |||
1228 | static int | ||
1229 | main_recode_copy (xd3_stream* stream, | ||
1230 | xd3_output* output, | ||
1231 | xd3_desect* input) | ||
1232 | { | ||
1233 | int ret; | ||
1234 | |||
1235 | XD3_ASSERT(output != NULL); | ||
1236 | XD3_ASSERT(output->next_page == NULL); | ||
1237 | |||
1238 | if ((ret = xd3_decode_allocate (recode_stream, | ||
1239 | input->size, | ||
1240 | &output->base, | ||
1241 | &output->avail))) | ||
1242 | { | ||
1243 | return ret; | ||
1244 | } | ||
1245 | |||
1246 | memcpy (output->base, input->buf, input->size); | ||
1247 | output->next = input->size; | ||
1248 | return 0; | ||
1249 | } | ||
1250 | |||
1251 | // Re-encode one window | ||
1252 | static int | ||
1253 | main_recode_func (xd3_stream* stream, main_file *xfile) | ||
1254 | { | ||
1255 | int ret; | ||
1256 | |||
1257 | XD3_ASSERT(stream->dec_state == DEC_FINISH); | ||
1258 | XD3_ASSERT(recode_stream->enc_state == ENC_INIT || | ||
1259 | recode_stream->enc_state == ENC_INPUT); | ||
1260 | |||
1261 | // Copy partial decoder output to partial encoder inputs | ||
1262 | if ((ret = main_recode_copy (recode_stream, | ||
1263 | DATA_HEAD(recode_stream), | ||
1264 | &stream->data_sect)) || | ||
1265 | (ret = main_recode_copy (recode_stream, | ||
1266 | INST_HEAD(recode_stream), | ||
1267 | &stream->inst_sect)) || | ||
1268 | (ret = main_recode_copy (recode_stream, | ||
1269 | ADDR_HEAD(recode_stream), | ||
1270 | &stream->addr_sect))) | ||
1271 | { | ||
1272 | return ret; | ||
1273 | } | ||
1274 | |||
1275 | // This jumps to xd3_emit_hdr() | ||
1276 | recode_stream->enc_state = ENC_FLUSH; | ||
1277 | //recode_stream->avail_in = stream->dec_tgtlen; | ||
1278 | //recode_stream->n_emit = stream->dec_tgtlen; | ||
1279 | |||
1280 | // Output loop | ||
1281 | for (;;) | ||
1282 | { | ||
1283 | switch((ret = xd3_encode_input (recode_stream))) | ||
1284 | { | ||
1285 | case XD3_INPUT: { | ||
1286 | /* finished recoding one window */ | ||
1287 | return 0; | ||
1288 | } | ||
1289 | case XD3_OUTPUT: { | ||
1290 | /* main_file_write below */ | ||
1291 | break; | ||
1292 | } | ||
1293 | case XD3_GOTHEADER: | ||
1294 | case XD3_WINSTART: | ||
1295 | case XD3_WINFINISH: { | ||
1296 | /* ignore */ | ||
1297 | continue; | ||
1298 | } | ||
1299 | case XD3_GETSRCBLK: | ||
1300 | case 0: { | ||
1301 | stream->msg = "invalid operation"; | ||
1302 | return XD3_INTERNAL; | ||
1303 | } | ||
1304 | default: | ||
1305 | return ret; | ||
1306 | } | ||
1307 | |||
1308 | if ((ret = main_file_write(xfile, | ||
1309 | recode_stream->next_out, | ||
1310 | recode_stream->avail_out, "write failed"))) | ||
1311 | { | ||
1312 | return ret; | ||
1313 | } | ||
1314 | |||
1315 | xd3_consume_output (recode_stream); | ||
1316 | } | ||
1317 | } | ||
1223 | #endif /* VCDIFF_TOOLS */ | 1318 | #endif /* VCDIFF_TOOLS */ |
1224 | 1319 | ||
1225 | /****************************************************************************************** | 1320 | /****************************************************************************************** |
@@ -2054,7 +2149,7 @@ main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *sour | |||
2054 | source->ioh = sfile; | 2149 | source->ioh = sfile; |
2055 | source->curblkno = (xoff_t) -1; | 2150 | source->curblkno = (xoff_t) -1; |
2056 | source->curblk = NULL; | 2151 | source->curblk = NULL; |
2057 | 2152 | ||
2058 | #if EXTERNAL_COMPRESSION | 2153 | #if EXTERNAL_COMPRESSION |
2059 | if (option_decompress_inputs) | 2154 | if (option_decompress_inputs) |
2060 | { | 2155 | { |
@@ -2149,7 +2244,7 @@ main_set_source (xd3_stream *stream, int cmd, main_file *sfile, xd3_source *sour | |||
2149 | if (option_verbose) | 2244 | if (option_verbose) |
2150 | { | 2245 | { |
2151 | static char buf[32]; | 2246 | static char buf[32]; |
2152 | 2247 | ||
2153 | XPR(NT "source %s winsize %s size %"Q"u\n", | 2248 | XPR(NT "source %s winsize %s size %"Q"u\n", |
2154 | sfile->filename, main_format_bcnt(option_srcwinsz, buf), source->size); | 2249 | sfile->filename, main_format_bcnt(option_srcwinsz, buf), source->size); |
2155 | } | 2250 | } |
@@ -2371,6 +2466,7 @@ main_input (xd3_cmd cmd, | |||
2371 | 2466 | ||
2372 | config.alloc = main_alloc; | 2467 | config.alloc = main_alloc; |
2373 | config.freef = main_free1; | 2468 | config.freef = main_free1; |
2469 | // TODO: what about sec_xxxx.ngroups = 1? | ||
2374 | config.sec_data.ngroups = 1; | 2470 | config.sec_data.ngroups = 1; |
2375 | config.sec_addr.ngroups = 1; | 2471 | config.sec_addr.ngroups = 1; |
2376 | config.sec_inst.ngroups = 1; | 2472 | config.sec_inst.ngroups = 1; |
@@ -2394,6 +2490,31 @@ main_input (xd3_cmd cmd, | |||
2394 | stream_flags |= XD3_ADLER32_NOVER; | 2490 | stream_flags |= XD3_ADLER32_NOVER; |
2395 | stdout_only = 1; | 2491 | stdout_only = 1; |
2396 | break; | 2492 | break; |
2493 | |||
2494 | case CMD_RECODE: | ||
2495 | |||
2496 | XD3_ASSERT (recode_stream == NULL); | ||
2497 | recode_stream = (xd3_stream*) main_malloc(sizeof(xd3_stream)); | ||
2498 | |||
2499 | xd3_config recode_config; | ||
2500 | xd3_init_config(&recode_config, 0); | ||
2501 | |||
2502 | // TODO: what about sec_xxxx.ngroups = 1? | ||
2503 | config.alloc = main_alloc; | ||
2504 | config.freef = main_free1; | ||
2505 | |||
2506 | if ((ret = xd3_config_stream (recode_stream, &recode_config)) || | ||
2507 | (ret = xd3_encode_init_buffers (recode_stream))) | ||
2508 | { | ||
2509 | return EXIT_FAILURE; | ||
2510 | } | ||
2511 | |||
2512 | // TODO: xd3_set_appheader (recode_stream) | ||
2513 | |||
2514 | ifile->flags |= RD_NONEXTERNAL; | ||
2515 | input_func = xd3_decode_input; | ||
2516 | output_func = main_recode_func; | ||
2517 | break; | ||
2397 | #endif | 2518 | #endif |
2398 | #if XD3_ENCODER | 2519 | #if XD3_ENCODER |
2399 | case CMD_ENCODE: | 2520 | case CMD_ENCODE: |
@@ -2615,7 +2736,8 @@ main_input (xd3_cmd cmd, | |||
2615 | } | 2736 | } |
2616 | else if (cmd == CMD_PRINTHDR || | 2737 | else if (cmd == CMD_PRINTHDR || |
2617 | cmd == CMD_PRINTHDRS || | 2738 | cmd == CMD_PRINTHDRS || |
2618 | cmd == CMD_PRINTDELTA) | 2739 | cmd == CMD_PRINTDELTA || |
2740 | cmd == CMD_RECODE) | ||
2619 | { | 2741 | { |
2620 | if (xd3_decoder_needs_source (& stream) && sfile->filename == NULL) | 2742 | if (xd3_decoder_needs_source (& stream) && sfile->filename == NULL) |
2621 | { | 2743 | { |
@@ -2676,7 +2798,7 @@ main_input (xd3_cmd cmd, | |||
2676 | stream.current_window * option_winsize, | 2798 | stream.current_window * option_winsize, |
2677 | (stream.current_window+1) * option_winsize); | 2799 | (stream.current_window+1) * option_winsize); |
2678 | } | 2800 | } |
2679 | 2801 | ||
2680 | /* Limited instruction buffer size affects source copies */ | 2802 | /* Limited instruction buffer size affects source copies */ |
2681 | if (option_verbose > 1 && stream.i_slots_used > stream.iopt_size) | 2803 | if (option_verbose > 1 && stream.i_slots_used > stream.iopt_size) |
2682 | { | 2804 | { |
@@ -2836,6 +2958,13 @@ main_cleanup (void) | |||
2836 | lru_misses = 0; | 2958 | lru_misses = 0; |
2837 | lru_filled = 0; | 2959 | lru_filled = 0; |
2838 | 2960 | ||
2961 | if (recode_stream != NULL) | ||
2962 | { | ||
2963 | xd3_free_stream (recode_stream); | ||
2964 | main_free (recode_stream); | ||
2965 | recode_stream = NULL; | ||
2966 | } | ||
2967 | |||
2839 | XD3_ASSERT (main_mallocs == 0); | 2968 | XD3_ASSERT (main_mallocs == 0); |
2840 | } | 2969 | } |
2841 | 2970 | ||
@@ -3044,6 +3173,7 @@ main (int argc, char **argv) | |||
3044 | else if (strcmp (my_optstr, "printhdr") == 0) { cmd = CMD_PRINTHDR; } | 3173 | else if (strcmp (my_optstr, "printhdr") == 0) { cmd = CMD_PRINTHDR; } |
3045 | else if (strcmp (my_optstr, "printhdrs") == 0) { cmd = CMD_PRINTHDRS; } | 3174 | else if (strcmp (my_optstr, "printhdrs") == 0) { cmd = CMD_PRINTHDRS; } |
3046 | else if (strcmp (my_optstr, "printdelta") == 0) { cmd = CMD_PRINTDELTA; } | 3175 | else if (strcmp (my_optstr, "printdelta") == 0) { cmd = CMD_PRINTDELTA; } |
3176 | else if (strcmp (my_optstr, "recode") == 0) { cmd = CMD_RECODE; } | ||
3047 | #endif | 3177 | #endif |
3048 | 3178 | ||
3049 | /* If no option was found and still no command, let the default command be | 3179 | /* If no option was found and still no command, let the default command be |
@@ -3216,6 +3346,7 @@ main (int argc, char **argv) | |||
3216 | case CMD_PRINTDELTA: | 3346 | case CMD_PRINTDELTA: |
3217 | #if XD3_ENCODER | 3347 | #if XD3_ENCODER |
3218 | case CMD_ENCODE: | 3348 | case CMD_ENCODE: |
3349 | case CMD_RECODE: | ||
3219 | #endif | 3350 | #endif |
3220 | case CMD_DECODE: | 3351 | case CMD_DECODE: |
3221 | ret = main_input (cmd, & ifile, & ofile, & sfile); | 3352 | ret = main_input (cmd, & ifile, & ofile, & sfile); |
@@ -3285,6 +3416,7 @@ main_help (void) | |||
3285 | DP(RINT " printdelta print information about the entire delta\n"); | 3416 | DP(RINT " printdelta print information about the entire delta\n"); |
3286 | DP(RINT " printhdr print information about the first window\n"); | 3417 | DP(RINT " printhdr print information about the first window\n"); |
3287 | DP(RINT " printhdrs print information about all windows\n"); | 3418 | DP(RINT " printhdrs print information about all windows\n"); |
3419 | DP(RINT " recode encode with new application/secondary settings\n"); | ||
3288 | #endif | 3420 | #endif |
3289 | DP(RINT "standard options:\n"); | 3421 | DP(RINT "standard options:\n"); |
3290 | DP(RINT " -0 .. -9 compression level\n"); | 3422 | DP(RINT " -0 .. -9 compression level\n"); |
diff --git a/xdelta3/xdelta3-second.h b/xdelta3/xdelta3-second.h index a8196fb..f925586 100644 --- a/xdelta3/xdelta3-second.h +++ b/xdelta3/xdelta3-second.h | |||
@@ -173,7 +173,7 @@ xd3_decode_secondary (xd3_stream *stream, | |||
173 | 173 | ||
174 | /* Decode the size, allocate the buffer. */ | 174 | /* Decode the size, allocate the buffer. */ |
175 | if ((ret = xd3_read_size (stream, & sect->buf, sect->buf_max, & dec_size)) || | 175 | if ((ret = xd3_read_size (stream, & sect->buf, sect->buf_max, & dec_size)) || |
176 | (ret = xd3_decode_allocate (stream, dec_size, & sect->copied2, & sect->alloc2, NULL, NULL))) | 176 | (ret = xd3_decode_allocate (stream, dec_size, & sect->copied2, & sect->alloc2))) |
177 | { | 177 | { |
178 | return ret; | 178 | return ret; |
179 | } | 179 | } |
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index 738bcb0..fb6191d 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -427,15 +427,15 @@ XD3_MAKELIST(xd3_rlist, xd3_rinst, link); | |||
427 | 427 | ||
428 | #define ENC_SECTS 4 /* Number of separate output sections. */ | 428 | #define ENC_SECTS 4 /* Number of separate output sections. */ |
429 | 429 | ||
430 | #define HDR_TAIL(s) (stream->enc_tails[0]) | 430 | #define HDR_TAIL(s) ((s)->enc_tails[0]) |
431 | #define DATA_TAIL(s) (stream->enc_tails[1]) | 431 | #define DATA_TAIL(s) ((s)->enc_tails[1]) |
432 | #define INST_TAIL(s) (stream->enc_tails[2]) | 432 | #define INST_TAIL(s) ((s)->enc_tails[2]) |
433 | #define ADDR_TAIL(s) (stream->enc_tails[3]) | 433 | #define ADDR_TAIL(s) ((s)->enc_tails[3]) |
434 | 434 | ||
435 | #define HDR_HEAD(s) (stream->enc_heads[0]) | 435 | #define HDR_HEAD(s) ((s)->enc_heads[0]) |
436 | #define DATA_HEAD(s) (stream->enc_heads[1]) | 436 | #define DATA_HEAD(s) ((s)->enc_heads[1]) |
437 | #define INST_HEAD(s) (stream->enc_heads[2]) | 437 | #define INST_HEAD(s) ((s)->enc_heads[2]) |
438 | #define ADDR_HEAD(s) (stream->enc_heads[3]) | 438 | #define ADDR_HEAD(s) ((s)->enc_heads[3]) |
439 | 439 | ||
440 | #define SIZEOF_ARRAY(x) (sizeof(x) / sizeof(x[0])) | 440 | #define SIZEOF_ARRAY(x) (sizeof(x) / sizeof(x[0])) |
441 | 441 | ||
@@ -577,8 +577,7 @@ static int xd3_emit_uint32_t (xd3_stream *stream, xd3_output **output, u | |||
577 | #endif /* XD3_ENCODER */ | 577 | #endif /* XD3_ENCODER */ |
578 | 578 | ||
579 | static int xd3_decode_allocate (xd3_stream *stream, usize_t size, | 579 | static int xd3_decode_allocate (xd3_stream *stream, usize_t size, |
580 | uint8_t **copied1, usize_t *alloc1, | 580 | uint8_t **copied1, usize_t *alloc1); |
581 | uint8_t **copied2, usize_t *alloc2); | ||
582 | 581 | ||
583 | static void xd3_compute_code_table_string (const xd3_dinst *code_table, uint8_t *str); | 582 | static void xd3_compute_code_table_string (const xd3_dinst *code_table, uint8_t *str); |
584 | static void* xd3_alloc (xd3_stream *stream, usize_t elts, usize_t size); | 583 | static void* xd3_alloc (xd3_stream *stream, usize_t elts, usize_t size); |
@@ -1975,9 +1974,11 @@ static int | |||
1975 | xd3_alloc_cache (xd3_stream *stream) | 1974 | xd3_alloc_cache (xd3_stream *stream) |
1976 | { | 1975 | { |
1977 | if (((stream->acache.s_near > 0) && | 1976 | if (((stream->acache.s_near > 0) && |
1978 | (stream->acache.near_array = xd3_alloc (stream, stream->acache.s_near, sizeof (usize_t))) == NULL) || | 1977 | (stream->acache.near_array = |
1978 | xd3_alloc (stream, stream->acache.s_near, sizeof (usize_t))) == NULL) || | ||
1979 | ((stream->acache.s_same > 0) && | 1979 | ((stream->acache.s_same > 0) && |
1980 | (stream->acache.same_array = xd3_alloc (stream, stream->acache.s_same * 256, sizeof (usize_t))) == NULL)) | 1980 | (stream->acache.same_array = |
1981 | xd3_alloc (stream, stream->acache.s_same * 256, sizeof (usize_t))) == NULL)) | ||
1981 | { | 1982 | { |
1982 | return ENOMEM; | 1983 | return ENOMEM; |
1983 | } | 1984 | } |
@@ -3312,7 +3313,11 @@ xd3_emit_hdr (xd3_stream *stream) | |||
3312 | 3313 | ||
3313 | /* Secondary compressor ID */ | 3314 | /* Secondary compressor ID */ |
3314 | #if SECONDARY_ANY | 3315 | #if SECONDARY_ANY |
3315 | if (use_secondary && (ret = xd3_emit_byte (stream, & HDR_TAIL (stream), stream->sec_type->id))) { return ret; } | 3316 | if (use_secondary && |
3317 | (ret = xd3_emit_byte (stream, & HDR_TAIL (stream), stream->sec_type->id))) | ||
3318 | { | ||
3319 | return ret; | ||
3320 | } | ||
3316 | #endif | 3321 | #endif |
3317 | 3322 | ||
3318 | /* Compressed code table */ | 3323 | /* Compressed code table */ |
@@ -3321,19 +3326,26 @@ xd3_emit_hdr (xd3_stream *stream) | |||
3321 | usize_t code_table_size; | 3326 | usize_t code_table_size; |
3322 | const uint8_t *code_table_data; | 3327 | const uint8_t *code_table_data; |
3323 | 3328 | ||
3324 | if ((ret = stream->comp_table_func (stream, & code_table_data, & code_table_size))) { return ret; } | 3329 | if ((ret = stream->comp_table_func (stream, & code_table_data, & code_table_size))) |
3330 | { | ||
3331 | return ret; | ||
3332 | } | ||
3325 | 3333 | ||
3326 | if ((ret = xd3_emit_size (stream, & HDR_TAIL (stream), code_table_size + 2)) || | 3334 | if ((ret = xd3_emit_size (stream, & HDR_TAIL (stream), code_table_size + 2)) || |
3327 | (ret = xd3_emit_byte (stream, & HDR_TAIL (stream), stream->code_table_desc->near_modes)) || | 3335 | (ret = xd3_emit_byte (stream, & HDR_TAIL (stream), stream->code_table_desc->near_modes)) || |
3328 | (ret = xd3_emit_byte (stream, & HDR_TAIL (stream), stream->code_table_desc->same_modes)) || | 3336 | (ret = xd3_emit_byte (stream, & HDR_TAIL (stream), stream->code_table_desc->same_modes)) || |
3329 | (ret = xd3_emit_bytes (stream, & HDR_TAIL (stream), code_table_data, code_table_size))) { return ret; } | 3337 | (ret = xd3_emit_bytes (stream, & HDR_TAIL (stream), code_table_data, code_table_size))) |
3338 | { | ||
3339 | return ret; | ||
3340 | } | ||
3330 | } | 3341 | } |
3331 | 3342 | ||
3332 | /* Application header */ | 3343 | /* Application header */ |
3333 | if (use_appheader) | 3344 | if (use_appheader) |
3334 | { | 3345 | { |
3335 | if ((ret = xd3_emit_size (stream, & HDR_TAIL (stream), stream->enc_appheadsz)) || | 3346 | if ((ret = xd3_emit_size (stream, & HDR_TAIL (stream), stream->enc_appheadsz)) || |
3336 | (ret = xd3_emit_bytes (stream, & HDR_TAIL (stream), stream->enc_appheader, stream->enc_appheadsz))) | 3347 | (ret = xd3_emit_bytes (stream, & HDR_TAIL (stream), stream->enc_appheader, |
3348 | stream->enc_appheadsz))) | ||
3337 | { | 3349 | { |
3338 | return ret; | 3350 | return ret; |
3339 | } | 3351 | } |
@@ -3387,7 +3399,7 @@ xd3_emit_hdr (xd3_stream *stream) | |||
3387 | inst_len = xd3_sizeof_output (INST_HEAD (stream)); | 3399 | inst_len = xd3_sizeof_output (INST_HEAD (stream)); |
3388 | addr_len = xd3_sizeof_output (ADDR_HEAD (stream)); | 3400 | addr_len = xd3_sizeof_output (ADDR_HEAD (stream)); |
3389 | 3401 | ||
3390 | /* The enc_len field is redundent... doh! */ | 3402 | /* The enc_len field is a redundency for future extensions.*/ |
3391 | enc_len = (1 + (xd3_sizeof_size (tgt_len) + | 3403 | enc_len = (1 + (xd3_sizeof_size (tgt_len) + |
3392 | xd3_sizeof_size (data_len) + | 3404 | xd3_sizeof_size (data_len) + |
3393 | xd3_sizeof_size (inst_len) + | 3405 | xd3_sizeof_size (inst_len) + |
@@ -3508,11 +3520,29 @@ xd3_alloc_iopt (xd3_stream *stream, int elts) | |||
3508 | return 0; | 3520 | return 0; |
3509 | } | 3521 | } |
3510 | 3522 | ||
3523 | /* This function allocates the encoder output buffers. */ | ||
3524 | static int | ||
3525 | xd3_encode_init_buffers (xd3_stream *stream) | ||
3526 | { | ||
3527 | int i; | ||
3528 | |||
3529 | for (i = 0; i < ENC_SECTS; i += 1) | ||
3530 | { | ||
3531 | if ((stream->enc_heads[i] = | ||
3532 | stream->enc_tails[i] = | ||
3533 | xd3_alloc_output (stream, NULL)) == NULL) | ||
3534 | { | ||
3535 | return ENOMEM; | ||
3536 | } | ||
3537 | } | ||
3538 | |||
3539 | return 0; | ||
3540 | } | ||
3541 | |||
3511 | /* This function allocates all memory initially used by the encoder. */ | 3542 | /* This function allocates all memory initially used by the encoder. */ |
3512 | static int | 3543 | static int |
3513 | xd3_encode_init (xd3_stream *stream) | 3544 | xd3_encode_init (xd3_stream *stream) |
3514 | { | 3545 | { |
3515 | int i; | ||
3516 | int large_comp = (stream->src != NULL); | 3546 | int large_comp = (stream->src != NULL); |
3517 | int small_comp = ! (stream->flags & XD3_NOCOMPRESS); | 3547 | int small_comp = ! (stream->flags & XD3_NOCOMPRESS); |
3518 | 3548 | ||
@@ -3537,15 +3567,8 @@ xd3_encode_init (xd3_stream *stream) | |||
3537 | & stream->small_hash); | 3567 | & stream->small_hash); |
3538 | } | 3568 | } |
3539 | 3569 | ||
3540 | for (i = 0; i < ENC_SECTS; i += 1) | 3570 | /* data buffers */ |
3541 | { | 3571 | if (xd3_encode_init_buffers(stream) != 0) { goto fail; } |
3542 | if ((stream->enc_heads[i] = | ||
3543 | stream->enc_tails[i] = | ||
3544 | xd3_alloc_output (stream, NULL)) == NULL) | ||
3545 | { | ||
3546 | goto fail; | ||
3547 | } | ||
3548 | } | ||
3549 | 3572 | ||
3550 | /* iopt buffer */ | 3573 | /* iopt buffer */ |
3551 | xd3_rlist_init (& stream->iopt_used); | 3574 | xd3_rlist_init (& stream->iopt_used); |
@@ -3725,10 +3748,17 @@ xd3_encode_input (xd3_stream *stream) | |||
3725 | 3748 | ||
3726 | /* Flush the instrution buffer, then possibly add one more instruction, then emit | 3749 | /* Flush the instrution buffer, then possibly add one more instruction, then emit |
3727 | * the header. */ | 3750 | * the header. */ |
3728 | stream->enc_state = ENC_FLUSH; | ||
3729 | if ((ret = xd3_iopt_flush_instructions (stream, 1)) || | 3751 | if ((ret = xd3_iopt_flush_instructions (stream, 1)) || |
3730 | (ret = xd3_iopt_add_finalize (stream)) || | 3752 | (ret = xd3_iopt_add_finalize (stream))) |
3731 | (ret = xd3_emit_hdr (stream))) | 3753 | { |
3754 | return ret; | ||
3755 | } | ||
3756 | |||
3757 | stream->enc_state = ENC_FLUSH; | ||
3758 | |||
3759 | case ENC_FLUSH: | ||
3760 | /* Note: main_recode_func() bypasses string-matching by setting ENC_FLUSH. */ | ||
3761 | if ((ret = xd3_emit_hdr (stream))) | ||
3732 | { | 3762 | { |
3733 | return ret; | 3763 | return ret; |
3734 | } | 3764 | } |
diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h index 67a4cac..e43574f 100644 --- a/xdelta3/xdelta3.h +++ b/xdelta3/xdelta3.h | |||
@@ -494,11 +494,28 @@ struct _xd3_hinst | |||
494 | struct _xd3_output | 494 | struct _xd3_output |
495 | { | 495 | { |
496 | uint8_t *base; | 496 | uint8_t *base; |
497 | usize_t next; | 497 | usize_t next; |
498 | usize_t avail; | 498 | usize_t avail; |
499 | xd3_output *next_page; | 499 | xd3_output *next_page; |
500 | }; | 500 | }; |
501 | 501 | ||
502 | /* used by the decoder to buffer input in sections. */ | ||
503 | struct _xd3_desect | ||
504 | { | ||
505 | const uint8_t *buf; | ||
506 | const uint8_t *buf_max; | ||
507 | uint32_t size; | ||
508 | usize_t pos; | ||
509 | |||
510 | /* used in xdelta3-decode.h */ | ||
511 | uint8_t *copied1; | ||
512 | usize_t alloc1; | ||
513 | |||
514 | /* used in xdelta3-second.h */ | ||
515 | uint8_t *copied2; | ||
516 | usize_t alloc2; | ||
517 | }; | ||
518 | |||
502 | /* the VCDIFF address cache, see the RFC */ | 519 | /* the VCDIFF address cache, see the RFC */ |
503 | struct _xd3_addr_cache | 520 | struct _xd3_addr_cache |
504 | { | 521 | { |
@@ -545,21 +562,6 @@ struct _xd3_slist | |||
545 | usize_t last_pos; | 562 | usize_t last_pos; |
546 | }; | 563 | }; |
547 | 564 | ||
548 | /* a decoder section (data, inst, or addr). there is an optimization to avoid copying | ||
549 | * these sections if all the input is available, related to the copied field below. | ||
550 | * secondation compression uses the copied2 field. */ | ||
551 | struct _xd3_desect | ||
552 | { | ||
553 | const uint8_t *buf; | ||
554 | const uint8_t *buf_max; | ||
555 | uint32_t size; | ||
556 | usize_t pos; | ||
557 | uint8_t *copied1; | ||
558 | usize_t alloc1; | ||
559 | uint8_t *copied2; | ||
560 | usize_t alloc2; | ||
561 | }; | ||
562 | |||
563 | /****************************************************************************************** | 565 | /****************************************************************************************** |
564 | public types | 566 | public types |
565 | ******************************************************************************************/ | 567 | ******************************************************************************************/ |