Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(450)

Unified Diff: content/browser/download/download_file_impl.cc

Issue 2770303002: Add a helper method to truncate SourceStream's length (Closed)
Patch Set: nit Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/download/download_file_impl.h ('k') | content/browser/download/download_item_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 4b47ae1f08e8bf0263a9e43c7fe8b8ec53113cae..865a5b8c4feb3ada64884b3ac27e306fc684ee6f 100644
--- a/content/browser/download/download_file_impl.cc
+++ b/content/browser/download/download_file_impl.cc
@@ -31,6 +31,8 @@
namespace content {
+namespace {
+
const int kUpdatePeriodMs = 500;
const int kMaxTimeBlockingFileThreadMs = 1000;
@@ -42,6 +44,12 @@ const int kInitialRenameRetryDelayMs = 200;
// Number of times a failing rename is retried before giving up.
const int kMaxRenameRetries = 3;
+// Because DownloadSaveInfo::kLengthFullContent is 0, we should avoid using
+// 0 for length if we found that a stream can no longer write any data.
+const int kNoBytesToWrite = -1;
+
+} // namespace
+
DownloadFileImpl::SourceStream::SourceStream(
int64_t offset,
int64_t length,
@@ -59,6 +67,25 @@ void DownloadFileImpl::SourceStream::OnWriteBytesToDisk(int64_t bytes_write) {
bytes_written_ += bytes_write;
}
+void DownloadFileImpl::SourceStream::TruncateLengthWithWrittenDataBlock(
+ int64_t offset,
+ int64_t bytes_written) {
+ DCHECK_GT(bytes_written, 0);
+ if (length_ == kNoBytesToWrite)
+ return;
+
+ if (offset <= offset_) {
+ if (offset + bytes_written > offset_)
+ length_ = kNoBytesToWrite;
+ return;
+ }
+
+ if (length_ == DownloadSaveInfo::kLengthFullContent ||
+ length_ > offset - offset_) {
+ length_ = offset - offset_;
+ }
+}
+
DownloadFileImpl::DownloadFileImpl(
std::unique_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_download_directory,
@@ -161,6 +188,11 @@ DownloadInterruptReason DownloadFileImpl::WriteDataToFile(int64_t offset,
bool DownloadFileImpl::CalculateBytesToWrite(SourceStream* source_stream,
size_t bytes_available_to_write,
size_t* bytes_to_write) {
+ if (source_stream->length() == kNoBytesToWrite) {
+ *bytes_to_write = 0;
+ return true;
+ }
+
// If a new slice finds that its target position has already been written,
// terminate the stream.
if (source_stream->bytes_written() == 0) {
@@ -448,6 +480,11 @@ void DownloadFileImpl::RegisterAndActivateStream(SourceStream* source_stream) {
stream_reader->RegisterCallback(base::Bind(&DownloadFileImpl::StreamActive,
weak_factory_.GetWeakPtr(),
source_stream));
+ // Truncate |source_stream|'s length if necessary.
+ for (const auto& received_slice : received_slices_) {
+ source_stream->TruncateLengthWithWrittenDataBlock(
+ received_slice.offset, received_slice.received_bytes);
+ }
StreamActive(source_stream);
num_active_streams_++;
}
@@ -503,12 +540,8 @@ void DownloadFileImpl::AddNewSlice(int64_t offset, int64_t length) {
source_stream->set_index(source_stream->index() + 1);
} else if (source_stream->offset() == offset) {
source_stream->set_index(index);
- } else if (source_stream->length() ==
- DownloadSaveInfo::kLengthFullContent ||
- source_stream->length() > offset - source_stream->offset()) {
- // The newly introduced slice will impact the length of the SourceStreams
- // preceding it.
- source_stream->set_length(offset - source_stream->offset());
+ } else {
+ source_stream->TruncateLengthWithWrittenDataBlock(offset, length);
}
}
}
@@ -564,7 +597,7 @@ void DownloadFileImpl::HandleStreamError(SourceStream* source_stream,
bool can_recover_from_error = false;
- if (is_sparse_file_) {
+ if (is_sparse_file_ && source_stream->length() != kNoBytesToWrite) {
// If a neighboring stream request is available, check if it can help
// download all the data left by |source stream| or has already done so. We
// want to avoid the situation that a server always fail additional requests
« no previous file with comments | « content/browser/download/download_file_impl.h ('k') | content/browser/download/download_item_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698