| Index: content/browser/download/download_file_impl.cc
|
| diff --git a/content/browser/download/download_file_impl.cc b/content/browser/download/download_file_impl.cc
|
| index eb1ef9bfd59e107735c6b49daf8f34df324f1191..0cb74d25c70c542c2c7b38bb264d400024e7afc8 100644
|
| --- a/content/browser/download/download_file_impl.cc
|
| +++ b/content/browser/download/download_file_impl.cc
|
| @@ -156,6 +156,35 @@ DownloadInterruptReason DownloadFileImpl::WriteDataToFile(int64_t offset,
|
| return file_.WriteDataToFile(offset, data, data_len);
|
| }
|
|
|
| +bool DownloadFileImpl::CalculateBytesToWrite(SourceStream* source_stream,
|
| + size_t bytes_available_to_write,
|
| + size_t* bytes_to_write) {
|
| + // If a new slice finds that its target position has already been written,
|
| + // terminate the stream.
|
| + if (source_stream->bytes_written() == 0) {
|
| + for (const auto& received_slice : received_slices_) {
|
| + if (received_slice.offset <= source_stream->offset() &&
|
| + received_slice.offset + received_slice.received_bytes >
|
| + source_stream->offset()) {
|
| + *bytes_to_write = 0;
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| +
|
| + if (source_stream->length() != DownloadSaveInfo::kLengthFullContent &&
|
| + source_stream->bytes_written() +
|
| + static_cast<int64_t>(bytes_available_to_write) >=
|
| + source_stream->length()) {
|
| + // Write a partial buffer as the incoming data exceeds the length limit.
|
| + *bytes_to_write = source_stream->length() - source_stream->bytes_written();
|
| + return true;
|
| + }
|
| +
|
| + *bytes_to_write = bytes_available_to_write;
|
| + return false;
|
| +}
|
| +
|
| void DownloadFileImpl::RenameAndUniquify(
|
| const base::FilePath& full_path,
|
| const RenameCompletionCallback& callback) {
|
| @@ -292,6 +321,7 @@ void DownloadFileImpl::StreamActive(SourceStream* source_stream) {
|
| size_t incoming_data_size = 0;
|
| size_t total_incoming_data_size = 0;
|
| size_t num_buffers = 0;
|
| + size_t bytes_to_write = 0;
|
| bool should_terminate = false;
|
| ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY);
|
| DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_NONE;
|
| @@ -310,34 +340,28 @@ void DownloadFileImpl::StreamActive(SourceStream* source_stream) {
|
| {
|
| ++num_buffers;
|
| base::TimeTicks write_start(base::TimeTicks::Now());
|
| - // Stop the stream if it writes more bytes than expected.
|
| - if (source_stream->length() != DownloadSaveInfo::kLengthFullContent &&
|
| - source_stream->bytes_written() +
|
| - static_cast<int64_t>(incoming_data_size) >=
|
| - source_stream->length()) {
|
| - should_terminate = true;
|
| - incoming_data_size =
|
| - source_stream->length() - source_stream->bytes_written();
|
| - }
|
| + should_terminate = CalculateBytesToWrite(
|
| + source_stream, incoming_data_size, &bytes_to_write);
|
| + DCHECK_GE(incoming_data_size, bytes_to_write);
|
| reason = WriteDataToFile(
|
| source_stream->offset() + source_stream->bytes_written(),
|
| - incoming_data.get()->data(), incoming_data_size);
|
| + incoming_data.get()->data(), bytes_to_write);
|
| disk_writes_time_ += (base::TimeTicks::Now() - write_start);
|
| - bytes_seen_ += incoming_data_size;
|
| - total_incoming_data_size += incoming_data_size;
|
| + bytes_seen_ += bytes_to_write;
|
| + total_incoming_data_size += bytes_to_write;
|
| if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) {
|
| int64_t prev_bytes_written = source_stream->bytes_written();
|
| - source_stream->OnWriteBytesToDisk(incoming_data_size);
|
| + source_stream->OnWriteBytesToDisk(bytes_to_write);
|
| if (!is_sparse_file_)
|
| break;
|
| // If the write operation creates a new slice, add it to the
|
| // |received_slices_| and update all the entries in
|
| // |source_streams_|.
|
| - if (incoming_data_size > 0 && prev_bytes_written == 0) {
|
| - AddNewSlice(source_stream->offset(), incoming_data_size);
|
| + if (bytes_to_write > 0 && prev_bytes_written == 0) {
|
| + AddNewSlice(source_stream->offset(), bytes_to_write);
|
| } else {
|
| received_slices_[source_stream->index()].received_bytes +=
|
| - incoming_data_size;
|
| + bytes_to_write;
|
| }
|
| }
|
| }
|
|
|