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

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

Issue 2695153002: Refactor BaseFile class to support sparse files (Closed)
Patch Set: remove the while loop around write Created 3 years, 10 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/base_file.h ('k') | content/browser/download/base_file_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/download/base_file.cc
diff --git a/content/browser/download/base_file.cc b/content/browser/download/base_file.cc
index 59dfa839cd51dca2373f2b6204d5a64c418fb41c..b95ef97ed98c372ddddcb82f12144b11418735ee 100644
--- a/content/browser/download/base_file.cc
+++ b/content/browser/download/base_file.cc
@@ -44,7 +44,8 @@ DownloadInterruptReason BaseFile::Initialize(
base::File file,
int64_t bytes_so_far,
const std::string& hash_so_far,
- std::unique_ptr<crypto::SecureHash> hash_state) {
+ std::unique_ptr<crypto::SecureHash> hash_state,
+ bool is_sparse_file) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(!detached_);
@@ -70,6 +71,8 @@ DownloadInterruptReason BaseFile::Initialize(
bytes_so_far_ = bytes_so_far;
secure_hash_ = std::move(hash_state);
+ is_sparse_file_ = is_sparse_file;
+ DCHECK(!is_sparse_file_ || !secure_hash_);
file_ = std::move(file);
return Open(hash_so_far);
@@ -77,9 +80,13 @@ DownloadInterruptReason BaseFile::Initialize(
DownloadInterruptReason BaseFile::AppendDataToFile(const char* data,
size_t data_len) {
- DCHECK_CURRENTLY_ON(BrowserThread::FILE);
- DCHECK(!detached_);
+ DCHECK(!is_sparse_file_);
+ return WriteDataToFile(bytes_so_far_, data, data_len);
+}
+DownloadInterruptReason BaseFile::WriteDataToFile(int64_t offset,
+ const char* data,
+ size_t data_len) {
// NOTE(benwells): The above DCHECK won't be present in release builds,
// so we log any occurences to see how common this error is in the wild.
if (detached_)
@@ -93,27 +100,16 @@ DownloadInterruptReason BaseFile::AppendDataToFile(const char* data,
if (data_len == 0)
return DOWNLOAD_INTERRUPT_REASON_NONE;
- // The Write call below is not guaranteed to write all the data.
- size_t write_count = 0;
- size_t len = data_len;
- const char* current_data = data;
net_log_.BeginEvent(net::NetLogEventType::DOWNLOAD_FILE_WRITTEN);
- while (len > 0) {
- write_count++;
- int write_result = file_.WriteAtCurrentPos(current_data, len);
- DCHECK_NE(0, write_result);
-
- // Report errors on file writes.
- if (write_result < 0)
- return LogSystemError("Write", logging::GetLastSystemErrorCode());
-
- // Update status.
- size_t write_size = static_cast<size_t>(write_result);
- DCHECK_LE(write_size, len);
- len -= write_size;
- current_data += write_size;
- bytes_so_far_ += write_size;
- }
+ int write_result = file_.Write(offset, data, data_len);
+ DCHECK_NE(0, write_result);
+
+ // Report errors on file writes.
+ if (write_result < 0)
+ return LogSystemError("Write", logging::GetLastSystemErrorCode());
+
+ DCHECK_EQ(static_cast<size_t>(write_result), data_len);
+ bytes_so_far_ += data_len;
net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_WRITTEN,
net::NetLog::Int64Callback("bytes", data_len));
@@ -186,6 +182,10 @@ void BaseFile::Cancel() {
std::unique_ptr<crypto::SecureHash> BaseFile::Finish() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+
+ // TODO(qinmin): verify that all the holes have been filled.
+ if (is_sparse_file_)
+ CalculatePartialHash(std::string());
Close();
return std::move(secure_hash_);
}
@@ -288,6 +288,16 @@ DownloadInterruptReason BaseFile::Open(const std::string& hash_so_far) {
net::NetLogEventType::DOWNLOAD_FILE_OPENED,
base::Bind(&FileOpenedNetLogCallback, &full_path_, bytes_so_far_));
+ // For sparse file, skip hash validation.
+ if (is_sparse_file_) {
+ if (file_.GetLength() < bytes_so_far_) {
+ ClearFile();
+ return LogInterruptReason("File has fewer written bytes than expected", 0,
+ DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT);
+ }
+ return DOWNLOAD_INTERRUPT_REASON_NONE;
+ }
+
if (!secure_hash_) {
DownloadInterruptReason reason = CalculatePartialHash(hash_so_far);
if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) {
« no previous file with comments | « content/browser/download/base_file.h ('k') | content/browser/download/base_file_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698