summaryrefslogtreecommitdiff
path: root/xdelta3/xdelta3-decode.h
diff options
context:
space:
mode:
authorjosh.macdonald <jmacd@users.noreply.github.com>2009-11-05 03:16:19 +0000
committerjosh.macdonald <jmacd@users.noreply.github.com>2009-11-05 03:16:19 +0000
commita42182cd17787a521afa61b2cea719ae67b7d45b (patch)
treeba00c105a48c8847dfde8166babe54151ab05965 /xdelta3/xdelta3-decode.h
parent97eb8c8b6f2b9e9a1d124e972e86765a92c2b37e (diff)
Cleanups in xd3_decode_output_halfinst() and xd3_decode_emit().
Diffstat (limited to 'xdelta3/xdelta3-decode.h')
-rw-r--r--xdelta3/xdelta3-decode.h117
1 files changed, 57 insertions, 60 deletions
diff --git a/xdelta3/xdelta3-decode.h b/xdelta3/xdelta3-decode.h
index 0835222..cc0a0e7 100644
--- a/xdelta3/xdelta3-decode.h
+++ b/xdelta3/xdelta3-decode.h
@@ -331,12 +331,14 @@ xd3_decode_instruction (xd3_stream *stream)
331} 331}
332 332
333/* Output the result of a single half-instruction. OPT: This the 333/* Output the result of a single half-instruction. OPT: This the
334 decoder hotspot. */ 334 decoder hotspot. Modifies "hinst", see below. */
335static int 335static int
336xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst) 336xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
337{ 337{
338 /* To make this reentrant, set take = min (inst->size, available 338 /* This method is reentrant for copy instructions which may return
339 space)... */ 339 * XD3_GETSRCBLK to the caller. Each time through a copy takes the
340 * minimum of inst->size and the available space on whichever block
341 * supplies the data */
340 usize_t take = inst->size; 342 usize_t take = inst->size;
341 343
342 XD3_ASSERT (inst->type != XD3_NOOP); 344 XD3_ASSERT (inst->type != XD3_NOOP);
@@ -388,22 +390,33 @@ xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
388 390
389 /* See if it copies from the VCD_TARGET/VCD_SOURCE window or 391 /* See if it copies from the VCD_TARGET/VCD_SOURCE window or
390 * the target window. Out-of-bounds checks for the addresses 392 * the target window. Out-of-bounds checks for the addresses
391 * and sizes are performed in xd3_decode_parse_halfinst. */ 393 * and sizes are performed in xd3_decode_parse_halfinst. This
394 * if/else must set "overlap", "src", and "dst". */
392 if (inst->addr < stream->dec_cpylen) 395 if (inst->addr < stream->dec_cpylen)
393 { 396 {
397 /* In both branches we are copying from outside the
398 * current decoder window, the first (VCD_TARGET) is
399 * unimplemented. */
394 overlap = 0; 400 overlap = 0;
395 401
402 /* This branch sets "src". As a side-effect, we modify
403 * "inst" so that if we reenter this method after a
404 * XD3_GETSRCBLK response the state is correct. So if the
405 * instruction can be fulfilled by a contiguous block of
406 * memory then we will set:
407 *
408 * inst->type = XD3_NOOP;
409 * inst->size = 0;
410 */
396 if (stream->dec_win_ind & VCD_TARGET) 411 if (stream->dec_win_ind & VCD_TARGET)
397 { 412 {
398 /* For VCD_TARGET we know the entire range is 413 /* TODO: Users have requested long-distance copies of
399 * in-memory, as established by 414 * similar material within a target (e.g., for dup
400 * decode_setup_buffers. 415 * supression in backups). */
401 *
402 * TODO: this is totally bogus, VCD_TARGET won't work.
403 */
404 src = stream->dec_cpyaddrbase + inst->addr;
405 inst->type = XD3_NOOP;
406 inst->size = 0; 416 inst->size = 0;
417 inst->type = XD3_NOOP;
418 stream->msg = "VCD_TARGET not implemented";
419 return XD3_UNIMPLEMENTED;
407 } 420 }
408 else 421 else
409 { 422 {
@@ -411,24 +424,14 @@ xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
411 * could return control to the caller. We need to 424 * could return control to the caller. We need to
412 * know the first block number needed for this 425 * know the first block number needed for this
413 * copy. */ 426 * copy. */
414 xd3_source *source; 427 xd3_source *source = stream->src;
415 xoff_t block; 428 xoff_t block = source->cpyoff_blocks;
416 usize_t blkoff; 429 usize_t blkoff = source->cpyoff_blkoff;
417 usize_t blksize; 430 const usize_t blksize = source->blksize;
418 int ret; 431 int ret;
419 432
420 more: 433 xd3_blksize_add (&block, &blkoff, source, inst->addr);
421 434 XD3_ASSERT (blkoff < blksize);
422 source = stream->src;
423 block = source->cpyoff_blocks;
424 blkoff = source->cpyoff_blkoff + inst->addr;
425 blksize = source->blksize;
426
427 while (blkoff >= blksize)
428 {
429 block += 1;
430 blkoff -= blksize;
431 }
432 435
433 if ((ret = xd3_getblk (stream, block))) 436 if ((ret = xd3_getblk (stream, block)))
434 { 437 {
@@ -443,8 +446,8 @@ xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
443 446
444 src = source->curblk + blkoff; 447 src = source->curblk + blkoff;
445 448
446 /* This block either contains enough data or the source file 449 /* This block is either full, or a partial block that
447 * is short. */ 450 * must contain enough bytes. */
448 if ((source->onblk != blksize) && 451 if ((source->onblk != blksize) &&
449 (blkoff + take > source->onblk)) 452 (blkoff + take > source->onblk))
450 { 453 {
@@ -461,6 +464,8 @@ xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
461 464
462 XD3_ASSERT (blkoff != blksize); 465 XD3_ASSERT (blkoff != blksize);
463 466
467 /* Check if we have enough data on this block to
468 * finish the instruction. */
464 if (blkoff + take <= blksize) 469 if (blkoff + take <= blksize)
465 { 470 {
466 inst->type = XD3_NOOP; 471 inst->type = XD3_NOOP;
@@ -468,16 +473,23 @@ xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
468 } 473 }
469 else 474 else
470 { 475 {
471 /* This block doesn't contain all the data, modify
472 * the instruction, do not set to XD3_NOOP. */
473 take = blksize - blkoff; 476 take = blksize - blkoff;
474 inst->size -= take; 477 inst->size -= take;
475 inst->addr += take; 478 inst->addr += take;
479
480 /* because (blkoff + take > blksize), above */
481 XD3_ASSERT (inst->size != 0);
476 } 482 }
477 } 483 }
478 } 484 }
479 else 485 else
480 { 486 {
487 /* TODO: the memcpy/overlap optimization, etc. Overlap
488 * here could be more specific, it's whether (inst->addr -
489 * srclen) + inst->size > input_pos ? And is the system
490 * memcpy really any good? */
491 overlap = 1;
492
481 /* For a target-window copy, we know the entire range is 493 /* For a target-window copy, we know the entire range is
482 * in-memory. The dec_tgtaddrbase is negatively offset by 494 * in-memory. The dec_tgtaddrbase is negatively offset by
483 * dec_cpylen because the addresses start beyond that 495 * dec_cpylen because the addresses start beyond that
@@ -485,12 +497,6 @@ xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
485 src = stream->dec_tgtaddrbase + inst->addr; 497 src = stream->dec_tgtaddrbase + inst->addr;
486 inst->type = XD3_NOOP; 498 inst->type = XD3_NOOP;
487 inst->size = 0; 499 inst->size = 0;
488
489 /* TODO: This can be more specific, it's whether
490 * (inst->addr - srclen) + inst->size > input_pos
491 * ?
492 */
493 overlap = 1;
494 } 500 }
495 501
496 dst = stream->next_out + stream->avail_out; 502 dst = stream->next_out + stream->avail_out;
@@ -509,19 +515,6 @@ xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
509 { 515 {
510 memcpy (dst, src, take); 516 memcpy (dst, src, take);
511 } 517 }
512
513 take = inst->size;
514
515 /* If there is more to copy, call getblk again. */
516 if (inst->type != XD3_NOOP)
517 {
518 XD3_ASSERT (take > 0);
519 goto more;
520 }
521 else
522 {
523 XD3_ASSERT (take == 0);
524 }
525 } 518 }
526 } 519 }
527 520
@@ -673,17 +666,21 @@ xd3_decode_emit (xd3_stream *stream)
673 (stream->dec_current2.type == XD3_NOOP) && 666 (stream->dec_current2.type == XD3_NOOP) &&
674 (ret = xd3_decode_instruction (stream))) { return ret; } 667 (ret = xd3_decode_instruction (stream))) { return ret; }
675 668
676 /* Output for each instruction. */ 669 /* Output dec_current1 */
677 if ((stream->dec_current1.type != XD3_NOOP) && 670 while ((stream->dec_current1.type != XD3_NOOP))
678 (ret = xd3_decode_output_halfinst (stream, & stream->dec_current1)))
679 { 671 {
680 return ret; 672 if ((ret = xd3_decode_output_halfinst (stream, & stream->dec_current1)))
673 {
674 return ret;
675 }
681 } 676 }
682 677 /* Output dec_current2 */
683 if ((stream->dec_current2.type != XD3_NOOP) && 678 while (stream->dec_current2.type != XD3_NOOP)
684 (ret = xd3_decode_output_halfinst (stream, & stream->dec_current2)))
685 { 679 {
686 return ret; 680 if ((ret = xd3_decode_output_halfinst (stream, & stream->dec_current2)))
681 {
682 return ret;
683 }
687 } 684 }
688 } 685 }
689 686