From f05ca65c8857804c078f06b260f3175493dd4720 Mon Sep 17 00:00:00 2001 From: "kkanetkar@chromium.org" Date: Thu, 16 Sep 2010 04:46:14 +0000 Subject: Test shell impl for WebKit's File System API:BUG=52799TEST=none Also refactored a bunch of code from chrome/browser to webkit/fileapi for reuse. Added class hierarchy. Test shell and browser operations now inherit from common webkit/fileapi/file_system_operation. Review URL: http://codereview.chromium.org/3186009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59616 0039d316-1c4b-4281-b951-d872f2087c98 --- webkit/fileapi/file_system_operation.cc | 192 ++++++++++++++++++++++++++ webkit/fileapi/file_system_operation.h | 99 +++++++++++++ webkit/fileapi/file_system_operation_client.h | 39 ++++++ webkit/fileapi/webkit_fileapi.gypi | 31 +++++ 4 files changed, 361 insertions(+) create mode 100644 webkit/fileapi/file_system_operation.cc create mode 100644 webkit/fileapi/file_system_operation.h create mode 100644 webkit/fileapi/file_system_operation_client.h create mode 100644 webkit/fileapi/webkit_fileapi.gypi (limited to 'webkit/fileapi') diff --git a/webkit/fileapi/file_system_operation.cc b/webkit/fileapi/file_system_operation.cc new file mode 100644 index 0000000..90eabad --- /dev/null +++ b/webkit/fileapi/file_system_operation.cc @@ -0,0 +1,192 @@ +// 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/file_system_operation.h" + +#include "webkit/fileapi/file_system_operation_client.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFileError.h" + +namespace { +// Utility method for error conversions. +WebKit::WebFileError PlatformFileErrorToWebFileError( + base::PlatformFileError rv) { + switch (rv) { + case base::PLATFORM_FILE_ERROR_NOT_FOUND: + return WebKit::WebFileErrorNotFound; + case base::PLATFORM_FILE_ERROR_INVALID_OPERATION: + case base::PLATFORM_FILE_ERROR_EXISTS: + case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY: + return WebKit::WebFileErrorInvalidModification; + case base::PLATFORM_FILE_ERROR_ACCESS_DENIED: + return WebKit::WebFileErrorNoModificationAllowed; + default: + return WebKit::WebFileErrorInvalidModification; + } +} +} // namespace + +namespace fileapi { + +FileSystemOperation::FileSystemOperation( + FileSystemOperationClient* client, + scoped_refptr proxy) + : proxy_(proxy), + client_(client), + callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + operation_pending_(false) { + DCHECK(client_); +} + +void FileSystemOperation::CreateFile(const FilePath& path, + bool exclusive) { + DCHECK(!operation_pending_); + operation_pending_ = true; + base::FileUtilProxy::CreateOrOpen( + proxy_, path, base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_READ, + callback_factory_.NewCallback( + exclusive ? &FileSystemOperation::DidCreateFileExclusive + : &FileSystemOperation::DidCreateFileNonExclusive)); +} + +void FileSystemOperation::CreateDirectory(const FilePath& path, + bool exclusive) { + DCHECK(!operation_pending_); + operation_pending_ = true; + base::FileUtilProxy::CreateDirectory(proxy_, path, exclusive, + false /* recursive */, callback_factory_.NewCallback( + &FileSystemOperation::DidFinishFileOperation)); +} + +void FileSystemOperation::Copy(const FilePath& src_path, + const FilePath& dest_path) { + DCHECK(!operation_pending_); + operation_pending_ = true; + base::FileUtilProxy::Copy(proxy_, src_path, dest_path, + callback_factory_.NewCallback( + &FileSystemOperation::DidFinishFileOperation)); +} + +void FileSystemOperation::Move(const FilePath& src_path, + const FilePath& dest_path) { + DCHECK(!operation_pending_); + operation_pending_ = true; + base::FileUtilProxy::Move(proxy_, src_path, dest_path, + callback_factory_.NewCallback( + &FileSystemOperation::DidFinishFileOperation)); +} + +void FileSystemOperation::DirectoryExists(const FilePath& path) { + DCHECK(!operation_pending_); + operation_pending_ = true; + base::FileUtilProxy::GetFileInfo(proxy_, path, callback_factory_.NewCallback( + &FileSystemOperation::DidDirectoryExists)); +} + +void FileSystemOperation::FileExists(const FilePath& path) { + DCHECK(!operation_pending_); + operation_pending_ = true; + base::FileUtilProxy::GetFileInfo(proxy_, path, callback_factory_.NewCallback( + &FileSystemOperation::DidFileExists)); +} + +void FileSystemOperation::GetMetadata(const FilePath& path) { + DCHECK(!operation_pending_); + operation_pending_ = true; + base::FileUtilProxy::GetFileInfo(proxy_, path, callback_factory_.NewCallback( + &FileSystemOperation::DidGetMetadata)); +} + +void FileSystemOperation::ReadDirectory(const FilePath& path) { + DCHECK(!operation_pending_); + operation_pending_ = true; + base::FileUtilProxy::ReadDirectory(proxy_, path, + callback_factory_.NewCallback( + &FileSystemOperation::DidReadDirectory)); +} + +void FileSystemOperation::Remove(const FilePath& path) { + DCHECK(!operation_pending_); + operation_pending_ = true; + base::FileUtilProxy::Delete(proxy_, path, callback_factory_.NewCallback( + &FileSystemOperation::DidFinishFileOperation)); +} + +void FileSystemOperation::DidCreateFileExclusive( + base::PlatformFileError rv, + base::PassPlatformFile file, + bool created) { + DidFinishFileOperation(rv); +} + +void FileSystemOperation::DidCreateFileNonExclusive( + base::PlatformFileError rv, + base::PassPlatformFile file, + bool created) { + // Suppress the already exists error and report success. + if (rv == base::PLATFORM_FILE_OK || + rv == base::PLATFORM_FILE_ERROR_EXISTS) + client_->DidSucceed(this); + else + client_->DidFail(PlatformFileErrorToWebFileError(rv), this); +} + +void FileSystemOperation::DidFinishFileOperation( + base::PlatformFileError rv) { + if (rv == base::PLATFORM_FILE_OK) + client_->DidSucceed(this); + else + client_->DidFail(PlatformFileErrorToWebFileError(rv), this); +} + +void FileSystemOperation::DidDirectoryExists( + base::PlatformFileError rv, + const base::PlatformFileInfo& file_info) { + if (rv == base::PLATFORM_FILE_OK) { + if (file_info.is_directory) + client_->DidSucceed(this); + else + client_->DidFail(WebKit::WebFileErrorInvalidState, + this); + } else { + // Something else went wrong. + client_->DidFail(PlatformFileErrorToWebFileError(rv), this); + } +} + +void FileSystemOperation::DidFileExists( + base::PlatformFileError rv, + const base::PlatformFileInfo& file_info) { + if (rv == base::PLATFORM_FILE_OK) { + if (file_info.is_directory) + client_->DidFail(WebKit::WebFileErrorInvalidState, + this); + else + client_->DidSucceed(this); + } else { + // Something else went wrong. + client_->DidFail(PlatformFileErrorToWebFileError(rv), this); + } +} + +void FileSystemOperation::DidGetMetadata( + base::PlatformFileError rv, + const base::PlatformFileInfo& file_info) { + if (rv == base::PLATFORM_FILE_OK) + client_->DidReadMetadata(file_info, this); + else + client_->DidFail(PlatformFileErrorToWebFileError(rv), this); +} + +void FileSystemOperation::DidReadDirectory( + base::PlatformFileError rv, + const std::vector& entries) { + if (rv == base::PLATFORM_FILE_OK) + client_->DidReadDirectory( + entries, false /* has_more */ , this); + else + client_->DidFail(PlatformFileErrorToWebFileError(rv), this); +} + +} // namespace fileapi + diff --git a/webkit/fileapi/file_system_operation.h b/webkit/fileapi/file_system_operation.h new file mode 100644 index 0000000..f9431c9 --- /dev/null +++ b/webkit/fileapi/file_system_operation.h @@ -0,0 +1,99 @@ +// 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_FILE_SYSTEM_OPERATION_H_ +#define WEBKIT_FILEAPI_FILE_SYSTEM_OPERATION_H_ + +#include + +#include "base/file_path.h" +#include "base/file_util_proxy.h" +#include "base/message_loop_proxy.h" +#include "base/platform_file.h" +#include "base/ref_counted.h" +#include "base/scoped_callback_factory.h" + +namespace fileapi { + +class FileSystemOperationClient; + +// This class is designed to serve one-time file system operation per instance. +// Each operation method (CreateFile, CreateDirectory, Copy, Move, +// DirectoryExists, GetMetadata, ReadDirectory and Remove) must be called +// only once in its lifetime. +class FileSystemOperation { + public: + FileSystemOperation( + FileSystemOperationClient* client, + scoped_refptr proxy); + + void CreateFile(const FilePath& path, + bool exclusive); + + void CreateDirectory(const FilePath& path, + bool exclusive); + + void Copy(const FilePath& src_path, + const FilePath& dest_path); + + // If |dest_path| exists and is a directory, behavior is unspecified or + // varies for different platforms. TODO(kkanetkar): Fix this as per spec + // when it is addressed in spec. + void Move(const FilePath& src_path, + const FilePath& dest_path); + + void DirectoryExists(const FilePath& path); + + void FileExists(const FilePath& path); + + void GetMetadata(const FilePath& path); + + void ReadDirectory(const FilePath& path); + + void Remove(const FilePath& path); + + protected: + // Proxy for calling file_util_proxy methods. + scoped_refptr proxy_; + + private: + // Callbacks for above methods. + void DidCreateFileExclusive( + base::PlatformFileError rv, base::PassPlatformFile file, bool created); + + // Returns success even if the file already existed. + void DidCreateFileNonExclusive( + base::PlatformFileError rv, base::PassPlatformFile file, bool created); + + // Generic callback that translates platform errors to WebKit error codes. + void DidFinishFileOperation(base::PlatformFileError rv); + + void DidDirectoryExists(base::PlatformFileError rv, + const base::PlatformFileInfo& file_info); + + void DidFileExists(base::PlatformFileError rv, + const base::PlatformFileInfo& file_info); + + void DidGetMetadata(base::PlatformFileError rv, + const base::PlatformFileInfo& file_info); + + void DidReadDirectory( + base::PlatformFileError rv, + const std::vector& entries); + + // Not owned. + FileSystemOperationClient* client_; + + base::ScopedCallbackFactory callback_factory_; + + // A flag to make sure we call operation only once per instance. + bool operation_pending_; + + DISALLOW_COPY_AND_ASSIGN(FileSystemOperation); +}; + +} // namespace fileapi + +#endif // WEBKIT_FILEAPI_FILE_SYSTEM_OPERATION_H_ + diff --git a/webkit/fileapi/file_system_operation_client.h b/webkit/fileapi/file_system_operation_client.h new file mode 100644 index 0000000..b126d4e --- /dev/null +++ b/webkit/fileapi/file_system_operation_client.h @@ -0,0 +1,39 @@ +// 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_FILE_SYSTEM_OPERATION_CLIENT_H_ +#define WEBKIT_FILEAPI_FILE_SYSTEM_OPERATION_CLIENT_H_ + +#include + +#include "base/file_util_proxy.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFileError.h" + +namespace fileapi { + +class FileSystemOperation; + +// Interface for client of FileSystemOperation. +class FileSystemOperationClient { + public: + virtual ~FileSystemOperationClient() {} + + virtual void DidFail( + WebKit::WebFileError status, + FileSystemOperation* operation) = 0; + + virtual void DidSucceed(FileSystemOperation* operation) = 0; + + // Info about the file entry such as modification date and size. + virtual void DidReadMetadata(const base::PlatformFileInfo& info, + FileSystemOperation* operation) = 0; + + virtual void DidReadDirectory( + const std::vector& entries, + bool has_more, FileSystemOperation* operation) = 0; +}; + +} // namespace fileapi + +#endif // WEBKIT_FILEAPI_FILE_SYSTEM_OPERATION_CLIENT_H_ diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi new file mode 100644 index 0000000..cce29cc --- /dev/null +++ b/webkit/fileapi/webkit_fileapi.gypi @@ -0,0 +1,31 @@ +# 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. + +{ + 'targets': [ + { + 'target_name': 'fileapi', + 'type': '<(library)', + 'msvs_guid': '40B53211-03ED-4932-8D53-52B172599DFE', + 'dependencies': [ + '<(DEPTH)/app/app.gyp:app_base', + '<(DEPTH)/base/base.gyp:base', + '<(DEPTH)/net/net.gyp:net', + ], + 'sources': [ + 'file_system_operation.cc', + 'file_system_operation.h', + 'file_system_operation_client.h', + ], + 'conditions': [ + ['inside_chromium_build==0', { + 'dependencies': [ + '<(DEPTH)/webkit/support/setup_third_party.gyp:third_party_headers', + ], + }], + ], + }, + ], +} + -- cgit v1.1