diff options
author | michaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-14 00:44:08 +0000 |
---|---|---|
committer | michaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-14 00:44:08 +0000 |
commit | 2687ad7d62c737430aa780f9db9a0a166931a735 (patch) | |
tree | 5e5a5eb1a62948713721241ebf87bbd0690ac341 /webkit/fileapi | |
parent | 1dfff5c058db41e3b2caa74159ee7ed458bc9d69 (diff) | |
download | chromium_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.h | 2 | ||||
-rw-r--r-- | webkit/fileapi/webfilewriter_base.cc | 145 | ||||
-rw-r--r-- | webkit/fileapi/webfilewriter_base.h | 69 | ||||
-rw-r--r-- | webkit/fileapi/webkit_fileapi.gypi | 2 |
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', { |