summaryrefslogtreecommitdiff
path: root/xdelta3
diff options
context:
space:
mode:
authorjosh.macdonald <jmacd@users.noreply.github.com>2007-09-12 07:36:37 +0000
committerjosh.macdonald <jmacd@users.noreply.github.com>2007-09-12 07:36:37 +0000
commita5cf569debedee47fbe8d4f3b96a200cf677c623 (patch)
tree9934771e706e2d6de26df31b5547de8f0c22836a /xdelta3
parenta69974bdf9f5b2248829ddefabf91c87256cbdce (diff)
Add "xdelta3 recode" function, which is currently outputing incorrect
VCDIFF windows.
Diffstat (limited to 'xdelta3')
-rw-r--r--xdelta3/xdelta3-decode.h22
-rw-r--r--xdelta3/xdelta3-main.h142
-rw-r--r--xdelta3/xdelta3-second.h2
-rw-r--r--xdelta3/xdelta3.c90
-rw-r--r--xdelta3/xdelta3.h36
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)
99static int 99static int
100xd3_decode_allocate (xd3_stream *stream, 100xd3_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 */
305static int allow_fake_source = 0; 306static int allow_fake_source = 0;
306 307
308/* State for xdelta3 recode */
309static 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. */
309static main_extcomp extcomp_types[] = 313static 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
1228static int
1229main_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
1252static int
1253main_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
579static int xd3_decode_allocate (xd3_stream *stream, usize_t size, 579static 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
583static void xd3_compute_code_table_string (const xd3_dinst *code_table, uint8_t *str); 582static void xd3_compute_code_table_string (const xd3_dinst *code_table, uint8_t *str);
584static void* xd3_alloc (xd3_stream *stream, usize_t elts, usize_t size); 583static void* xd3_alloc (xd3_stream *stream, usize_t elts, usize_t size);
@@ -1975,9 +1974,11 @@ static int
1975xd3_alloc_cache (xd3_stream *stream) 1974xd3_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. */
3524static int
3525xd3_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. */
3512static int 3543static int
3513xd3_encode_init (xd3_stream *stream) 3544xd3_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
494struct _xd3_output 494struct _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. */
503struct _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 */
503struct _xd3_addr_cache 520struct _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. */
551struct _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 ******************************************************************************************/