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 |