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 e4ec806f7718c8b4de357eb9977f329a852834a7..d0ef47d1f43d0fe8f9f5867793acadf575ec6b72 100644 |
--- a/content/browser/download/download_file_impl.cc |
+++ b/content/browser/download/download_file_impl.cc |
@@ -151,6 +151,34 @@ DownloadInterruptReason DownloadFileImpl::WriteDataToFile(int64_t offset, |
return file_.WriteDataToFile(offset, data, data_len); |
} |
+bool DownloadFileImpl::CalculateBytesToWrite( |
+ SourceStream* source_stream, |
+ size_t bytes_read, |
+ size_t *bytes_to_write) { |
+ // If a new slice find 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 && |
xingliu
2017/03/11 00:11:46
nit%: Maybe add a comment for this block.
Write a
qinmin
2017/03/14 23:24:50
Done.
|
+ source_stream->bytes_written() + |
+ static_cast<int64_t>(bytes_read) >= source_stream->length()) { |
+ *bytes_to_write = source_stream->length() - source_stream->bytes_written(); |
+ return true; |
+ } |
+ |
+ *bytes_to_write = bytes_read; |
+ return false; |
+} |
+ |
void DownloadFileImpl::RenameAndUniquify( |
const base::FilePath& full_path, |
const RenameCompletionCallback& callback) { |
@@ -287,6 +315,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; |
@@ -305,23 +334,17 @@ 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); |
+ |
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) |
- source_stream->OnWriteBytesToDisk(incoming_data_size); |
+ source_stream->OnWriteBytesToDisk(bytes_to_write); |
} |
break; |
case ByteStreamReader::STREAM_COMPLETE: |