summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-29 18:01:30 +0000
committerericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-29 18:01:30 +0000
commitd41c69dc6254efd7643d151d4265e996755ddb6c (patch)
tree24075a30988a2d72bb1241208924f766cbe8f3f4 /chrome
parentc2bfb817511464d5d0fbcece69f25b5c8789dcab (diff)
downloadchromium_src-d41c69dc6254efd7643d151d4265e996755ddb6c.zip
chromium_src-d41c69dc6254efd7643d151d4265e996755ddb6c.tar.gz
chromium_src-d41c69dc6254efd7643d151d4265e996755ddb6c.tar.bz2
This adds WebFileWriterImpl, which implements WebFileWriter and AsyncFileWriterClient.
BUG=none TEST=none Review URL: http://codereview.chromium.org/3397030 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60964 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/chrome_common.gypi2
-rw-r--r--chrome/common/file_system/file_system_dispatcher.cc52
-rw-r--r--chrome/common/file_system/file_system_dispatcher.h12
-rw-r--r--chrome/common/file_system/webfilesystem_impl.cc7
-rw-r--r--chrome/common/file_system/webfilesystem_impl.h8
-rw-r--r--chrome/common/file_system/webfilewriter_impl.cc150
-rw-r--r--chrome/common/file_system/webfilewriter_impl.h71
7 files changed, 302 insertions, 0 deletions
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index b3b085a3..cc9e2c6 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -56,6 +56,8 @@
'common/file_system/webfilesystem_callback_dispatcher.h',
'common/file_system/webfilesystem_impl.cc',
'common/file_system/webfilesystem_impl.h',
+ 'common/file_system/webfilewriter_impl.cc',
+ 'common/file_system/webfilewriter_impl.h',
'common/font_descriptor_mac.h',
'common/font_descriptor_mac.mm',
'common/geoposition.cc',
diff --git a/chrome/common/file_system/file_system_dispatcher.cc b/chrome/common/file_system/file_system_dispatcher.cc
index 0e46c97..7159e3c 100644
--- a/chrome/common/file_system/file_system_dispatcher.cc
+++ b/chrome/common/file_system/file_system_dispatcher.cc
@@ -33,6 +33,7 @@ bool FileSystemDispatcher::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewMsg_FileSystem_DidReadDirectory, DidReadDirectory)
IPC_MESSAGE_HANDLER(ViewMsg_FileSystem_DidReadMetadata, DidReadMetadata)
IPC_MESSAGE_HANDLER(ViewMsg_FileSystem_DidFail, DidFail)
+ IPC_MESSAGE_HANDLER(ViewMsg_FileSystem_DidWrite, DidWrite)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -108,6 +109,46 @@ bool FileSystemDispatcher::ReadDirectory(
new ViewHostMsg_FileSystem_ReadDirectory(request_id, path));
}
+bool FileSystemDispatcher::Truncate(
+ const FilePath& path,
+ int64 offset,
+ int* request_id_out,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ int request_id = dispatchers_.Add(dispatcher);
+ if (ChildThread::current()->Send(
+ new ViewHostMsg_FileSystem_Truncate(request_id, path, offset))) {
+ if (request_id_out)
+ *request_id_out = request_id;
+ return true;
+ }
+ return false;
+}
+
+bool FileSystemDispatcher::Write(
+ const FilePath& path,
+ const GURL& blob_url,
+ int64 offset,
+ int* request_id_out,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ int request_id = dispatchers_.Add(dispatcher);
+ if (ChildThread::current()->Send(
+ new ViewHostMsg_FileSystem_Write(
+ request_id, path, blob_url, offset))) {
+ if (request_id_out)
+ *request_id_out = request_id;
+ return true;
+ }
+ return false;
+}
+
+bool FileSystemDispatcher::Cancel(
+ int request_id_to_cancel,
+ fileapi::FileSystemCallbackDispatcher* dispatcher) {
+ int request_id = dispatchers_.Add(dispatcher);
+ return ChildThread::current()->Send(
+ new ViewHostMsg_FileSystem_CancelWrite(request_id, request_id_to_cancel));
+}
+
bool FileSystemDispatcher::TouchFile(
const FilePath& path,
const base::Time& last_access_time,
@@ -168,3 +209,14 @@ void FileSystemDispatcher::DidFail(
dispatcher->DidFail(error_code);
dispatchers_.Remove(request_id);
}
+
+void FileSystemDispatcher::DidWrite(
+ int request_id, int64 bytes, bool complete) {
+ fileapi::FileSystemCallbackDispatcher* dispatcher =
+ dispatchers_.Lookup(request_id);
+ DCHECK(dispatcher);
+ // TODO(ericu): Coming soon.
+ // dispatcher->DidWrite(bytes, complete);
+ if (complete)
+ dispatchers_.Remove(request_id);
+}
diff --git a/chrome/common/file_system/file_system_dispatcher.h b/chrome/common/file_system/file_system_dispatcher.h
index ec20e6d..80443c4 100644
--- a/chrome/common/file_system/file_system_dispatcher.h
+++ b/chrome/common/file_system/file_system_dispatcher.h
@@ -56,6 +56,17 @@ class FileSystemDispatcher {
fileapi::FileSystemCallbackDispatcher* dispatcher);
bool ReadDirectory(const FilePath& path,
fileapi::FileSystemCallbackDispatcher* dispatcher);
+ bool Truncate(const FilePath& path,
+ int64 offset,
+ int* request_id_out,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ bool Write(const FilePath& path,
+ const GURL& blob_url,
+ int64 offset,
+ int* request_id_out,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
+ bool Cancel(int request_id_to_cancel,
+ fileapi::FileSystemCallbackDispatcher* dispatcher);
bool TouchFile(const FilePath& file_path,
const base::Time& last_access_time,
const base::Time& last_modified_time,
@@ -78,6 +89,7 @@ class FileSystemDispatcher {
const std::vector<base::file_util_proxy::Entry>& entries,
bool has_more);
void DidFail(int request_id, base::PlatformFileError error_code);
+ void DidWrite(int request_id, int64 bytes, bool complete);
IDMap<fileapi::FileSystemCallbackDispatcher, IDMapOwnPointer> dispatchers_;
diff --git a/chrome/common/file_system/webfilesystem_impl.cc b/chrome/common/file_system/webfilesystem_impl.cc
index b7940c8..9128cf1 100644
--- a/chrome/common/file_system/webfilesystem_impl.cc
+++ b/chrome/common/file_system/webfilesystem_impl.cc
@@ -6,6 +6,7 @@
#include "chrome/common/file_system/file_system_dispatcher.h"
#include "chrome/common/file_system/webfilesystem_callback_dispatcher.h"
+#include "chrome/common/file_system/webfilewriter_impl.h"
#include "chrome/common/child_thread.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileInfo.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileSystemCallbacks.h"
@@ -98,3 +99,9 @@ void WebFileSystemImpl::readDirectory(const WebString& path,
dispatcher->ReadDirectory(webkit_glue::WebStringToFilePath(path),
new WebFileSystemCallbackDispatcher(callbacks));
}
+
+WebKit::WebFileWriter* WebFileSystemImpl::createFileWriter(
+ const WebString& path, WebKit::WebFileWriterClient* client) {
+ return new WebFileWriterImpl(path, client);
+}
+
diff --git a/chrome/common/file_system/webfilesystem_impl.h b/chrome/common/file_system/webfilesystem_impl.h
index 8ca67ab..6892eac 100644
--- a/chrome/common/file_system/webfilesystem_impl.h
+++ b/chrome/common/file_system/webfilesystem_impl.h
@@ -8,6 +8,11 @@
#include "base/basictypes.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileSystem.h"
+namespace WebKit {
+class WebFileWriter;
+class WebFileWriterClient;
+}
+
class WebFileSystemImpl : public WebKit::WebFileSystem {
public:
WebFileSystemImpl();
@@ -52,6 +57,9 @@ class WebFileSystemImpl : public WebKit::WebFileSystem {
virtual void readDirectory(
const WebKit::WebString& path,
WebKit::WebFileSystemCallbacks*);
+
+ virtual WebKit::WebFileWriter* createFileWriter(
+ const WebKit::WebString& path, WebKit::WebFileWriterClient*);
};
#endif // CHROME_COMMON_FILE_SYSTEM_WEBFILESYSTEM_IMPL_H_
diff --git a/chrome/common/file_system/webfilewriter_impl.cc b/chrome/common/file_system/webfilewriter_impl.cc
new file mode 100644
index 0000000..6894e30
--- /dev/null
+++ b/chrome/common/file_system/webfilewriter_impl.cc
@@ -0,0 +1,150 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/file_system/webfilewriter_impl.h"
+
+#include "chrome/common/child_thread.h"
+#include "chrome/common/file_system/file_system_util.h"
+#include "chrome/common/file_system/webfilesystem_impl.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFileError.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFileWriterClient.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
+#include "webkit/glue/webkit_glue.h"
+
+WebFileWriterImpl::WebFileWriterImpl(
+ const WebKit::WebString& path, WebKit::WebFileWriterClient* client)
+ : path_(webkit_glue::WebStringToFilePath(path)),
+ client_(client),
+ operation_(kOperationNone),
+ cancel_state_(kCancelNotInProgress) {
+}
+
+WebFileWriterImpl::~WebFileWriterImpl() {
+}
+
+void WebFileWriterImpl::truncate(
+ int64 length) {
+ DCHECK(kOperationNone == operation_);
+ DCHECK(kCancelNotInProgress == cancel_state_);
+ operation_ = kOperationTruncate;
+ FileSystemDispatcher* dispatcher =
+ ChildThread::current()->file_system_dispatcher();
+ dispatcher->Truncate(path_, length, &request_id_, this);
+}
+
+void WebFileWriterImpl::write(
+ int64 position,
+ const WebKit::WebURL& blob_url) {
+ DCHECK(kOperationNone == operation_);
+ DCHECK(kCancelNotInProgress == cancel_state_);
+ operation_ = kOperationWrite;
+ FileSystemDispatcher* dispatcher =
+ ChildThread::current()->file_system_dispatcher();
+ dispatcher->Write(path_, blob_url, position, &request_id_, this);
+}
+
+// When we cancel a write/truncate, we always get back the result of the write
+// before the result of the cancel, no matter what happens.
+// So we'll get back either
+// success [of the write/truncate, in a DidWrite(XXX, true)/DidSucceed() call]
+// followed by failure [of the cancel]; or
+// failure [of the write, either from cancel or other reasons] followed by
+// the result of the cancel.
+// In the write case, there could also be queued up non-terminal DidWrite calls
+// before any of that comes back, but there will always be a terminal write
+// response [success or failure] after them, followed by the cancel result, so
+// we can ignore non-terminal write responses, take the terminal write success
+// or the first failure as the last write response, then know that the next
+// thing to come back is the cancel response. We only notify the
+// AsyncFileWriterClient when it's all over.
+void WebFileWriterImpl::cancel() {
+ DCHECK(kOperationWrite == operation_ || kOperationTruncate == operation_);
+ if (kCancelNotInProgress != cancel_state_)
+ return;
+ cancel_state_ = kCancelSent;
+ FileSystemDispatcher* dispatcher =
+ ChildThread::current()->file_system_dispatcher();
+ dispatcher->Cancel(request_id_, this);
+}
+
+void WebFileWriterImpl::FinishCancel() {
+ DCHECK(kCancelReceivedWriteResponse == cancel_state_);
+ DCHECK(kOperationNone != operation_);
+ cancel_state_ = kCancelNotInProgress;
+ operation_ = kOperationNone;
+ client_->didFail(WebKit::WebFileErrorAbort);
+}
+
+void WebFileWriterImpl::DidSucceed() {
+ // Write never gets a DidSucceed call, so this is either a cancel or truncate
+ // response.
+ switch (cancel_state_) {
+ case kCancelNotInProgress:
+ // A truncate succeeded, with no complications.
+ DCHECK(kOperationTruncate == operation_);
+ operation_ = kOperationNone;
+ client_->didTruncate();
+ break;
+ case kCancelSent:
+ DCHECK(kOperationTruncate == operation_);
+ // This is the success call of the truncate, which we'll eat, even though
+ // it succeeded before the cancel got there. We accepted the cancel call,
+ // so the truncate will eventually return an error.
+ cancel_state_ = kCancelReceivedWriteResponse;
+ break;
+ case kCancelReceivedWriteResponse:
+ // This is the success of the cancel operation.
+ FinishCancel();
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+void WebFileWriterImpl::DidFail(base::PlatformFileError error_code) {
+ DCHECK(kOperationNone != operation_);
+ switch (cancel_state_) {
+ case kCancelNotInProgress:
+ // A write or truncate failed.
+ operation_ = kOperationNone;
+ client_->didFail(
+ webkit_glue::PlatformFileErrorToWebFileError(error_code));
+ break;
+ case kCancelSent:
+ // This is the failure of a write or truncate; the next message should be
+ // the result of the cancel. We don't assume that it'll be a success, as
+ // the write/truncate could have failed for other reasons.
+ cancel_state_ = kCancelReceivedWriteResponse;
+ break;
+ case kCancelReceivedWriteResponse:
+ // The cancel reported failure, meaning that the write or truncate
+ // finished before the cancel got there. But we suppressed the
+ // write/truncate's response, and will now report that it was cancelled.
+ FinishCancel();
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+void WebFileWriterImpl::DidWrite(int64 bytes, bool complete) {
+ DCHECK(kOperationWrite == operation_);
+ switch (cancel_state_) {
+ case kCancelNotInProgress:
+ if (complete)
+ operation_ = kOperationNone;
+ client_->didWrite(bytes, complete);
+ break;
+ case kCancelSent:
+ // This is the success call of the write, which we'll eat, even though
+ // it succeeded before the cancel got there. We accepted the cancel call,
+ // so the write will eventually return an error.
+ if (complete)
+ cancel_state_ = kCancelReceivedWriteResponse;
+ break;
+ case kCancelReceivedWriteResponse:
+ default:
+ NOTREACHED();
+ }
+}
diff --git a/chrome/common/file_system/webfilewriter_impl.h b/chrome/common/file_system/webfilewriter_impl.h
new file mode 100644
index 0000000..42e52e7
--- /dev/null
+++ b/chrome/common/file_system/webfilewriter_impl.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_FILE_SYSTEM_WEBFILEWRITER_IMPL_H_
+#define CHROME_COMMON_FILE_SYSTEM_WEBFILEWRITER_IMPL_H_
+
+#include "base/basictypes.h"
+#include "chrome/common/file_system/file_system_dispatcher.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFileWriter.h"
+
+namespace WebKit {
+class WebFileWriterClient;
+class WebString;
+class WebURL;
+}
+
+class WebFileWriterImpl
+ : public WebKit::WebFileWriter,
+ public fileapi::FileSystemCallbackDispatcher {
+
+ public:
+ WebFileWriterImpl(
+ const WebKit::WebString& path, WebKit::WebFileWriterClient* client);
+ virtual ~WebFileWriterImpl();
+
+ // WebFileWriter implementation
+ virtual void truncate(int64 length);
+ virtual void write(int64 position, const WebKit::WebURL& blobURL);
+ virtual void cancel();
+
+ // FileSystemCallbackDispatcher implementation
+ virtual void DidReadMetadata(const base::PlatformFileInfo&) {
+ NOTREACHED();
+ }
+ virtual void DidReadDirectory(
+ const std::vector<base::file_util_proxy::Entry>& entries,
+ bool has_more) {
+ NOTREACHED();
+ }
+ virtual void DidOpenFileSystem(const std::string& name,
+ const FilePath& root_path) {
+ NOTREACHED();
+ }
+ virtual void DidSucceed();
+ virtual void DidFail(base::PlatformFileError error_code);
+ virtual void DidWrite(int64 bytes, bool complete);
+
+ private:
+ enum OperationType {
+ kOperationNone,
+ kOperationWrite,
+ kOperationTruncate
+ };
+
+ enum CancelState {
+ kCancelNotInProgress,
+ kCancelSent,
+ kCancelReceivedWriteResponse,
+ };
+
+ void FinishCancel();
+
+ FilePath path_;
+ WebKit::WebFileWriterClient* client_;
+ int request_id_;
+ OperationType operation_;
+ CancelState cancel_state_;
+};
+
+#endif // CHROME_COMMON_FILE_SYSTEM_WEBFILEWRITER_IMPL_H_