Index: courgette/third_party/bsdiff_apply.cc |
=================================================================== |
--- courgette/third_party/bsdiff_apply.cc (revision 16336) |
+++ courgette/third_party/bsdiff_apply.cc (working copy) |
@@ -44,9 +44,6 @@ |
if (!stream->ReadVarint32(&header->slen)) return READ_ERROR; |
if (!stream->ReadVarint32(&header->scrc32)) return READ_ERROR; |
if (!stream->ReadVarint32(&header->dlen)) return READ_ERROR; |
- if (!stream->ReadVarint32(&header->cblen)) return READ_ERROR; |
- if (!stream->ReadVarint32(&header->difflen)) return READ_ERROR; |
- if (!stream->ReadVarint32(&header->extralen)) return READ_ERROR; |
// The string will have a NUL terminator that we don't use, hence '-1'. |
COMPILE_ASSERT(sizeof(MBS_PATCH_HEADER_TAG) - 1 == sizeof(header->tag), |
@@ -54,12 +51,6 @@ |
if (memcmp(header->tag, MBS_PATCH_HEADER_TAG, 8) != 0) |
return UNEXPECTED_ERROR; |
- size_t bytes_remaining = stream->Remaining(); |
- if (header->cblen + |
- header->difflen + |
- header->extralen != bytes_remaining) |
- return UNEXPECTED_ERROR; |
- |
return OK; |
} |
@@ -69,35 +60,37 @@ |
SinkStream* new_stream) { |
const uint8* old_end = old_start + old_size; |
- SourceStream control_stream; |
- |
- const uint8* control_start = patch_stream->Buffer(); |
- if (!patch_stream->ReadSubstream(header->cblen, &control_stream)) |
+ SourceStreamSet patch_streams; |
+ if (!patch_streams.Init(patch_stream)) |
return READ_ERROR; |
- if (!patch_stream->Skip(header->difflen + header->extralen)) |
- return READ_ERROR; |
- if (!patch_stream->Empty()) |
- return READ_ERROR; |
- const uint8* diff_start = control_start + header->cblen; |
- const uint8* diff_end = diff_start + header->difflen; |
- const uint8* extra_start = diff_end; |
- const uint8* extra_end = extra_start + header->extralen; |
+ SourceStream* control_stream_copy_counts = patch_streams.stream(0); |
+ SourceStream* control_stream_extra_counts = patch_streams.stream(1); |
+ SourceStream* control_stream_seeks = patch_streams.stream(2); |
+ SourceStream* diff_skips = patch_streams.stream(3); |
+ SourceStream* diff_bytes = patch_streams.stream(4); |
+ SourceStream* extra_bytes = patch_streams.stream(5); |
- const uint8* old_position = old_start; |
- const uint8* diff_position = diff_start; |
+ const uint8* extra_start = extra_bytes->Buffer(); |
+ const uint8* extra_end = extra_start + extra_bytes->Remaining(); |
const uint8* extra_position = extra_start; |
+ const uint8* old_position = old_start; |
+ |
new_stream->Reserve(header->dlen); |
- while (!control_stream.Empty()) { |
+ uint32 pending_diff_zeros = 0; |
+ if (!diff_skips->ReadVarint32(&pending_diff_zeros)) |
+ return UNEXPECTED_ERROR; |
+ |
+ while (!control_stream_copy_counts->Empty()) { |
uint32 copy_count, extra_count; |
int32 seek_adjustment; |
- if (!control_stream.ReadVarint32(©_count)) |
+ if (!control_stream_copy_counts->ReadVarint32(©_count)) |
return UNEXPECTED_ERROR; |
- if (!control_stream.ReadVarint32(&extra_count)) |
+ if (!control_stream_extra_counts->ReadVarint32(&extra_count)) |
return UNEXPECTED_ERROR; |
- if (!control_stream.ReadVarint32Signed(&seek_adjustment)) |
+ if (!control_stream_seeks->ReadVarint32Signed(&seek_adjustment)) |
return UNEXPECTED_ERROR; |
#ifdef DEBUG_bsmedberg |
@@ -108,16 +101,22 @@ |
// block. |
if (copy_count > static_cast<size_t>(old_end - old_position)) |
return UNEXPECTED_ERROR; |
- if (copy_count > static_cast<size_t>(diff_end - diff_position)) |
- return UNEXPECTED_ERROR; |
// Add together bytes from the 'old' file and the 'diff' stream. |
for (size_t i = 0; i < copy_count; ++i) { |
- uint8 byte = old_position[i] + diff_position[i]; |
+ uint8 diff_byte = 0; |
+ if (pending_diff_zeros) { |
+ --pending_diff_zeros; |
+ } else { |
+ if (!diff_skips->ReadVarint32(&pending_diff_zeros)) |
+ return UNEXPECTED_ERROR; |
+ if (!diff_bytes->Read(&diff_byte, 1)) |
+ return UNEXPECTED_ERROR; |
+ } |
+ uint8 byte = old_position[i] + diff_byte; |
new_stream->Write(&byte, 1); |
} |
old_position += copy_count; |
- diff_position += copy_count; |
// Copy bytes from the extra block. |
if (extra_count > static_cast<size_t>(extra_end - extra_position)) |
@@ -134,10 +133,13 @@ |
old_position += seek_adjustment; |
} |
- if (diff_position != diff_end) |
+ if (!control_stream_copy_counts->Empty() || |
+ !control_stream_extra_counts->Empty() || |
+ !control_stream_seeks->Empty() || |
+ !diff_skips->Empty() || |
+ !diff_bytes->Empty() || |
+ !extra_bytes->Empty()) |
return UNEXPECTED_ERROR; |
- if (extra_position != extra_end) |
- return UNEXPECTED_ERROR; |
return OK; |
} |