Chromium Code Reviews| 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..ac0c79ae53e0025f2edad4e67abd2304be032bd1 100644 |
| --- a/webkit/fileapi/file_system_file_util.cc |
| +++ b/webkit/fileapi/file_system_file_util.cc |
| @@ -148,9 +148,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 +167,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 +220,51 @@ 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( |
|
michaeln
2011/05/25 19:27:57
A comment about why you need a local_dest_context
ericu
2011/05/25 19:56:20
Done.
|
| + 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 { |
| + 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 dest_file_path is in the root, dest_file_path.DirName() will be ".", |
| + // since we use paths with no leading '/'. |
| + FilePath dest_parent = dest_file_path.DirName(); |
| + if (dest_parent != FilePath(FILE_PATH_LITERAL(".")) && |
|
michaeln
2011/05/25 19:27:57
I get it, but odd looking case testing for ".", ma
ericu
2011/05/25 19:56:20
Done: ParentExists().
|
| + !dest_util->DirectoryExists(dest_context, dest_parent)) |
| 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 +274,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 +284,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 +310,37 @@ 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); |
| + 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((dest_file_path.DirName() == FilePath(FILE_PATH_LITERAL("."))) || |
| + dest_util->DirectoryExists(&dest_context, dest_file_path.DirName())); |
| + 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 +354,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 +374,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) { |