diff options
-rw-r--r-- | webkit/fileapi/cross_file_util_helper.cc | 187 | ||||
-rw-r--r-- | webkit/fileapi/cross_file_util_helper.h | 71 | ||||
-rw-r--r-- | webkit/fileapi/file_system_file_util_proxy.cc | 16 | ||||
-rw-r--r-- | webkit/fileapi/file_system_file_util_unittest.cc | 26 | ||||
-rw-r--r-- | webkit/fileapi/file_system_test_helper.cc | 15 | ||||
-rw-r--r-- | webkit/fileapi/file_system_test_helper.h | 1 | ||||
-rw-r--r-- | webkit/fileapi/file_util_helper.cc | 248 | ||||
-rw-r--r-- | webkit/fileapi/file_util_helper.h | 14 | ||||
-rw-r--r-- | webkit/fileapi/webkit_fileapi.gypi | 2 |
9 files changed, 285 insertions, 295 deletions
diff --git a/webkit/fileapi/cross_file_util_helper.cc b/webkit/fileapi/cross_file_util_helper.cc deleted file mode 100644 index 56d504b..0000000 --- a/webkit/fileapi/cross_file_util_helper.cc +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (c) 2012 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/cross_file_util_helper.h" - -#include "webkit/fileapi/file_system_file_util.h" -#include "webkit/fileapi/file_system_operation_context.h" -#include "webkit/fileapi/file_system_path.h" -#include "webkit/fileapi/file_util_helper.h" - -using base::PlatformFileError; - -namespace fileapi { - -CrossFileUtilHelper::CrossFileUtilHelper( - FileSystemOperationContext* context, - FileSystemFileUtil* src_util, - FileSystemFileUtil* dest_util, - const FileSystemPath& src_path, - const FileSystemPath& dest_path, - Operation operation) - : context_(context), - src_util_(src_util), - dest_util_(dest_util), - src_root_path_(src_path), - dest_root_path_(dest_path), - operation_(operation) {} - -CrossFileUtilHelper::~CrossFileUtilHelper() {} - -base::PlatformFileError CrossFileUtilHelper::DoWork() { - base::PlatformFileError error = - PerformErrorCheckAndPreparationForMoveAndCopy(); - if (error != base::PLATFORM_FILE_OK) - return error; - if (src_util_->DirectoryExists(context_, src_root_path_)) { - return CopyOrMoveDirectory(src_root_path_, dest_root_path_); - } - return CopyOrMoveFile(src_root_path_, dest_root_path_); -} - -PlatformFileError -CrossFileUtilHelper::PerformErrorCheckAndPreparationForMoveAndCopy() { - // Exits earlier if the source path does not exist. - if (!src_util_->PathExists(context_, src_root_path_)) - return base::PLATFORM_FILE_ERROR_NOT_FOUND; - - bool same_file_system = - (src_root_path_.origin() == dest_root_path_.origin()) && - (src_root_path_.type() == dest_root_path_.type()); - - // The parent of the |dest_root_path_| does not exist. - if (!ParentExists(dest_root_path_, dest_util_)) - return base::PLATFORM_FILE_ERROR_NOT_FOUND; - - // It is an error to try to copy/move an entry into its child. - if (same_file_system && src_root_path_.IsParent(dest_root_path_)) - return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; - - // Now it is ok to return if the |dest_root_path_| does not exist. - if (!dest_util_->PathExists(context_, dest_root_path_)) - return base::PLATFORM_FILE_OK; - - // |src_root_path_| exists and is a directory. - // |dest_root_path_| exists and is a file. - bool src_is_directory = src_util_->DirectoryExists(context_, src_root_path_); - bool dest_is_directory = - dest_util_->DirectoryExists(context_, dest_root_path_); - - // Either one of |src_root_path_| or |dest_root_path_| is directory, - // while the other is not. - if (src_is_directory != dest_is_directory) - return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; - - // It is an error to copy/move an entry into the same path. - if (same_file_system && (src_root_path_.internal_path() == - dest_root_path_.internal_path())) - return base::PLATFORM_FILE_ERROR_EXISTS; - - if (dest_is_directory) { - // It is an error to copy/move an entry to a non-empty directory. - // Otherwise the copy/move attempt must overwrite the destination, but - // the file_util's Copy or Move method doesn't perform overwrite - // on all platforms, so we delete the destination directory here. - if (base::PLATFORM_FILE_OK != - dest_util_->DeleteSingleDirectory(context_, dest_root_path_)) { - if (!dest_util_->IsDirectoryEmpty(context_, dest_root_path_)) - return base::PLATFORM_FILE_ERROR_NOT_EMPTY; - return base::PLATFORM_FILE_ERROR_FAILED; - } - } - return base::PLATFORM_FILE_OK; -} - -bool CrossFileUtilHelper::ParentExists( - const FileSystemPath& path, FileSystemFileUtil* file_util) { - // If path is in the root, path.DirName() will be ".", - // since we use paths with no leading '/'. - FilePath parent = path.internal_path().DirName(); - if (parent == FilePath(FILE_PATH_LITERAL("."))) - return true; - return file_util->DirectoryExists( - context_, path.WithInternalPath(parent)); -} - -PlatformFileError CrossFileUtilHelper::CopyOrMoveDirectory( - const FileSystemPath& src_path, - const FileSystemPath& dest_path) { - // At this point we must have gone through - // PerformErrorCheckAndPreparationForMoveAndCopy so this must be true. - DCHECK(!((src_path.origin() == dest_path.origin()) && - (src_path.type() == dest_path.type())) || - !src_path.IsParent(dest_path)); - - PlatformFileError error = dest_util_->CreateDirectory( - context_, dest_path, false, false); - if (error != base::PLATFORM_FILE_OK) - return error; - - scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum( - src_util_->CreateFileEnumerator(context_, src_path, - true /* recursive */)); - FilePath src_file_path_each; - while (!(src_file_path_each = file_enum->Next()).empty()) { - FilePath dest_file_path_each(dest_path.internal_path()); - src_path.internal_path().AppendRelativePath( - src_file_path_each, &dest_file_path_each); - - if (file_enum->IsDirectory()) { - PlatformFileError error = dest_util_->CreateDirectory( - context_, - dest_path.WithInternalPath(dest_file_path_each), - true /* exclusive */, false /* recursive */); - if (error != base::PLATFORM_FILE_OK) - return error; - } else { - PlatformFileError error = CopyOrMoveFile( - src_path.WithInternalPath(src_file_path_each), - dest_path.WithInternalPath(dest_file_path_each)); - if (error != base::PLATFORM_FILE_OK) - return error; - } - } - - if (operation_ == OPERATION_MOVE) { - PlatformFileError error = - FileUtilHelper::Delete(context_, src_util_, - src_path, true /* recursive */); - if (error != base::PLATFORM_FILE_OK) - return error; - } - - return base::PLATFORM_FILE_OK; -} - -PlatformFileError CrossFileUtilHelper::CopyOrMoveFile( - const FileSystemPath& src_path, - const FileSystemPath& dest_path) { - if ((src_path.origin() == dest_path.origin()) && - (src_path.type() == dest_path.type())) { - DCHECK(src_util_ == dest_util_); - // Source and destination are in the same FileSystemFileUtil; now we can - // safely call FileSystemFileUtil method on src_util_ (== dest_util_). - return src_util_->CopyOrMoveFile(context_, src_path, dest_path, - operation_ == OPERATION_COPY); - } - - // Resolve the src_path's underlying file path. - base::PlatformFileInfo file_info; - FilePath platform_file_path; - PlatformFileError error = src_util_->GetFileInfo( - context_, src_path, &file_info, &platform_file_path); - if (error != base::PLATFORM_FILE_OK) - return error; - - // Call CopyInForeignFile() on the dest_util_ with the resolved source path - // to perform limited cross-FileSystemFileUtil copy/move. - error = dest_util_->CopyInForeignFile( - context_, src_path.WithInternalPath(platform_file_path), dest_path); - - if (operation_ == OPERATION_COPY || error != base::PLATFORM_FILE_OK) - return error; - return src_util_->DeleteFile(context_, src_path); -} - -} // namespace fileapi diff --git a/webkit/fileapi/cross_file_util_helper.h b/webkit/fileapi/cross_file_util_helper.h deleted file mode 100644 index 3466928..0000000 --- a/webkit/fileapi/cross_file_util_helper.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2012 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_CROSS_FILE_UTIL_HELPER_H_ -#define WEBKIT_FILEAPI_CROSS_FILE_UTIL_HELPER_H_ - -#include "base/callback.h" -#include "base/platform_file.h" - -namespace fileapi { - -class FileSystemFileUtil; -class FileSystemOperationContext; -class FileSystemPath; - -// A helper class for cross-FileUtil Copy/Move operations. -class CrossFileUtilHelper { - public: - enum Operation { - OPERATION_COPY, - OPERATION_MOVE - }; - - CrossFileUtilHelper(FileSystemOperationContext* context, - FileSystemFileUtil* src_util, - FileSystemFileUtil* dest_util, - const FileSystemPath& src_path, - const FileSystemPath& dest_path, - Operation operation); - ~CrossFileUtilHelper(); - - base::PlatformFileError DoWork(); - - private: - // Performs common pre-operation check and preparation. - // This may delete the destination directory if it's empty. - base::PlatformFileError PerformErrorCheckAndPreparationForMoveAndCopy(); - - // This assumes that the root exists. - bool ParentExists(const FileSystemPath& path, FileSystemFileUtil* file_util); - - // Performs recursive copy or move by calling CopyOrMoveFile for individual - // files. Operations for recursive traversal are encapsulated in this method. - // It assumes src_path and dest_path have passed - // PerformErrorCheckAndPreparationForMoveAndCopy(). - base::PlatformFileError CopyOrMoveDirectory( - const FileSystemPath& src_path, - const FileSystemPath& dest_path); - - // Determines whether a simple same-filesystem move or copy can be done. If - // so, it delegates to CopyOrMoveFile. Otherwise it looks up the true - // platform path of the source file, delegates to CopyInForeignFile, and [for - // move] calls DeleteFile on the source file. - base::PlatformFileError CopyOrMoveFile( - const FileSystemPath& src_path, - const FileSystemPath& dest_path); - - FileSystemOperationContext* context_; - FileSystemFileUtil* src_util_; // Not owned. - FileSystemFileUtil* dest_util_; // Not owned. - const FileSystemPath& src_root_path_; - const FileSystemPath& dest_root_path_; - Operation operation_; - - DISALLOW_COPY_AND_ASSIGN(CrossFileUtilHelper); -}; - -} // namespace fileapi - -#endif // WEBKIT_FILEAPI_CROSS_FILE_UTIL_HELPER_H_ diff --git a/webkit/fileapi/file_system_file_util_proxy.cc b/webkit/fileapi/file_system_file_util_proxy.cc index 52b0fd5..6301d6c 100644 --- a/webkit/fileapi/file_system_file_util_proxy.cc +++ b/webkit/fileapi/file_system_file_util_proxy.cc @@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop_proxy.h" -#include "webkit/fileapi/cross_file_util_helper.h" #include "webkit/fileapi/file_system_file_util.h" #include "webkit/fileapi/file_system_operation_context.h" #include "webkit/fileapi/file_util_helper.h" @@ -131,14 +130,10 @@ bool FileSystemFileUtilProxy::Copy( const FileSystemPath& src_path, const FileSystemPath& dest_path, const StatusCallback& callback) { - CrossFileUtilHelper* helper = - new CrossFileUtilHelper( - context, src_util, dest_util, src_path, dest_path, - CrossFileUtilHelper::OPERATION_COPY); - return base::FileUtilProxy::RelayFileTask( message_loop_proxy, FROM_HERE, - Bind(&CrossFileUtilHelper::DoWork, Owned(helper)), + Bind(&FileUtilHelper::Copy, + context, src_util, dest_util, src_path, dest_path), callback); } @@ -151,13 +146,10 @@ bool FileSystemFileUtilProxy::Move( const FileSystemPath& src_path, const FileSystemPath& dest_path, const StatusCallback& callback) { - CrossFileUtilHelper* helper = - new CrossFileUtilHelper( - context, src_util, dest_util, src_path, dest_path, - CrossFileUtilHelper::OPERATION_MOVE); return base::FileUtilProxy::RelayFileTask( message_loop_proxy, FROM_HERE, - Bind(&CrossFileUtilHelper::DoWork, Owned(helper)), + Bind(&FileUtilHelper::Move, + context, src_util, dest_util, src_path, dest_path), callback); } diff --git a/webkit/fileapi/file_system_file_util_unittest.cc b/webkit/fileapi/file_system_file_util_unittest.cc index 40cd803..707ea71 100644 --- a/webkit/fileapi/file_system_file_util_unittest.cc +++ b/webkit/fileapi/file_system_file_util_unittest.cc @@ -8,10 +8,10 @@ #include "base/platform_file.h" #include "base/scoped_temp_dir.h" #include "testing/gtest/include/gtest/gtest.h" -#include "webkit/fileapi/cross_file_util_helper.h" #include "webkit/fileapi/file_system_context.h" #include "webkit/fileapi/file_system_operation_context.h" #include "webkit/fileapi/file_system_test_helper.h" +#include "webkit/fileapi/file_util_helper.h" #include "webkit/fileapi/native_file_util.h" #include "webkit/fileapi/obfuscated_file_util.h" #include "webkit/fileapi/test_file_set.h" @@ -90,15 +90,21 @@ class FileSystemFileUtilTest : public testing::Test { src_helper.NewOperationContext()); copy_context->set_allowed_bytes_growth(1024 * 1024); // OFSFU path quota. - CrossFileUtilHelper cross_util_helper( - copy_context.get(), - src_helper.file_util(), - dest_helper.file_util(), - src_root, - dest_root, - copy ? CrossFileUtilHelper::OPERATION_COPY - : CrossFileUtilHelper::OPERATION_MOVE); - ASSERT_EQ(base::PLATFORM_FILE_OK, cross_util_helper.DoWork()); + if (copy) { + ASSERT_EQ( + base::PLATFORM_FILE_OK, + FileUtilHelper::Copy( + copy_context.get(), + src_helper.file_util(), dest_helper.file_util(), + src_root, dest_root)); + } else { + ASSERT_EQ( + base::PLATFORM_FILE_OK, + FileUtilHelper::Move( + copy_context.get(), + src_helper.file_util(), dest_helper.file_util(), + src_root, dest_root)); + } // Validate that the destination paths are correct. for (size_t i = 0; i < test::kRegularTestCaseSize; ++i) { diff --git a/webkit/fileapi/file_system_test_helper.cc b/webkit/fileapi/file_system_test_helper.cc index 9f3705d..958da18 100644 --- a/webkit/fileapi/file_system_test_helper.cc +++ b/webkit/fileapi/file_system_test_helper.cc @@ -13,6 +13,7 @@ #include "webkit/fileapi/file_system_operation_context.h" #include "webkit/fileapi/file_system_usage_cache.h" #include "webkit/fileapi/file_system_util.h" +#include "webkit/fileapi/file_util_helper.h" #include "webkit/fileapi/mock_file_system_options.h" #include "webkit/fileapi/sandbox_mount_point_provider.h" #include "webkit/quota/mock_special_storage_policy.h" @@ -134,24 +135,14 @@ base::PlatformFileError FileSystemTestOriginHelper::SameFileUtilCopy( FileSystemOperationContext* context, const FileSystemPath& src, const FileSystemPath& dest) const { - CrossFileUtilHelper cross_util_helper( - context, - file_util(), file_util(), - src, dest, - CrossFileUtilHelper::OPERATION_COPY); - return cross_util_helper.DoWork(); + return FileUtilHelper::Copy(context, file_util(), file_util(), src, dest); } base::PlatformFileError FileSystemTestOriginHelper::SameFileUtilMove( FileSystemOperationContext* context, const FileSystemPath& src, const FileSystemPath& dest) const { - CrossFileUtilHelper cross_util_helper( - context, - file_util(), file_util(), - src, dest, - CrossFileUtilHelper::OPERATION_MOVE); - return cross_util_helper.DoWork(); + return FileUtilHelper::Move(context, file_util(), file_util(), src, dest); } int64 FileSystemTestOriginHelper::GetCachedOriginUsage() const { diff --git a/webkit/fileapi/file_system_test_helper.h b/webkit/fileapi/file_system_test_helper.h index 132226b..8c495bd 100644 --- a/webkit/fileapi/file_system_test_helper.h +++ b/webkit/fileapi/file_system_test_helper.h @@ -12,7 +12,6 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "googleurl/src/gurl.h" -#include "webkit/fileapi/cross_file_util_helper.h" #include "webkit/fileapi/file_system_path.h" #include "webkit/fileapi/file_system_types.h" #include "webkit/fileapi/file_system_util.h" diff --git a/webkit/fileapi/file_util_helper.cc b/webkit/fileapi/file_util_helper.cc index 1310f18..b2885de 100644 --- a/webkit/fileapi/file_util_helper.cc +++ b/webkit/fileapi/file_util_helper.cc @@ -12,6 +12,253 @@ using base::PlatformFileError; namespace fileapi { +namespace { + +// A helper class for cross-FileUtil Copy/Move operations. +class CrossFileUtilHelper { + public: + enum Operation { + OPERATION_COPY, + OPERATION_MOVE + }; + + CrossFileUtilHelper(FileSystemOperationContext* context, + FileSystemFileUtil* src_util, + FileSystemFileUtil* dest_util, + const FileSystemPath& src_path, + const FileSystemPath& dest_path, + Operation operation); + ~CrossFileUtilHelper(); + + base::PlatformFileError DoWork(); + + private: + // Performs common pre-operation check and preparation. + // This may delete the destination directory if it's empty. + base::PlatformFileError PerformErrorCheckAndPreparation(); + + // This assumes that the root exists. + bool ParentExists(const FileSystemPath& path, FileSystemFileUtil* file_util); + + // Performs recursive copy or move by calling CopyOrMoveFile for individual + // files. Operations for recursive traversal are encapsulated in this method. + // It assumes src_path and dest_path have passed + // PerformErrorCheckAndPreparationForMoveAndCopy(). + base::PlatformFileError CopyOrMoveDirectory( + const FileSystemPath& src_path, + const FileSystemPath& dest_path); + + // Determines whether a simple same-filesystem move or copy can be done. If + // so, it delegates to CopyOrMoveFile. Otherwise it looks up the true + // platform path of the source file, delegates to CopyInForeignFile, and [for + // move] calls DeleteFile on the source file. + base::PlatformFileError CopyOrMoveFile( + const FileSystemPath& src_path, + const FileSystemPath& dest_path); + + FileSystemOperationContext* context_; + FileSystemFileUtil* src_util_; // Not owned. + FileSystemFileUtil* dest_util_; // Not owned. + const FileSystemPath& src_root_path_; + const FileSystemPath& dest_root_path_; + Operation operation_; + bool same_file_system_; + + DISALLOW_COPY_AND_ASSIGN(CrossFileUtilHelper); +}; + +CrossFileUtilHelper::CrossFileUtilHelper( + FileSystemOperationContext* context, + FileSystemFileUtil* src_util, + FileSystemFileUtil* dest_util, + const FileSystemPath& src_path, + const FileSystemPath& dest_path, + Operation operation) + : context_(context), + src_util_(src_util), + dest_util_(dest_util), + src_root_path_(src_path), + dest_root_path_(dest_path), + operation_(operation) { + same_file_system_ = + src_root_path_.origin() == dest_root_path_.origin() && + src_root_path_.type() == dest_root_path_.type(); +} + +CrossFileUtilHelper::~CrossFileUtilHelper() {} + +base::PlatformFileError CrossFileUtilHelper::DoWork() { + base::PlatformFileError error = PerformErrorCheckAndPreparation(); + if (error != base::PLATFORM_FILE_OK) + return error; + if (src_util_->DirectoryExists(context_, src_root_path_)) + return CopyOrMoveDirectory(src_root_path_, dest_root_path_); + return CopyOrMoveFile(src_root_path_, dest_root_path_); +} + +PlatformFileError CrossFileUtilHelper::PerformErrorCheckAndPreparation() { + // Exits earlier if the source path does not exist. + if (!src_util_->PathExists(context_, src_root_path_)) + return base::PLATFORM_FILE_ERROR_NOT_FOUND; + + // The parent of the |dest_root_path_| does not exist. + if (!ParentExists(dest_root_path_, dest_util_)) + return base::PLATFORM_FILE_ERROR_NOT_FOUND; + + // It is an error to try to copy/move an entry into its child. + if (same_file_system_ && src_root_path_.IsParent(dest_root_path_)) + return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; + + // Now it is ok to return if the |dest_root_path_| does not exist. + if (!dest_util_->PathExists(context_, dest_root_path_)) + return base::PLATFORM_FILE_OK; + + // |src_root_path_| exists and is a directory. + // |dest_root_path_| exists and is a file. + bool src_is_directory = src_util_->DirectoryExists(context_, src_root_path_); + bool dest_is_directory = + dest_util_->DirectoryExists(context_, dest_root_path_); + + // Either one of |src_root_path_| or |dest_root_path_| is directory, + // while the other is not. + if (src_is_directory != dest_is_directory) + return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; + + // It is an error to copy/move an entry into the same path. + if (same_file_system_ && + src_root_path_.internal_path() == dest_root_path_.internal_path()) + return base::PLATFORM_FILE_ERROR_EXISTS; + + if (dest_is_directory) { + // It is an error to copy/move an entry to a non-empty directory. + // Otherwise the copy/move attempt must overwrite the destination, but + // the file_util's Copy or Move method doesn't perform overwrite + // on all platforms, so we delete the destination directory here. + if (base::PLATFORM_FILE_OK != + dest_util_->DeleteSingleDirectory(context_, dest_root_path_)) { + if (!dest_util_->IsDirectoryEmpty(context_, dest_root_path_)) + return base::PLATFORM_FILE_ERROR_NOT_EMPTY; + return base::PLATFORM_FILE_ERROR_FAILED; + } + } + return base::PLATFORM_FILE_OK; +} + +bool CrossFileUtilHelper::ParentExists( + const FileSystemPath& path, FileSystemFileUtil* file_util) { + // If path is in the root, path.DirName() will be ".", + // since we use paths with no leading '/'. + FilePath parent = path.internal_path().DirName(); + if (parent == FilePath(FILE_PATH_LITERAL("."))) + return true; + return file_util->DirectoryExists( + context_, path.WithInternalPath(parent)); +} + +PlatformFileError CrossFileUtilHelper::CopyOrMoveDirectory( + const FileSystemPath& src_path, + const FileSystemPath& dest_path) { + // At this point we must have gone through + // PerformErrorCheckAndPreparationForMoveAndCopy so this must be true. + DCHECK(!same_file_system_ || + !src_path.IsParent(dest_path)); + + PlatformFileError error = dest_util_->CreateDirectory( + context_, dest_path, false, false); + if (error != base::PLATFORM_FILE_OK) + return error; + + scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum( + src_util_->CreateFileEnumerator(context_, src_path, true)); + FilePath src_file_path_each; + while (!(src_file_path_each = file_enum->Next()).empty()) { + FilePath dest_file_path_each(dest_path.internal_path()); + src_path.internal_path().AppendRelativePath( + src_file_path_each, &dest_file_path_each); + + if (file_enum->IsDirectory()) { + PlatformFileError error = dest_util_->CreateDirectory( + context_, + dest_path.WithInternalPath(dest_file_path_each), + true /* exclusive */, false /* recursive */); + if (error != base::PLATFORM_FILE_OK) + return error; + } else { + PlatformFileError error = CopyOrMoveFile( + src_path.WithInternalPath(src_file_path_each), + dest_path.WithInternalPath(dest_file_path_each)); + if (error != base::PLATFORM_FILE_OK) + return error; + } + } + + if (operation_ == OPERATION_MOVE) { + PlatformFileError error = + FileUtilHelper::Delete(context_, src_util_, + src_path, true /* recursive */); + if (error != base::PLATFORM_FILE_OK) + return error; + } + + return base::PLATFORM_FILE_OK; +} + +PlatformFileError CrossFileUtilHelper::CopyOrMoveFile( + const FileSystemPath& src_path, + const FileSystemPath& dest_path) { + if (same_file_system_) { + DCHECK(src_util_ == dest_util_); + // Source and destination are in the same FileSystemFileUtil; now we can + // safely call FileSystemFileUtil method on src_util_ (== dest_util_). + return src_util_->CopyOrMoveFile(context_, src_path, dest_path, + operation_ == OPERATION_COPY); + } + + // Resolve the src_path's underlying file path. + base::PlatformFileInfo file_info; + FilePath platform_file_path; + PlatformFileError error = src_util_->GetFileInfo( + context_, src_path, &file_info, &platform_file_path); + if (error != base::PLATFORM_FILE_OK) + return error; + + // Call CopyInForeignFile() on the dest_util_ with the resolved source path + // to perform limited cross-FileSystemFileUtil copy/move. + error = dest_util_->CopyInForeignFile( + context_, src_path.WithInternalPath(platform_file_path), dest_path); + + if (operation_ == OPERATION_COPY || error != base::PLATFORM_FILE_OK) + return error; + return src_util_->DeleteFile(context_, src_path); +} + +} // anonymous namespace + +// static +base::PlatformFileError FileUtilHelper::Copy( + FileSystemOperationContext* context, + FileSystemFileUtil* src_file_util, + FileSystemFileUtil* dest_file_util, + const FileSystemPath& src_root_path, + const FileSystemPath& dest_root_path) { + return CrossFileUtilHelper(context, src_file_util, dest_file_util, + src_root_path, dest_root_path, + CrossFileUtilHelper::OPERATION_COPY).DoWork(); +} + +// static +base::PlatformFileError FileUtilHelper::Move( + FileSystemOperationContext* context, + FileSystemFileUtil* src_file_util, + FileSystemFileUtil* dest_file_util, + const FileSystemPath& src_root_path, + const FileSystemPath& dest_root_path) { + return CrossFileUtilHelper(context, src_file_util, dest_file_util, + src_root_path, dest_root_path, + CrossFileUtilHelper::OPERATION_MOVE).DoWork(); +} + +// static base::PlatformFileError FileUtilHelper::Delete( FileSystemOperationContext* context, FileSystemFileUtil* file_util, @@ -27,6 +274,7 @@ base::PlatformFileError FileUtilHelper::Delete( } } +// static base::PlatformFileError FileUtilHelper::DeleteDirectoryRecursive( FileSystemOperationContext* context, FileSystemFileUtil* file_util, diff --git a/webkit/fileapi/file_util_helper.h b/webkit/fileapi/file_util_helper.h index 91c6e7a..494be1f 100644 --- a/webkit/fileapi/file_util_helper.h +++ b/webkit/fileapi/file_util_helper.h @@ -17,6 +17,20 @@ class FileSystemPath; // FileSystemFileUtilProxy. The method should be called on FILE thread. class FileUtilHelper { public: + static base::PlatformFileError Copy( + FileSystemOperationContext* context, + FileSystemFileUtil* src_file_util, + FileSystemFileUtil* dest_file_utile, + const FileSystemPath& src_root_path, + const FileSystemPath& dest_root_path); + + static base::PlatformFileError Move( + FileSystemOperationContext* context, + FileSystemFileUtil* src_file_util, + FileSystemFileUtil* dest_file_utile, + const FileSystemPath& src_root_path, + const FileSystemPath& dest_root_path); + static base::PlatformFileError Delete( FileSystemOperationContext* context, FileSystemFileUtil* file_util, diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi index 68d8cf1..4ac71cf 100644 --- a/webkit/fileapi/webkit_fileapi.gypi +++ b/webkit/fileapi/webkit_fileapi.gypi @@ -15,8 +15,6 @@ '<(DEPTH)/webkit/support/webkit_support.gyp:quota', ], 'sources': [ - 'cross_file_util_helper.cc', - 'cross_file_util_helper.h', 'file_system_callback_dispatcher.cc', 'file_system_callback_dispatcher.h', 'file_system_context.cc', |