Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3056)

Unified Diff: webkit/fileapi/file_system_file_util.cc

Issue 7066033: Enable cross-filesystem moves and copies. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rolled in Michael's feedback; removed unnecessary unlimited quota flag. Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webkit/fileapi/file_system_file_util.h ('k') | webkit/fileapi/file_system_file_util_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/fileapi/file_system_file_util.cc
diff --git a/webkit/fileapi/file_system_file_util.cc b/webkit/fileapi/file_system_file_util.cc
index 9349ad0368a474e5674ed1410fcb958693e22890..71a936578a86b56fdc177b164362e38909721853 100644
--- a/webkit/fileapi/file_system_file_util.cc
+++ b/webkit/fileapi/file_system_file_util.cc
@@ -13,6 +13,22 @@
namespace fileapi {
+namespace {
+
+// This assumes that the root exists.
+bool ParentExists(FileSystemOperationContext* context,
+ FileSystemFileUtil* file_util, const FilePath& file_path) {
+ // If file_path is in the root, file_path.DirName() will be ".",
+ // since we use paths with no leading '/'.
+ FilePath parent = file_path.DirName();
+ if (parent != FilePath(FILE_PATH_LITERAL(".")) &&
+ !file_util->DirectoryExists(context, parent))
+ return false;
michaeln 2011/05/25 20:30:11 nit: maybe could be more readable... FilePath par
ericu 2011/05/25 21:51:58 Done.
+ return true;
+}
+
+}
+
// static
FileSystemFileUtil* FileSystemFileUtil::GetInstance() {
return Singleton<FileSystemFileUtil>::get();
@@ -148,9 +164,8 @@ PlatformFileError FileSystemFileUtil::Copy(
if (DirectoryExists(context, src_file_path))
return CopyOrMoveDirectory(context, src_file_path, dest_file_path,
true /* copy */);
- else
- return CopyOrMoveFile(context, src_file_path, dest_file_path,
- true /* copy */);
+ return CopyOrMoveFileHelper(context, src_file_path, dest_file_path,
+ true /* copy */);
}
PlatformFileError FileSystemFileUtil::Move(
@@ -168,9 +183,8 @@ PlatformFileError FileSystemFileUtil::Move(
if (DirectoryExists(context, src_file_path))
return CopyOrMoveDirectory(context, src_file_path, dest_file_path,
false /* copy */);
- else
- return CopyOrMoveFile(context, src_file_path, dest_file_path,
- false /* copy */);
+ return CopyOrMoveFileHelper(context, src_file_path, dest_file_path,
+ false /* copy */);
}
PlatformFileError FileSystemFileUtil::Delete(
@@ -222,26 +236,50 @@ FileSystemFileUtil::PerformCommonCheckAndPreparationForMoveAndCopy(
FileSystemOperationContext* context,
const FilePath& src_file_path,
const FilePath& dest_file_path) {
+ bool same_file_system =
+ (context->src_origin_url() == context->dest_origin_url()) &&
+ (context->src_type() == context->dest_type());
+ FileSystemFileUtil* dest_util = context->dest_file_system_file_util();
+ DCHECK(dest_util);
+ FileSystemOperationContext local_dest_context(
+ context->file_system_context(), dest_util);
+ FileSystemOperationContext* dest_context;
+ if (same_file_system) {
+ dest_context = context;
+ DCHECK(context->src_file_system_file_util() ==
+ context->dest_file_system_file_util());
+ } else {
+ // All the single-path virtual FSFU methods expect the context information
+ // to be in the src_* variables, not the dest_* variables, so we have to
+ // make a new context if we want to call them on the dest_file_path.
+ dest_context = &local_dest_context;
+ dest_context->set_src_type(context->dest_type());
+ dest_context->set_src_origin_url(context->dest_origin_url());
+ dest_context->set_src_virtual_path(context->dest_virtual_path());
+ dest_context->set_allowed_bytes_growth(context->allowed_bytes_growth());
+ }
+
// Exits earlier if the source path does not exist.
if (!PathExists(context, src_file_path))
return base::PLATFORM_FILE_ERROR_NOT_FOUND;
// The parent of the |dest_file_path| does not exist.
- if (!DirectoryExists(context, dest_file_path.DirName()))
+ if (!ParentExists(dest_context, dest_util, dest_file_path))
return base::PLATFORM_FILE_ERROR_NOT_FOUND;
// It is an error to try to copy/move an entry into its child.
- if (src_file_path.IsParent(dest_file_path))
+ if (same_file_system && src_file_path.IsParent(dest_file_path))
return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
// Now it is ok to return if the |dest_file_path| does not exist.
- if (!PathExists(context, dest_file_path))
+ if (!dest_util->PathExists(dest_context, dest_file_path))
return base::PLATFORM_FILE_OK;
// |src_file_path| exists and is a directory.
// |dest_file_path| exists and is a file.
bool src_is_directory = DirectoryExists(context, src_file_path);
- bool dest_is_directory = DirectoryExists(context, dest_file_path);
+ bool dest_is_directory =
+ dest_util->DirectoryExists(dest_context, dest_file_path);
if (src_is_directory && !dest_is_directory)
return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
@@ -251,7 +289,7 @@ FileSystemFileUtil::PerformCommonCheckAndPreparationForMoveAndCopy(
return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
// It is an error to copy/move an entry into the same path.
- if (src_file_path.value() == dest_file_path.value())
+ if (same_file_system && (src_file_path.value() == dest_file_path.value()))
return base::PLATFORM_FILE_ERROR_EXISTS;
if (dest_is_directory) {
@@ -261,8 +299,9 @@ FileSystemFileUtil::PerformCommonCheckAndPreparationForMoveAndCopy(
// on all platforms, so we delete the destination directory here.
// TODO(kinuko): may be better to change the file_util::{Copy,Move}.
if (base::PLATFORM_FILE_OK !=
- Delete(context, dest_file_path, false /* recursive */)) {
- if (!IsDirectoryEmpty(context, dest_file_path))
+ dest_util->Delete(dest_context, dest_file_path,
+ false /* recursive */)) {
+ if (!dest_util->IsDirectoryEmpty(dest_context, dest_file_path))
return base::PLATFORM_FILE_ERROR_NOT_EMPTY;
return base::PLATFORM_FILE_ERROR_FAILED;
}
@@ -286,19 +325,39 @@ PlatformFileError FileSystemFileUtil::CopyOrMoveFile(
return base::PLATFORM_FILE_ERROR_FAILED;
}
+PlatformFileError FileSystemFileUtil::CopyInForeignFile(
+ FileSystemOperationContext* context,
+ const FilePath& src_file_path,
+ const FilePath& dest_file_path) {
+ return CopyOrMoveFile(context, src_file_path, dest_file_path, true);
+}
+
PlatformFileError FileSystemFileUtil::CopyOrMoveDirectory(
FileSystemOperationContext* context,
const FilePath& src_file_path,
const FilePath& dest_file_path,
bool copy) {
+ FileSystemFileUtil* dest_util = context->dest_file_system_file_util();
+ FileSystemOperationContext dest_context(
+ context->file_system_context(), dest_util);
+ // All the single-path virtual FSFU methods expect the context information to
+ // be in the src_* variables, not the dest_* variables, so we have to make a
+ // new context if we want to call them on the dest_file_path.
+ dest_context.set_src_type(context->dest_type());
+ dest_context.set_src_origin_url(context->dest_origin_url());
+ dest_context.set_src_virtual_path(context->dest_virtual_path());
+ dest_context.set_allowed_bytes_growth(context->allowed_bytes_growth());
+
// Re-check PerformCommonCheckAndPreparationForMoveAndCopy() by DCHECK.
DCHECK(DirectoryExists(context, src_file_path));
- DCHECK(DirectoryExists(context, dest_file_path.DirName()));
- DCHECK(!src_file_path.IsParent(dest_file_path));
- DCHECK(!PathExists(context, dest_file_path));
-
- if (!DirectoryExists(context, dest_file_path)) {
- PlatformFileError error = CreateDirectory(context,
+ DCHECK(ParentExists(&dest_context, dest_util, dest_file_path));
+ DCHECK(!dest_util->PathExists(&dest_context, dest_file_path));
+ if ((context->src_origin_url() == context->dest_origin_url()) &&
+ (context->src_type() == context->dest_type()))
+ DCHECK(!src_file_path.IsParent(dest_file_path));
+
+ if (!dest_util->DirectoryExists(&dest_context, dest_file_path)) {
+ PlatformFileError error = dest_util->CreateDirectory(&dest_context,
dest_file_path, false, false);
if (error != base::PLATFORM_FILE_OK)
return error;
@@ -312,13 +371,12 @@ PlatformFileError FileSystemFileUtil::CopyOrMoveDirectory(
src_file_path.AppendRelativePath(src_file_path_each, &dest_file_path_each);
if (file_enum->IsDirectory()) {
- PlatformFileError error = CreateDirectory(context,
+ PlatformFileError error = dest_util->CreateDirectory(&dest_context,
dest_file_path_each, false, false);
if (error != base::PLATFORM_FILE_OK)
return error;
} else {
- // CopyOrMoveFile here is the virtual overridden member function.
- PlatformFileError error = CopyOrMoveFile(
+ PlatformFileError error = CopyOrMoveFileHelper(
context, src_file_path_each, dest_file_path_each, copy);
if (error != base::PLATFORM_FILE_OK)
return error;
@@ -333,6 +391,35 @@ PlatformFileError FileSystemFileUtil::CopyOrMoveDirectory(
return base::PLATFORM_FILE_OK;
}
+PlatformFileError FileSystemFileUtil::CopyOrMoveFileHelper(
+ FileSystemOperationContext* context,
+ const FilePath& src_file_path,
+ const FilePath& dest_file_path,
+ bool copy) {
+ // CopyOrMoveFile here is the virtual overridden member function.
+ if ((context->src_origin_url() == context->dest_origin_url()) &&
+ (context->src_type() == context->dest_type())) {
+ DCHECK(context->src_file_system_file_util() ==
+ context->dest_file_system_file_util());
+ return CopyOrMoveFile(context, src_file_path, dest_file_path, copy);
+ }
+ base::PlatformFileInfo file_info;
+ FilePath platform_file_path;
+ PlatformFileError error_code;
+ error_code =
+ GetFileInfo(context, src_file_path, &file_info, &platform_file_path);
+ if (error_code != base::PLATFORM_FILE_OK)
+ return error_code;
+
+ DCHECK(context->dest_file_system_file_util());
+ error_code = context->dest_file_system_file_util()->CopyInForeignFile(
+ context, platform_file_path, dest_file_path);
+ if (copy || error_code != base::PLATFORM_FILE_OK)
+ return error_code;
+ return DeleteFile(context, src_file_path);
+}
+
+
PlatformFileError FileSystemFileUtil::DeleteFile(
FileSystemOperationContext* unused,
const FilePath& file_path) {
« no previous file with comments | « webkit/fileapi/file_system_file_util.h ('k') | webkit/fileapi/file_system_file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698