diff options
author | josh.macdonald <jmacd@users.noreply.github.com> | 2009-11-05 03:16:19 +0000 |
---|---|---|
committer | josh.macdonald <jmacd@users.noreply.github.com> | 2009-11-05 03:16:19 +0000 |
commit | a42182cd17787a521afa61b2cea719ae67b7d45b (patch) | |
tree | ba00c105a48c8847dfde8166babe54151ab05965 /xdelta3/xdelta3-decode.h | |
parent | 97eb8c8b6f2b9e9a1d124e972e86765a92c2b37e (diff) |
Cleanups in xd3_decode_output_halfinst() and xd3_decode_emit().
Diffstat (limited to 'xdelta3/xdelta3-decode.h')
-rw-r--r-- | xdelta3/xdelta3-decode.h | 117 |
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. */ |
335 | static int | 335 | static int |
336 | xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst) | 336 | xd3_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 | ||