summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/fileapi/file_system_operation_impl_unittest.cc39
-rw-r--r--webkit/browser/fileapi/copy_or_move_operation_delegate.cc33
2 files changed, 70 insertions, 2 deletions
diff --git a/content/browser/fileapi/file_system_operation_impl_unittest.cc b/content/browser/fileapi/file_system_operation_impl_unittest.cc
index afbe664..0399fe6 100644
--- a/content/browser/fileapi/file_system_operation_impl_unittest.cc
+++ b/content/browser/fileapi/file_system_operation_impl_unittest.cc
@@ -50,6 +50,15 @@ void AssertFileErrorEq(const tracked_objects::Location& from_here,
ASSERT_EQ(expected, actual) << from_here.ToString();
}
+void AssertFileErrorEqWithClosure(
+ const tracked_objects::Location& from_here,
+ base::File::Error expected,
+ base::Closure closure,
+ base::File::Error actual) {
+ ASSERT_EQ(expected, actual) << from_here.ToString();
+ closure.Run();
+}
+
} // namespace
// Test class for FileSystemOperationImpl.
@@ -1287,4 +1296,34 @@ TEST_F(FileSystemOperationImplTest,
EXPECT_EQ(expected_usage, usage);
}
+TEST_F(FileSystemOperationImplTest,
+ TestCopySuccessSrcFileWithDifferentFileSize) {
+ FileSystemURL src_file(CreateFile("src"));
+ FileSystemURL dest_file(CreateFile("dest"));
+
+ {
+ base::RunLoop run_loop;
+ operation_runner()->Truncate(
+ dest_file, 6,
+ base::Bind(&AssertFileErrorEqWithClosure,
+ FROM_HERE,
+ base::File::FILE_OK,
+ run_loop.QuitClosure()));
+ run_loop.Run();
+ }
+
+ {
+ base::RunLoop run_loop;
+ operation_runner()->Copy(
+ src_file, dest_file, FileSystemOperation::OPTION_NONE,
+ FileSystemOperationRunner::CopyProgressCallback(),
+ base::Bind(&AssertFileErrorEqWithClosure,
+ FROM_HERE,
+ base::File::FILE_OK,
+ run_loop.QuitClosure()));
+ run_loop.Run();
+ }
+ EXPECT_EQ(0, GetFileSize("dest"));
+}
+
} // namespace content
diff --git a/webkit/browser/fileapi/copy_or_move_operation_delegate.cc b/webkit/browser/fileapi/copy_or_move_operation_delegate.cc
index 97de4f4..6bb089b 100644
--- a/webkit/browser/fileapi/copy_or_move_operation_delegate.cc
+++ b/webkit/browser/fileapi/copy_or_move_operation_delegate.cc
@@ -423,10 +423,12 @@ class StreamCopyOrMoveImpl
// To use FileStreamWriter, we need to ensure the destination file exists.
operation_runner_->CreateFile(
- dest_url_, false /* exclusive */,
+ dest_url_,
+ true /* exclusive */,
base::Bind(&StreamCopyOrMoveImpl::RunAfterCreateFileForDestination,
weak_factory_.GetWeakPtr(),
- callback, file_info.last_modified));
+ callback,
+ file_info.last_modified));
}
void RunAfterCreateFileForDestination(
@@ -436,6 +438,33 @@ class StreamCopyOrMoveImpl
if (cancel_requested_)
error = base::File::FILE_ERROR_ABORT;
+ if (error != base::File::FILE_OK &&
+ error != base::File::FILE_ERROR_EXISTS) {
+ callback.Run(error);
+ return;
+ }
+
+ if (error == base::File::FILE_ERROR_EXISTS) {
+ operation_runner_->Truncate(
+ dest_url_,
+ 0 /* length */,
+ base::Bind(&StreamCopyOrMoveImpl::RunAfterTruncateForDestination,
+ weak_factory_.GetWeakPtr(),
+ callback,
+ last_modified));
+ return;
+ }
+ RunAfterTruncateForDestination(
+ callback, last_modified, base::File::FILE_OK);
+ }
+
+ void RunAfterTruncateForDestination(
+ const CopyOrMoveOperationDelegate::StatusCallback& callback,
+ const base::Time& last_modified,
+ base::File::Error error) {
+ if (cancel_requested_)
+ error = base::File::FILE_ERROR_ABORT;
+
if (error != base::File::FILE_OK) {
callback.Run(error);
return;