diff options
author | ericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-29 18:01:30 +0000 |
---|---|---|
committer | ericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-29 18:01:30 +0000 |
commit | d41c69dc6254efd7643d151d4265e996755ddb6c (patch) | |
tree | 24075a30988a2d72bb1241208924f766cbe8f3f4 /chrome | |
parent | c2bfb817511464d5d0fbcece69f25b5c8789dcab (diff) | |
download | chromium_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.gypi | 2 | ||||
-rw-r--r-- | chrome/common/file_system/file_system_dispatcher.cc | 52 | ||||
-rw-r--r-- | chrome/common/file_system/file_system_dispatcher.h | 12 | ||||
-rw-r--r-- | chrome/common/file_system/webfilesystem_impl.cc | 7 | ||||
-rw-r--r-- | chrome/common/file_system/webfilesystem_impl.h | 8 | ||||
-rw-r--r-- | chrome/common/file_system/webfilewriter_impl.cc | 150 | ||||
-rw-r--r-- | chrome/common/file_system/webfilewriter_impl.h | 71 |
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_ |