summaryrefslogtreecommitdiffstats
path: root/webkit/fileapi/file_writer_delegate.cc
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-22 09:19:31 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-22 09:19:31 +0000
commit397a1f4db17560722bcb45108ccf7bf07fd5139f (patch)
tree4527d92f136e2e32c2cea613e69e1cd468cab89a /webkit/fileapi/file_writer_delegate.cc
parent1adcd7531107e881f31ce3f1cb18a87d94935347 (diff)
downloadchromium_src-397a1f4db17560722bcb45108ccf7bf07fd5139f.zip
chromium_src-397a1f4db17560722bcb45108ccf7bf07fd5139f.tar.gz
chromium_src-397a1f4db17560722bcb45108ccf7bf07fd5139f.tar.bz2
Implement SandboxFileWriter and rewrite FileWriterDelegate to use it
BUG=127529 TEST=FileWriterDelegate*, FileSystemOperationWrite* Review URL: https://chromiumcodereview.appspot.com/10387054 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138236 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/fileapi/file_writer_delegate.cc')
-rw-r--r--webkit/fileapi/file_writer_delegate.cc192
1 files changed, 33 insertions, 159 deletions
diff --git a/webkit/fileapi/file_writer_delegate.cc b/webkit/fileapi/file_writer_delegate.cc
index 283cbe0..d8c33ba 100644
--- a/webkit/fileapi/file_writer_delegate.cc
+++ b/webkit/fileapi/file_writer_delegate.cc
@@ -13,9 +13,7 @@
#include "base/threading/thread_restrictions.h"
#include "net/base/net_errors.h"
#include "webkit/fileapi/file_system_context.h"
-#include "webkit/fileapi/file_system_operation.h"
-#include "webkit/fileapi/file_system_operation_context.h"
-#include "webkit/fileapi/file_system_quota_util.h"
+#include "webkit/fileapi/file_writer.h"
namespace fileapi {
@@ -23,70 +21,30 @@ static const int kReadBufSize = 32768;
namespace {
-typedef base::Callback<void(base::PlatformFileError /* error code */,
- const base::PlatformFileInfo& /* file_info */)>
- InitializeTaskCallback;
-
-class InitializeTask : public base::RefCountedThreadSafe<InitializeTask> {
- public:
- InitializeTask(
- base::PlatformFile file,
- const InitializeTaskCallback& callback)
- : original_loop_(base::MessageLoopProxy::current()),
- error_code_(base::PLATFORM_FILE_OK),
- file_(file),
- callback_(callback) {
- DCHECK_EQ(false, callback.is_null());
- }
-
- bool Start(base::SequencedTaskRunner* task_runner,
- const tracked_objects::Location& from_here) {
- return task_runner->PostTask(
- from_here,
- base::Bind(&InitializeTask::ProcessOnTargetThread, this));
- }
-
- private:
- friend class base::RefCountedThreadSafe<InitializeTask>;
- ~InitializeTask() {}
-
- void RunCallback() {
- callback_.Run(error_code_, file_info_);
+base::PlatformFileError NetErrorToPlatformFileError(int error) {
+// TODO(kinuko): Move this static method to more convenient place.
+ switch (error) {
+ case net::ERR_FILE_NO_SPACE:
+ return base::PLATFORM_FILE_ERROR_NO_SPACE;
+ case net::ERR_FILE_NOT_FOUND:
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND;
+ case net::ERR_ACCESS_DENIED:
+ return base::PLATFORM_FILE_ERROR_ACCESS_DENIED;
+ default:
+ return base::PLATFORM_FILE_ERROR_FAILED;
}
+}
- void ProcessOnTargetThread() {
- if (!base::GetPlatformFileInfo(file_, &file_info_))
- error_code_ = base::PLATFORM_FILE_ERROR_FAILED;
- original_loop_->PostTask(
- FROM_HERE,
- base::Bind(&InitializeTask::RunCallback, this));
- }
-
- scoped_refptr<base::MessageLoopProxy> original_loop_;
- base::PlatformFileError error_code_;
-
- base::PlatformFile file_;
- InitializeTaskCallback callback_;
-
- base::PlatformFileInfo file_info_;
-};
-
-} // namespace (anonymous)
+} // namespace
FileWriterDelegate::FileWriterDelegate(
- FileSystemOperation* file_system_operation,
- const FileSystemPath& path,
- int64 offset)
- : file_system_operation_(file_system_operation),
- file_(base::kInvalidPlatformFileValue),
- path_(path),
- offset_(offset),
- has_pending_write_(false),
+ const FileSystemOperationInterface::WriteCallback& write_callback,
+ scoped_ptr<FileWriter> file_writer)
+ : write_callback_(write_callback),
+ file_writer_(file_writer.Pass()),
bytes_written_backlog_(0),
bytes_written_(0),
bytes_read_(0),
- total_bytes_written_(0),
- allowed_bytes_to_write_(0),
io_buffer_(new net::IOBufferWithSize(kReadBufSize)),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
}
@@ -94,44 +52,11 @@ FileWriterDelegate::FileWriterDelegate(
FileWriterDelegate::~FileWriterDelegate() {
}
-void FileWriterDelegate::OnGetFileInfoAndStartRequest(
- scoped_ptr<net::URLRequest> request,
- base::PlatformFileError error,
- const base::PlatformFileInfo& file_info) {
- if (error != base::PLATFORM_FILE_OK) {
- OnError(error);
- return;
- }
- int64 allowed_bytes_growth =
- file_system_operation_context()->allowed_bytes_growth();
- if (allowed_bytes_growth < 0)
- allowed_bytes_growth = 0;
- int64 overlap = file_info.size - offset_;
- allowed_bytes_to_write_ = allowed_bytes_growth;
- if (kint64max - overlap > allowed_bytes_growth)
- allowed_bytes_to_write_ += overlap;
- size_ = file_info.size;
- file_stream_.reset(new net::FileStream(
- file_,
- base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE |
- base::PLATFORM_FILE_ASYNC,
- NULL));
- DCHECK(!request_.get());
+void FileWriterDelegate::Start(scoped_ptr<net::URLRequest> request) {
request_ = request.Pass();
request_->Start();
}
-void FileWriterDelegate::Start(base::PlatformFile file,
- scoped_ptr<net::URLRequest> request) {
- file_ = file;
-
- scoped_refptr<InitializeTask> relay = new InitializeTask(
- file_,
- base::Bind(&FileWriterDelegate::OnGetFileInfoAndStartRequest,
- weak_factory_.GetWeakPtr(), base::Passed(&request)));
- relay->Start(file_system_operation_context()->file_task_runner(), FROM_HERE);
-}
-
bool FileWriterDelegate::Cancel() {
if (request_.get()) {
// This halts any callbacks on this delegate.
@@ -139,9 +64,12 @@ bool FileWriterDelegate::Cancel() {
request_->Cancel();
}
- // Return true to finish immediately if we're not writing.
- // Otherwise we'll do the final cleanup in the write callback.
- return !has_pending_write_;
+ const int status = file_writer_->Cancel(
+ base::Bind(&FileWriterDelegate::OnWriteCancelled,
+ weak_factory_.GetWeakPtr()));
+ // Return true to finish immediately if we have no pending writes.
+ // Otherwise we'll do the final cleanup in the Cancel callback.
+ return (status != net::ERR_IO_PENDING);
}
void FileWriterDelegate::OnReceivedRedirect(net::URLRequest* request,
@@ -173,18 +101,10 @@ void FileWriterDelegate::OnSSLCertificateError(net::URLRequest* request,
void FileWriterDelegate::OnResponseStarted(net::URLRequest* request) {
DCHECK_EQ(request_.get(), request);
- // file_stream_->Seek() blocks the IO thread.
- // See http://crbug.com/75548.
- base::ThreadRestrictions::ScopedAllowIO allow_io;
if (!request->status().is_success() || request->GetResponseCode() != 200) {
OnError(base::PLATFORM_FILE_ERROR_FAILED);
return;
}
- int64 error = file_stream_->SeekSync(net::FROM_BEGIN, offset_);
- if (error != offset_) {
- OnError(base::PLATFORM_FILE_ERROR_FAILED);
- return;
- }
Read();
}
@@ -201,8 +121,7 @@ void FileWriterDelegate::OnReadCompleted(net::URLRequest* request,
void FileWriterDelegate::Read() {
bytes_written_ = 0;
bytes_read_ = 0;
- if (request_->Read(io_buffer_.get(), io_buffer_->size(),
- &bytes_read_)) {
+ if (request_->Read(io_buffer_.get(), io_buffer_->size(), &bytes_read_)) {
MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&FileWriterDelegate::OnDataReceived,
@@ -226,24 +145,9 @@ void FileWriterDelegate::OnDataReceived(int bytes_read) {
}
void FileWriterDelegate::Write() {
- // allowed_bytes_to_write could be negative if the file size is
- // greater than the current (possibly new) quota.
- // (The UI should clear the entire origin data if the smaller quota size
- // is set in general, though the UI/deletion code is not there yet.)
- DCHECK(total_bytes_written_ <= allowed_bytes_to_write_ ||
- allowed_bytes_to_write_ < 0);
- if (total_bytes_written_ >= allowed_bytes_to_write_) {
- OnError(base::PLATFORM_FILE_ERROR_NO_SPACE);
- return;
- }
-
int64 bytes_to_write = bytes_read_ - bytes_written_;
- if (bytes_to_write > allowed_bytes_to_write_ - total_bytes_written_)
- bytes_to_write = allowed_bytes_to_write_ - total_bytes_written_;
-
- has_pending_write_ = true;
int write_response =
- file_stream_->Write(cursor_,
+ file_writer_->Write(cursor_,
static_cast<int>(bytes_to_write),
base::Bind(&FileWriterDelegate::OnDataWritten,
weak_factory_.GetWeakPtr()));
@@ -253,26 +157,20 @@ void FileWriterDelegate::Write() {
base::Bind(&FileWriterDelegate::OnDataWritten,
weak_factory_.GetWeakPtr(), write_response));
else if (net::ERR_IO_PENDING != write_response)
- OnError(base::PLATFORM_FILE_ERROR_FAILED);
+ OnError(NetErrorToPlatformFileError(write_response));
}
void FileWriterDelegate::OnDataWritten(int write_response) {
- has_pending_write_ = false;
if (write_response > 0) {
- if (request_->status().status() == net::URLRequestStatus::CANCELED) {
- OnProgress(write_response, true);
- return;
- }
OnProgress(write_response, false);
cursor_->DidConsume(write_response);
bytes_written_ += write_response;
- total_bytes_written_ += write_response;
if (bytes_written_ == bytes_read_)
Read();
else
Write();
} else {
- OnError(base::PLATFORM_FILE_ERROR_FAILED);
+ OnError(NetErrorToPlatformFileError(write_response));
}
}
@@ -282,22 +180,11 @@ void FileWriterDelegate::OnError(base::PlatformFileError error) {
request_->Cancel();
}
- file_system_operation_->DidWrite(error, 0, true);
+ write_callback_.Run(error, 0, true);
}
void FileWriterDelegate::OnProgress(int bytes_written, bool done) {
DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_);
- if (quota_util() &&
- bytes_written > 0 &&
- total_bytes_written_ + bytes_written + offset_ > size_) {
- int overlapped = 0;
- if (total_bytes_written_ + offset_ < size_)
- overlapped = size_ - total_bytes_written_ - offset_;
- quota_util()->proxy()->UpdateOriginUsage(
- file_system_operation_->file_system_context()->quota_manager_proxy(),
- path_.origin(), path_.type(),
- bytes_written - overlapped);
- }
static const int kMinProgressDelayMS = 200;
base::Time currentTime = base::Time::Now();
if (done || last_progress_event_time_.is_null() ||
@@ -306,28 +193,15 @@ void FileWriterDelegate::OnProgress(int bytes_written, bool done) {
bytes_written += bytes_written_backlog_;
last_progress_event_time_ = currentTime;
bytes_written_backlog_ = 0;
- if (done && quota_util())
- quota_util()->proxy()->EndUpdateOrigin(path_.origin(), path_.type());
- file_system_operation_->DidWrite(
+ write_callback_.Run(
base::PLATFORM_FILE_OK, bytes_written, done);
return;
}
bytes_written_backlog_ += bytes_written;
}
-FileSystemOperationContext*
-FileWriterDelegate::file_system_operation_context() const {
- DCHECK(file_system_operation_);
- DCHECK(file_system_operation_->file_system_operation_context());
- return file_system_operation_->file_system_operation_context();
-}
-
-FileSystemQuotaUtil* FileWriterDelegate::quota_util() const {
- DCHECK(file_system_operation_);
- DCHECK(file_system_operation_->file_system_context());
- DCHECK(file_system_operation_->file_system_operation_context());
- return file_system_operation_->file_system_context()->GetQuotaUtil(
- path_.type());
+void FileWriterDelegate::OnWriteCancelled(int status) {
+ write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, true);
}
} // namespace fileapi