summaryrefslogtreecommitdiffstats
path: root/webkit/fileapi
diff options
context:
space:
mode:
authormichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-14 00:44:08 +0000
committermichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-14 00:44:08 +0000
commit2687ad7d62c737430aa780f9db9a0a166931a735 (patch)
tree5e5a5eb1a62948713721241ebf87bbd0690ac341 /webkit/fileapi
parent1dfff5c058db41e3b2caa74159ee7ed458bc9d69 (diff)
downloadchromium_src-2687ad7d62c737430aa780f9db9a0a166931a735.zip
chromium_src-2687ad7d62c737430aa780f9db9a0a166931a735.tar.gz
chromium_src-2687ad7d62c737430aa780f9db9a0a166931a735.tar.bz2
SimpleFileWriter for test_shell and DRT.
BUG=none TEST=manual Review URL: http://codereview.chromium.org/3683004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62486 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/fileapi')
-rw-r--r--webkit/fileapi/file_system_callback_dispatcher.h2
-rw-r--r--webkit/fileapi/webfilewriter_base.cc145
-rw-r--r--webkit/fileapi/webfilewriter_base.h69
-rw-r--r--webkit/fileapi/webkit_fileapi.gypi2
4 files changed, 218 insertions, 0 deletions
diff --git a/webkit/fileapi/file_system_callback_dispatcher.h b/webkit/fileapi/file_system_callback_dispatcher.h
index e33dd69..ea7c442 100644
--- a/webkit/fileapi/file_system_callback_dispatcher.h
+++ b/webkit/fileapi/file_system_callback_dispatcher.h
@@ -16,6 +16,8 @@ namespace fileapi {
// but uses chromium types.
class FileSystemCallbackDispatcher {
public:
+ virtual ~FileSystemCallbackDispatcher() {}
+
// Callback for various operations that don't require return values.
virtual void DidSucceed() = 0;
diff --git a/webkit/fileapi/webfilewriter_base.cc b/webkit/fileapi/webfilewriter_base.cc
new file mode 100644
index 0000000..9d3939f
--- /dev/null
+++ b/webkit/fileapi/webfilewriter_base.cc
@@ -0,0 +1,145 @@
+// 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 "webkit/fileapi/webfilewriter_base.h"
+
+#include "base/logging.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"
+
+namespace fileapi {
+
+WebFileWriterBase::WebFileWriterBase(
+ const WebKit::WebString& path, WebKit::WebFileWriterClient* client)
+ : path_(webkit_glue::WebStringToFilePath(path)),
+ client_(client),
+ operation_(kOperationNone),
+ cancel_state_(kCancelNotInProgress) {
+}
+
+WebFileWriterBase::~WebFileWriterBase() {
+}
+
+void WebFileWriterBase::truncate(long long length) {
+ DCHECK(kOperationNone == operation_);
+ DCHECK(kCancelNotInProgress == cancel_state_);
+ operation_ = kOperationTruncate;
+ DoTruncate(path_, length);
+}
+
+void WebFileWriterBase::write(
+ long long position,
+ const WebKit::WebURL& blob_url) {
+ DCHECK(kOperationNone == operation_);
+ DCHECK(kCancelNotInProgress == cancel_state_);
+ operation_ = kOperationWrite;
+ DoWrite(path_, blob_url, position);
+}
+
+// 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 WebFileWriterBase::cancel() {
+ DCHECK(kOperationWrite == operation_ || kOperationTruncate == operation_);
+ if (kCancelNotInProgress != cancel_state_)
+ return;
+ cancel_state_ = kCancelSent;
+ DoCancel();
+}
+
+void WebFileWriterBase::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 WebFileWriterBase::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 WebFileWriterBase::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();
+ }
+}
+
+void WebFileWriterBase::FinishCancel() {
+ DCHECK(kCancelReceivedWriteResponse == cancel_state_);
+ DCHECK(kOperationNone != operation_);
+ cancel_state_ = kCancelNotInProgress;
+ operation_ = kOperationNone;
+ client_->didFail(WebKit::WebFileErrorAbort);
+}
+
+} // namespace fileapi
diff --git a/webkit/fileapi/webfilewriter_base.h b/webkit/fileapi/webfilewriter_base.h
new file mode 100644
index 0000000..790e48b
--- /dev/null
+++ b/webkit/fileapi/webfilewriter_base.h
@@ -0,0 +1,69 @@
+// 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 WEBKIT_FILEAPI_WEBFILEWRITER_BASE_H_
+#define WEBKIT_FILEAPI_WEBFILEWRITER_BASE_H_
+
+#include "base/file_path.h"
+#include "base/platform_file.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFileWriter.h"
+
+class GURL;
+
+namespace WebKit {
+class WebFileWriterClient;
+class WebString;
+class WebURL;
+}
+
+namespace fileapi {
+
+class WebFileWriterBase : public WebKit::WebFileWriter {
+ public:
+ WebFileWriterBase(
+ const WebKit::WebString& path, WebKit::WebFileWriterClient* client);
+ virtual ~WebFileWriterBase();
+
+ // WebFileWriter implementation
+ virtual void truncate(long long length);
+ virtual void write(long long position, const WebKit::WebURL& blobURL);
+ virtual void cancel();
+
+ protected:
+ // Derived classes must provide these methods to asynchronously perform
+ // the requested operation, and they must call the appropiate DidSomething
+ // method upon completion and as progress is made in the Write case.
+ virtual void DoTruncate(const FilePath& path, int64 offset) = 0;
+ virtual void DoWrite(const FilePath& path, const GURL& blob_url,
+ int64 offset) = 0;
+ virtual void DoCancel() = 0;
+
+ void DidSucceed();
+ void DidFail(base::PlatformFileError error_code);
+ void DidWrite(int64 bytes, bool complete);
+
+ private:
+ enum OperationType {
+ kOperationNone,
+ kOperationWrite,
+ kOperationTruncate
+ };
+
+ enum CancelState {
+ kCancelNotInProgress,
+ kCancelSent,
+ kCancelReceivedWriteResponse,
+ };
+
+ void FinishCancel();
+
+ FilePath path_;
+ WebKit::WebFileWriterClient* client_;
+ OperationType operation_;
+ CancelState cancel_state_;
+};
+
+} // namespace fileapi
+
+#endif // WEBKIT_FILEAPI_WEBFILEWRITER_BASE_H_
diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi
index 5189564..73d49838 100644
--- a/webkit/fileapi/webkit_fileapi.gypi
+++ b/webkit/fileapi/webkit_fileapi.gypi
@@ -24,6 +24,8 @@
'file_system_types.h',
'file_writer_delegate.cc',
'file_writer_delegate.h',
+ 'webfilewriter_base.cc',
+ 'webfilewriter_base.h',
],
'conditions': [
['inside_chromium_build==0', {