summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--webkit/fileapi/cross_file_util_helper.cc187
-rw-r--r--webkit/fileapi/cross_file_util_helper.h71
-rw-r--r--webkit/fileapi/file_system_file_util_proxy.cc16
-rw-r--r--webkit/fileapi/file_system_file_util_unittest.cc26
-rw-r--r--webkit/fileapi/file_system_test_helper.cc15
-rw-r--r--webkit/fileapi/file_system_test_helper.h1
-rw-r--r--webkit/fileapi/file_util_helper.cc248
-rw-r--r--webkit/fileapi/file_util_helper.h14
-rw-r--r--webkit/fileapi/webkit_fileapi.gypi2
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',