| 382 | // patch to it. |
| 383 | template <typename OldReader, typename NewSink, typename PatchReader> |
| 384 | BSDiffStatus ApplyBinaryPatch(OldReader & old_reader, NewSink & new_sink, |
| 385 | PatchReader & patch_reader, const base::Cancellable & cancellable) |
| 386 | { |
| 387 | ReaderSource<OldReader> old_source(old_reader); |
| 388 | ReaderSource<PatchReader> patch_source(patch_reader); |
| 389 | |
| 390 | MBSPatchHeader header; |
| 391 | BSDiffStatus ret = MBS_ReadHeader(patch_source, &header); |
| 392 | if (ret != OK) |
| 393 | return ret; |
| 394 | |
| 395 | const auto old_size = static_cast<size_t>(old_source.Size()); |
| 396 | std::vector<uint8_t> old_buf(old_size); |
| 397 | old_source.Read(old_buf.data(), old_buf.size()); |
| 398 | |
| 399 | const uint8_t* old_start = old_buf.data(); |
| 400 | const uint8_t* old_end = old_buf.data() + old_buf.size(); |
| 401 | const uint8_t* old_position = old_start; |
| 402 | |
| 403 | if (old_size != header.slen) |
| 404 | return UNEXPECTED_ERROR; |
| 405 | |
| 406 | if (CalculateCrc(old_start, old_size) != header.scrc32) |
| 407 | return CRC_ERROR; |
| 408 | |
| 409 | CHECK_GREATER_OR_EQUAL(kNumStreams, 6, ()); |
| 410 | std::vector<uint32_t> stream_sizes(kNumStreams); |
| 411 | for (auto & s : stream_sizes) |
| 412 | s = ReadPrimitiveFromSource<uint32_t>(patch_source); |
| 413 | |
| 414 | std::vector<ReaderSource<PatchReader>> patch_streams; |
| 415 | patch_streams.reserve(kNumStreams); |
| 416 | for (size_t i = 0; i < kNumStreams; ++i) { |
| 417 | uint64_t size = static_cast<uint64_t>(stream_sizes[i]); |
| 418 | patch_streams.emplace_back(ReaderSource<PatchReader>(patch_source.SubReader(size))); |
| 419 | } |
| 420 | |
| 421 | auto & control_stream_copy_counts = patch_streams[0]; |
| 422 | auto & control_stream_extra_counts = patch_streams[1]; |
| 423 | auto & control_stream_seeks = patch_streams[2]; |
| 424 | auto & diff_skips = patch_streams[3]; |
| 425 | auto & diff_bytes = patch_streams[4]; |
| 426 | auto & extra_bytes = patch_streams[5]; |
| 427 | |
| 428 | std::vector<uint8_t> extra_bytes_buf(static_cast<size_t>(extra_bytes.Size())); |
| 429 | extra_bytes.Read(extra_bytes_buf.data(), extra_bytes_buf.size()); |
| 430 | |
| 431 | const uint8_t* extra_start = extra_bytes_buf.data(); |
| 432 | const uint8_t* extra_end = extra_bytes_buf.data() + extra_bytes_buf.size(); |
| 433 | const uint8_t* extra_position = extra_start; |
| 434 | |
| 435 | // if (header->dlen && !new_sink->Reserve(header->dlen)) |
| 436 | // return MEM_ERROR; |
| 437 | |
| 438 | auto pending_diff_zeros = ReadVarUint<uint32_t>(diff_skips); |
| 439 | |
| 440 | // We will check whether the application process has been cancelled |
| 441 | // upon copying every |kCheckCancelledPeriod| bytes from the old file. |
no test coverage detected