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/webfilewriter_base.cc | |
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/webfilewriter_base.cc')
-rw-r--r-- | webkit/fileapi/webfilewriter_base.cc | 145 |
1 files changed, 145 insertions, 0 deletions
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 |