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

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

Issue 2695153002: Refactor BaseFile class to support sparse files (Closed)
Patch Set: 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
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..a24a3d78a96d14e0534ca7ed966ba9a6ea8ee8fa 100644
--- a/content/browser/download/base_file.cc
+++ b/content/browser/download/base_file.cc
@@ -42,9 +42,10 @@ DownloadInterruptReason BaseFile::Initialize(
const base::FilePath& full_path,
const base::FilePath& default_directory,
base::File file,
- int64_t bytes_so_far,
+ int64_t offset,
const std::string& hash_so_far,
- std::unique_ptr<crypto::SecureHash> hash_state) {
+ std::unique_ptr<crypto::SecureHash> hash_state,
+ AccessMode access_mode) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(!detached_);
@@ -68,15 +69,18 @@ DownloadInterruptReason BaseFile::Initialize(
full_path_ = full_path;
}
- bytes_so_far_ = bytes_so_far;
+ access_mode_ = access_mode;
+ offset_ = offset;
+ if (access_mode_ == EXCLUSIVE)
+ bytes_so_far_ = offset;
secure_hash_ = std::move(hash_state);
file_ = std::move(file);
return Open(hash_so_far);
}
-DownloadInterruptReason BaseFile::AppendDataToFile(const char* data,
- size_t data_len) {
+DownloadInterruptReason BaseFile::WriteDataToFile(const char* data,
+ size_t data_len) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
DCHECK(!detached_);
@@ -112,6 +116,7 @@ DownloadInterruptReason BaseFile::AppendDataToFile(const char* data,
DCHECK_LE(write_size, len);
len -= write_size;
current_data += write_size;
+ offset_ += write_size;
bytes_so_far_ += write_size;
}
net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_WRITTEN,
@@ -195,17 +200,18 @@ std::string BaseFile::DebugString() const {
"{ "
" full_path_ = \"%" PRFilePath
"\""
- " bytes_so_far_ = %" PRId64 " detached_ = %c }",
- full_path_.value().c_str(),
- bytes_so_far_,
- detached_ ? 'T' : 'F');
+ " offset_ = %" PRId64 " detached_ = %c }",
+ full_path_.value().c_str(), offset_, detached_ ? 'T' : 'F');
}
DownloadInterruptReason BaseFile::CalculatePartialHash(
const std::string& hash_to_expect) {
secure_hash_ = crypto::SecureHash::Create(crypto::SecureHash::SHA256);
- if (bytes_so_far_ == 0)
+ if (access_mode_ == SHARED)
+ return DOWNLOAD_INTERRUPT_REASON_NONE;
+
+ if (offset_ == 0)
return DOWNLOAD_INTERRUPT_REASON_NONE;
if (file_.Seek(base::File::FROM_BEGIN, 0) != 0)
@@ -220,17 +226,16 @@ DownloadInterruptReason BaseFile::CalculatePartialHash(
// The size of the buffer is:
// - at least kMinBufferSize so that we can use it to hold the hash as well.
// - at most kMaxBufferSize so that there's a reasonable bound.
- // - not larger than |bytes_so_far_| unless bytes_so_far_ is less than the
- // hash size.
+ // - not larger than |offset_| unless |offset_| is less than the hash size.
std::vector<char> buffer(std::max<int64_t>(
- kMinBufferSize, std::min<int64_t>(kMaxBufferSize, bytes_so_far_)));
+ kMinBufferSize, std::min<int64_t>(kMaxBufferSize, offset_)));
int64_t current_position = 0;
- while (current_position < bytes_so_far_) {
+ while (current_position < offset_) {
// While std::min needs to work with int64_t, the result is always at most
// kMaxBufferSize, which fits on an int.
int bytes_to_read =
- std::min<int64_t>(buffer.size(), bytes_so_far_ - current_position);
+ std::min<int64_t>(buffer.size(), offset_ - current_position);
int length = file_.ReadAtCurrentPos(&buffer.front(), bytes_to_read);
if (length == -1) {
return LogInterruptReason("Reading partial file",
@@ -245,7 +250,7 @@ DownloadInterruptReason BaseFile::CalculatePartialHash(
current_position += length;
}
- if (current_position != bytes_so_far_) {
+ if (current_position != offset_) {
return LogInterruptReason(
"Verifying prefix hash", 0, DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT);
}
@@ -286,7 +291,16 @@ DownloadInterruptReason BaseFile::Open(const std::string& hash_so_far) {
net_log_.BeginEvent(
net::NetLogEventType::DOWNLOAD_FILE_OPENED,
- base::Bind(&FileOpenedNetLogCallback, &full_path_, bytes_so_far_));
+ base::Bind(&FileOpenedNetLogCallback, &full_path_, offset_));
+
+ if (access_mode_ == SHARED) {
+ if (file_.Seek(base::File::FROM_BEGIN, offset_) < 0) {
+ logging::SystemErrorCode error = logging::GetLastSystemErrorCode();
+ ClearFile();
+ return LogSystemError("Seeking to end", error);
+ }
+ return DOWNLOAD_INTERRUPT_REASON_NONE;
+ }
if (!secure_hash_) {
DownloadInterruptReason reason = CalculatePartialHash(hash_so_far);
@@ -301,17 +315,17 @@ DownloadInterruptReason BaseFile::Open(const std::string& hash_so_far) {
logging::SystemErrorCode error = logging::GetLastSystemErrorCode();
ClearFile();
return LogSystemError("Seeking to end", error);
- } else if (file_size > bytes_so_far_) {
+ } else if (file_size > offset_) {
// The file is larger than we expected.
// This is OK, as long as we don't use the extra.
// Truncate the file.
- if (!file_.SetLength(bytes_so_far_) ||
- file_.Seek(base::File::FROM_BEGIN, bytes_so_far_) != bytes_so_far_) {
+ if (!file_.SetLength(offset_) ||
+ file_.Seek(base::File::FROM_BEGIN, offset_) != offset_) {
logging::SystemErrorCode error = logging::GetLastSystemErrorCode();
ClearFile();
return LogSystemError("Truncating to last known offset", error);
}
- } else if (file_size < bytes_so_far_) {
+ } else if (file_size < offset_) {
// The file is shorter than we expected. Our hashes won't be valid.
ClearFile();
return LogInterruptReason("Unable to seek to last written point", 0,

Powered by Google App Engine
This is Rietveld 408576698