diff options
Diffstat (limited to 'chromium/content/browser/download/base_file.cc')
-rw-r--r-- | chromium/content/browser/download/base_file.cc | 111 |
1 files changed, 43 insertions, 68 deletions
diff --git a/chromium/content/browser/download/base_file.cc b/chromium/content/browser/download/base_file.cc index 1de3e842dd8..362f64ea1e0 100644 --- a/chromium/content/browser/download/base_file.cc +++ b/chromium/content/browser/download/base_file.cc @@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/file_util.h" +#include "base/files/file.h" #include "base/format_macros.h" #include "base/logging.h" #include "base/pickle.h" @@ -17,7 +18,6 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" #include "crypto/secure_hash.h" -#include "net/base/file_stream.h" #include "net/base/net_errors.h" namespace content { @@ -31,18 +31,18 @@ BaseFile::BaseFile(const base::FilePath& full_path, int64 received_bytes, bool calculate_hash, const std::string& hash_state_bytes, - scoped_ptr<net::FileStream> file_stream, + base::File file, const net::BoundNetLog& bound_net_log) : full_path_(full_path), source_url_(source_url), referrer_url_(referrer_url), - file_stream_(file_stream.Pass()), + file_(file.Pass()), bytes_so_far_(received_bytes), start_tick_(base::TimeTicks::Now()), calculate_hash_(calculate_hash), detached_(false), bound_net_log_(bound_net_log) { - memcpy(sha256_hash_, kEmptySha256Hash, kSha256HashLen); + memcpy(sha256_hash_, kEmptySha256Hash, crypto::kSHA256Length); if (calculate_hash_) { secure_hash_.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256)); if ((bytes_so_far_ > 0) && // Not starting at the beginning. @@ -67,11 +67,6 @@ DownloadInterruptReason BaseFile::Initialize( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); DCHECK(!detached_); - if (file_stream_) { - file_stream_->SetBoundNetLogSource(bound_net_log_); - file_stream_->EnableErrorStatistics(); - } - if (full_path_.empty()) { base::FilePath initial_directory(default_directory); base::FilePath temp_file; @@ -103,7 +98,7 @@ DownloadInterruptReason BaseFile::AppendDataToFile(const char* data, if (detached_) RecordDownloadCount(APPEND_TO_DETACHED_FILE_COUNT); - if (!file_stream_) + if (!file_.IsValid()) return LogInterruptReason("No file stream on append", 0, DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); @@ -117,19 +112,12 @@ DownloadInterruptReason BaseFile::AppendDataToFile(const char* data, const char* current_data = data; while (len > 0) { write_count++; - int write_result = - file_stream_->WriteSync(current_data, len); + int write_result = file_.WriteAtCurrentPos(current_data, len); DCHECK_NE(0, write_result); - // Check for errors. - if (static_cast<size_t>(write_result) != data_len) { - // We should never get ERR_IO_PENDING, as the Write above is synchronous. - DCHECK_NE(net::ERR_IO_PENDING, write_result); - - // Report errors on file writes. - if (write_result < 0) - return LogNetError("Write", static_cast<net::Error>(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); @@ -197,16 +185,17 @@ void BaseFile::Cancel() { if (!full_path_.empty()) { bound_net_log_.AddEvent(net::NetLog::TYPE_DOWNLOAD_FILE_DELETED); - base::DeleteFile(full_path_, false); } + + Detach(); } void BaseFile::Finish() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); if (calculate_hash_) - secure_hash_->Finish(sha256_hash_, kSha256HashLen); + secure_hash_->Finish(sha256_hash_, crypto::kSHA256Length); Close(); } @@ -243,8 +232,8 @@ std::string BaseFile::GetHashState() { // static bool BaseFile::IsEmptyHash(const std::string& hash) { - return (hash.size() == kSha256HashLen && - 0 == memcmp(hash.data(), kEmptySha256Hash, sizeof(kSha256HashLen))); + return (hash.size() == crypto::kSHA256Length && + 0 == memcmp(hash.data(), kEmptySha256Hash, crypto::kSHA256Length)); } std::string BaseFile::DebugString() const { @@ -258,11 +247,6 @@ std::string BaseFile::DebugString() const { detached_ ? 'T' : 'F'); } -void BaseFile::CreateFileStream() { - file_stream_.reset(new net::FileStream(bound_net_log_.net_log())); - file_stream_->SetBoundNetLogSource(bound_net_log_); -} - DownloadInterruptReason BaseFile::Open() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); DCHECK(!detached_); @@ -272,43 +256,36 @@ DownloadInterruptReason BaseFile::Open() { net::NetLog::TYPE_DOWNLOAD_FILE_OPENED, base::Bind(&FileOpenedNetLogCallback, &full_path_, bytes_so_far_)); - // Create a new file stream if it is not provided. - if (!file_stream_) { - CreateFileStream(); - file_stream_->EnableErrorStatistics(); - int open_result = file_stream_->OpenSync( - full_path_, - base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE); - if (open_result != net::OK) { - ClearStream(); - return LogNetError("Open", static_cast<net::Error>(open_result)); - } - - // We may be re-opening the file after rename. Always make sure we're - // writing at the end of the file. - int64 seek_result = file_stream_->SeekSync(net::FROM_END, 0); - if (seek_result < 0) { - ClearStream(); - return LogNetError("Seek", static_cast<net::Error>(seek_result)); + // Create a new file if it is not provided. + if (!file_.IsValid()) { + file_.Initialize( + full_path_, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE); + if (!file_.IsValid()) { + return LogNetError("Open", + net::FileErrorToNetError(file_.error_details())); } - } else { - file_stream_->SetBoundNetLogSource(bound_net_log_); } - int64 file_size = file_stream_->SeekSync(net::FROM_END, 0); - if (file_size > bytes_so_far_) { + // We may be re-opening the file after rename. Always make sure we're + // writing at the end of the file. + int64 file_size = file_.Seek(base::File::FROM_END, 0); + if (file_size < 0) { + logging::SystemErrorCode error = logging::GetLastSystemErrorCode(); + ClearFile(); + return LogSystemError("Seek", error); + } else if (file_size > bytes_so_far_) { // The file is larger than we expected. // This is OK, as long as we don't use the extra. // Truncate the file. - int64 truncate_result = file_stream_->Truncate(bytes_so_far_); - if (truncate_result < 0) - return LogNetError("Truncate", static_cast<net::Error>(truncate_result)); - - // If if wasn't an error, it should have truncated to the size - // specified. - DCHECK_EQ(bytes_so_far_, truncate_result); + if (!file_.SetLength(bytes_so_far_) || + file_.Seek(base::File::FROM_BEGIN, bytes_so_far_) != bytes_so_far_) { + logging::SystemErrorCode error = logging::GetLastSystemErrorCode(); + ClearFile(); + return LogSystemError("Truncate", error); + } } else if (file_size < bytes_so_far_) { // The file is shorter than we expected. Our hashes won't be valid. + ClearFile(); return LogInterruptReason("Unable to seek to last written point", 0, DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT); } @@ -321,20 +298,18 @@ void BaseFile::Close() { bound_net_log_.AddEvent(net::NetLog::TYPE_DOWNLOAD_FILE_CLOSED); - if (file_stream_) { -#if defined(OS_CHROMEOS) + if (file_.IsValid()) { // Currently we don't really care about the return value, since if it fails // theres not much we can do. But we might in the future. - file_stream_->FlushSync(); -#endif - ClearStream(); + file_.Flush(); + ClearFile(); } } -void BaseFile::ClearStream() { +void BaseFile::ClearFile() { // This should only be called when we have a stream. - DCHECK(file_stream_.get() != NULL); - file_stream_.reset(); + DCHECK(file_.IsValid()); + file_.Close(); bound_net_log_.EndEvent(net::NetLog::TYPE_DOWNLOAD_FILE_OPENED); } @@ -349,7 +324,7 @@ DownloadInterruptReason BaseFile::LogNetError( DownloadInterruptReason BaseFile::LogSystemError( const char* operation, - int os_error) { + logging::SystemErrorCode os_error) { // There's no direct conversion from a system error to an interrupt reason. net::Error net_error = net::MapSystemError(os_error); return LogInterruptReason( |