| OLD | NEW |
| 1 /* | 1 /* |
| 2 bsdiff.c -- Binary patch generator. | 2 bsdiff.c -- Binary patch generator. |
| 3 | 3 |
| 4 Copyright 2003 Colin Percival | 4 Copyright 2003 Colin Percival |
| 5 | 5 |
| 6 For the terms under which this work may be distributed, please see | 6 For the terms under which this work may be distributed, please see |
| 7 the adjoining file "LICENSE". | 7 the adjoining file "LICENSE". |
| 8 | 8 |
| 9 ChangeLog: | 9 ChangeLog: |
| 10 2005-05-05 - Use the modified header struct from bspatch.h; use 32-bit | 10 2005-05-05 - Use the modified header struct from bspatch.h; use 32-bit |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 if(memcmp(old+I[x],newbuf,std::min(oldsize-I[x],newsize))<0) { | 184 if(memcmp(old+I[x],newbuf,std::min(oldsize-I[x],newsize))<0) { |
| 185 return search(I,old,oldsize,newbuf,newsize,x,en,pos); | 185 return search(I,old,oldsize,newbuf,newsize,x,en,pos); |
| 186 } else { | 186 } else { |
| 187 return search(I,old,oldsize,newbuf,newsize,st,x,pos); | 187 return search(I,old,oldsize,newbuf,newsize,st,x,pos); |
| 188 } | 188 } |
| 189 } | 189 } |
| 190 | 190 |
| 191 // End of 'verbatim' code. | 191 // End of 'verbatim' code. |
| 192 // ------------------------------------------------------------------------ | 192 // ------------------------------------------------------------------------ |
| 193 | 193 |
| 194 static void WriteHeader(SinkStream* stream, MBSPatchHeader* header) { | 194 static CheckBool WriteHeader(SinkStream* stream, MBSPatchHeader* header) { |
| 195 stream->Write(header->tag, sizeof(header->tag)); | 195 bool ok = stream->Write(header->tag, sizeof(header->tag)); |
| 196 stream->WriteVarint32(header->slen); | 196 ok &= stream->WriteVarint32(header->slen); |
| 197 stream->WriteVarint32(header->scrc32); | 197 ok &= stream->WriteVarint32(header->scrc32); |
| 198 stream->WriteVarint32(header->dlen); | 198 ok &= stream->WriteVarint32(header->dlen); |
| 199 return ok; |
| 199 } | 200 } |
| 200 | 201 |
| 201 BSDiffStatus CreateBinaryPatch(SourceStream* old_stream, | 202 BSDiffStatus CreateBinaryPatch(SourceStream* old_stream, |
| 202 SourceStream* new_stream, | 203 SourceStream* new_stream, |
| 203 SinkStream* patch_stream) | 204 SinkStream* patch_stream) |
| 204 { | 205 { |
| 205 base::Time start_bsdiff_time = base::Time::Now(); | 206 base::Time start_bsdiff_time = base::Time::Now(); |
| 206 VLOG(1) << "Start bsdiff"; | 207 VLOG(1) << "Start bsdiff"; |
| 207 size_t initial_patch_stream_length = patch_stream->Length(); | 208 size_t initial_patch_stream_length = patch_stream->Length(); |
| 208 | 209 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 } | 369 } |
| 369 | 370 |
| 370 lenf += lens - overlap; | 371 lenf += lens - overlap; |
| 371 lenb -= lens; | 372 lenb -= lens; |
| 372 }; | 373 }; |
| 373 | 374 |
| 374 for (int i = 0; i < lenf; i++) { | 375 for (int i = 0; i < lenf; i++) { |
| 375 uint8 diff_byte = newbuf[lastscan + i] - old[lastpos + i]; | 376 uint8 diff_byte = newbuf[lastscan + i] - old[lastpos + i]; |
| 376 if (diff_byte) { | 377 if (diff_byte) { |
| 377 ++diff_bytes_nonzero; | 378 ++diff_bytes_nonzero; |
| 378 diff_skips->WriteVarint32(pending_diff_zeros); | 379 if (!diff_skips->WriteVarint32(pending_diff_zeros)) |
| 380 return MEM_ERROR; |
| 379 pending_diff_zeros = 0; | 381 pending_diff_zeros = 0; |
| 380 diff_bytes->Write(&diff_byte, 1); | 382 if (!diff_bytes->Write(&diff_byte, 1)) |
| 383 return MEM_ERROR; |
| 381 } else { | 384 } else { |
| 382 ++pending_diff_zeros; | 385 ++pending_diff_zeros; |
| 383 } | 386 } |
| 384 } | 387 } |
| 385 int gap = (scan - lenb) - (lastscan + lenf); | 388 int gap = (scan - lenb) - (lastscan + lenf); |
| 386 for (int i = 0; i < gap; i++) | 389 for (int i = 0; i < gap; i++) { |
| 387 extra_bytes->Write(&newbuf[lastscan + lenf + i], 1); | 390 if (!extra_bytes->Write(&newbuf[lastscan + lenf + i], 1)) |
| 391 return MEM_ERROR; |
| 392 } |
| 388 | 393 |
| 389 diff_bytes_length += lenf; | 394 diff_bytes_length += lenf; |
| 390 extra_bytes_length += gap; | 395 extra_bytes_length += gap; |
| 391 | 396 |
| 392 uint32 copy_count = lenf; | 397 uint32 copy_count = lenf; |
| 393 uint32 extra_count = gap; | 398 uint32 extra_count = gap; |
| 394 int32 seek_adjustment = ((pos - lenb) - (lastpos + lenf)); | 399 int32 seek_adjustment = ((pos - lenb) - (lastpos + lenf)); |
| 395 | 400 |
| 396 control_stream_copy_counts->WriteVarint32(copy_count); | 401 if (!control_stream_copy_counts->WriteVarint32(copy_count) || |
| 397 control_stream_extra_counts->WriteVarint32(extra_count); | 402 !control_stream_extra_counts->WriteVarint32(extra_count) || |
| 398 control_stream_seeks->WriteVarint32Signed(seek_adjustment); | 403 !control_stream_seeks->WriteVarint32Signed(seek_adjustment)) { |
| 404 return MEM_ERROR; |
| 405 } |
| 406 |
| 399 ++control_length; | 407 ++control_length; |
| 400 #ifdef DEBUG_bsmedberg | 408 #ifdef DEBUG_bsmedberg |
| 401 VLOG(1) << StringPrintf("Writing a block: copy: %-8u extra: %-8u seek: " | 409 VLOG(1) << StringPrintf("Writing a block: copy: %-8u extra: %-8u seek: " |
| 402 "%+-9d", copy_count, extra_count, | 410 "%+-9d", copy_count, extra_count, |
| 403 seek_adjustment); | 411 seek_adjustment); |
| 404 #endif | 412 #endif |
| 405 | 413 |
| 406 lastscan = scan - lenb; // Include the backward extension in seed. | 414 lastscan = scan - lenb; // Include the backward extension in seed. |
| 407 lastpos = pos - lenb; // ditto. | 415 lastpos = pos - lenb; // ditto. |
| 408 lastoffset = lastpos - lastscan; | 416 lastoffset = lastpos - lastscan; |
| 409 } | 417 } |
| 410 } | 418 } |
| 411 | 419 |
| 412 diff_skips->WriteVarint32(pending_diff_zeros); | 420 if (!diff_skips->WriteVarint32(pending_diff_zeros)) |
| 421 return MEM_ERROR; |
| 413 | 422 |
| 414 I.clear(); | 423 I.clear(); |
| 415 | 424 |
| 416 MBSPatchHeader header; | 425 MBSPatchHeader header; |
| 417 // The string will have a null terminator that we don't use, hence '-1'. | 426 // The string will have a null terminator that we don't use, hence '-1'. |
| 418 COMPILE_ASSERT(sizeof(MBS_PATCH_HEADER_TAG) - 1 == sizeof(header.tag), | 427 COMPILE_ASSERT(sizeof(MBS_PATCH_HEADER_TAG) - 1 == sizeof(header.tag), |
| 419 MBS_PATCH_HEADER_TAG_must_match_header_field_size); | 428 MBS_PATCH_HEADER_TAG_must_match_header_field_size); |
| 420 memcpy(header.tag, MBS_PATCH_HEADER_TAG, sizeof(header.tag)); | 429 memcpy(header.tag, MBS_PATCH_HEADER_TAG, sizeof(header.tag)); |
| 421 header.slen = oldsize; | 430 header.slen = oldsize; |
| 422 header.scrc32 = CalculateCrc(old, oldsize); | 431 header.scrc32 = CalculateCrc(old, oldsize); |
| 423 header.dlen = newsize; | 432 header.dlen = newsize; |
| 424 | 433 |
| 425 WriteHeader(patch_stream, &header); | 434 if (!WriteHeader(patch_stream, &header)) |
| 435 return MEM_ERROR; |
| 426 | 436 |
| 427 size_t diff_skips_length = diff_skips->Length(); | 437 size_t diff_skips_length = diff_skips->Length(); |
| 428 patch_streams.CopyTo(patch_stream); | 438 if (!patch_streams.CopyTo(patch_stream)) |
| 439 return MEM_ERROR; |
| 429 | 440 |
| 430 VLOG(1) << "Control tuples: " << control_length | 441 VLOG(1) << "Control tuples: " << control_length |
| 431 << " copy bytes: " << diff_bytes_length | 442 << " copy bytes: " << diff_bytes_length |
| 432 << " mistakes: " << diff_bytes_nonzero | 443 << " mistakes: " << diff_bytes_nonzero |
| 433 << " (skips: " << diff_skips_length << ")" | 444 << " (skips: " << diff_skips_length << ")" |
| 434 << " extra bytes: " << extra_bytes_length | 445 << " extra bytes: " << extra_bytes_length |
| 435 << "\nUncompressed bsdiff patch size " | 446 << "\nUncompressed bsdiff patch size " |
| 436 << patch_stream->Length() - initial_patch_stream_length | 447 << patch_stream->Length() - initial_patch_stream_length |
| 437 << "\nEnd bsdiff " | 448 << "\nEnd bsdiff " |
| 438 << (base::Time::Now() - start_bsdiff_time).InSecondsF(); | 449 << (base::Time::Now() - start_bsdiff_time).InSecondsF(); |
| 439 | 450 |
| 440 return OK; | 451 return OK; |
| 441 } | 452 } |
| 442 | 453 |
| 443 } // namespace | 454 } // namespace |
| OLD | NEW |