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

Side by Side 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: Hack to try to fix windows tests. 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/fileapi/file_system_file_util.h" 5 #include "webkit/fileapi/file_system_file_util.h"
6 6
7 #include <stack> 7 #include <stack>
8 8
9 #include "base/file_util_proxy.h" 9 #include "base/file_util_proxy.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 PlatformFileError error_code; 141 PlatformFileError error_code;
142 error_code = 142 error_code =
143 PerformCommonCheckAndPreparationForMoveAndCopy( 143 PerformCommonCheckAndPreparationForMoveAndCopy(
144 context, src_file_path, dest_file_path); 144 context, src_file_path, dest_file_path);
145 if (error_code != base::PLATFORM_FILE_OK) 145 if (error_code != base::PLATFORM_FILE_OK)
146 return error_code; 146 return error_code;
147 147
148 if (DirectoryExists(context, src_file_path)) 148 if (DirectoryExists(context, src_file_path))
149 return CopyOrMoveDirectory(context, src_file_path, dest_file_path, 149 return CopyOrMoveDirectory(context, src_file_path, dest_file_path,
150 true /* copy */); 150 true /* copy */);
151 else 151 return CopyOrMoveFileHelper(context, src_file_path, dest_file_path,
152 return CopyOrMoveFile(context, src_file_path, dest_file_path, 152 true /* copy */);
153 true /* copy */);
154 } 153 }
155 154
156 PlatformFileError FileSystemFileUtil::Move( 155 PlatformFileError FileSystemFileUtil::Move(
157 FileSystemOperationContext* context, 156 FileSystemOperationContext* context,
158 const FilePath& src_file_path, 157 const FilePath& src_file_path,
159 const FilePath& dest_file_path) { 158 const FilePath& dest_file_path) {
160 PlatformFileError error_code; 159 PlatformFileError error_code;
161 error_code = 160 error_code =
162 PerformCommonCheckAndPreparationForMoveAndCopy( 161 PerformCommonCheckAndPreparationForMoveAndCopy(
163 context, src_file_path, dest_file_path); 162 context, src_file_path, dest_file_path);
164 if (error_code != base::PLATFORM_FILE_OK) 163 if (error_code != base::PLATFORM_FILE_OK)
165 return error_code; 164 return error_code;
166 165
167 // TODO(dmikurube): ReplaceFile if in the same domain and filesystem type. 166 // TODO(dmikurube): ReplaceFile if in the same domain and filesystem type.
168 if (DirectoryExists(context, src_file_path)) 167 if (DirectoryExists(context, src_file_path))
169 return CopyOrMoveDirectory(context, src_file_path, dest_file_path, 168 return CopyOrMoveDirectory(context, src_file_path, dest_file_path,
170 false /* copy */); 169 false /* copy */);
171 else 170 return CopyOrMoveFileHelper(context, src_file_path, dest_file_path,
172 return CopyOrMoveFile(context, src_file_path, dest_file_path, 171 false /* copy */);
173 false /* copy */);
174 } 172 }
175 173
176 PlatformFileError FileSystemFileUtil::Delete( 174 PlatformFileError FileSystemFileUtil::Delete(
177 FileSystemOperationContext* context, 175 FileSystemOperationContext* context,
178 const FilePath& file_path, 176 const FilePath& file_path,
179 bool recursive) { 177 bool recursive) {
180 if (DirectoryExists(context, file_path)) { 178 if (DirectoryExists(context, file_path)) {
181 if (!recursive) 179 if (!recursive)
182 return DeleteSingleDirectory(context, file_path); 180 return DeleteSingleDirectory(context, file_path);
183 else 181 else
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 error_code = base::PLATFORM_FILE_ERROR_FAILED; 213 error_code = base::PLATFORM_FILE_ERROR_FAILED;
216 base::ClosePlatformFile(file); 214 base::ClosePlatformFile(file);
217 return error_code; 215 return error_code;
218 } 216 }
219 217
220 PlatformFileError 218 PlatformFileError
221 FileSystemFileUtil::PerformCommonCheckAndPreparationForMoveAndCopy( 219 FileSystemFileUtil::PerformCommonCheckAndPreparationForMoveAndCopy(
222 FileSystemOperationContext* context, 220 FileSystemOperationContext* context,
223 const FilePath& src_file_path, 221 const FilePath& src_file_path,
224 const FilePath& dest_file_path) { 222 const FilePath& dest_file_path) {
223 bool same_file_system =
224 (context->src_origin_url() == context->dest_origin_url()) &&
225 (context->src_type() == context->dest_type());
226 FileSystemFileUtil* dest_util = context->dest_file_system_file_util();
227 DCHECK(dest_util);
228 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.
229 context->file_system_context(), dest_util);
230 FileSystemOperationContext* dest_context;
231 if (same_file_system) {
232 dest_context = context;
233 DCHECK(context->src_file_system_file_util() ==
234 context->dest_file_system_file_util());
235 } else {
236 dest_context = &local_dest_context;
237 dest_context->set_src_type(context->dest_type());
238 dest_context->set_src_origin_url(context->dest_origin_url());
239 dest_context->set_src_virtual_path(context->dest_virtual_path());
240 dest_context->set_allowed_bytes_growth(context->allowed_bytes_growth());
241 }
242
225 // Exits earlier if the source path does not exist. 243 // Exits earlier if the source path does not exist.
226 if (!PathExists(context, src_file_path)) 244 if (!PathExists(context, src_file_path))
227 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 245 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
228 246
229 // The parent of the |dest_file_path| does not exist. 247 // The parent of the |dest_file_path| does not exist.
230 if (!DirectoryExists(context, dest_file_path.DirName())) 248 // If dest_file_path is in the root, dest_file_path.DirName() will be ".",
249 // since we use paths with no leading '/'.
250 FilePath dest_parent = dest_file_path.DirName();
251 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().
252 !dest_util->DirectoryExists(dest_context, dest_parent))
231 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 253 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
232 254
233 // It is an error to try to copy/move an entry into its child. 255 // It is an error to try to copy/move an entry into its child.
234 if (src_file_path.IsParent(dest_file_path)) 256 if (same_file_system && src_file_path.IsParent(dest_file_path))
235 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; 257 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
236 258
237 // Now it is ok to return if the |dest_file_path| does not exist. 259 // Now it is ok to return if the |dest_file_path| does not exist.
238 if (!PathExists(context, dest_file_path)) 260 if (!dest_util->PathExists(dest_context, dest_file_path))
239 return base::PLATFORM_FILE_OK; 261 return base::PLATFORM_FILE_OK;
240 262
241 // |src_file_path| exists and is a directory. 263 // |src_file_path| exists and is a directory.
242 // |dest_file_path| exists and is a file. 264 // |dest_file_path| exists and is a file.
243 bool src_is_directory = DirectoryExists(context, src_file_path); 265 bool src_is_directory = DirectoryExists(context, src_file_path);
244 bool dest_is_directory = DirectoryExists(context, dest_file_path); 266 bool dest_is_directory =
267 dest_util->DirectoryExists(dest_context, dest_file_path);
245 if (src_is_directory && !dest_is_directory) 268 if (src_is_directory && !dest_is_directory)
246 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; 269 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
247 270
248 // |src_file_path| exists and is a file. 271 // |src_file_path| exists and is a file.
249 // |dest_file_path| exists and is a directory. 272 // |dest_file_path| exists and is a directory.
250 if (!src_is_directory && dest_is_directory) 273 if (!src_is_directory && dest_is_directory)
251 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; 274 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
252 275
253 // It is an error to copy/move an entry into the same path. 276 // It is an error to copy/move an entry into the same path.
254 if (src_file_path.value() == dest_file_path.value()) 277 if (same_file_system && (src_file_path.value() == dest_file_path.value()))
255 return base::PLATFORM_FILE_ERROR_EXISTS; 278 return base::PLATFORM_FILE_ERROR_EXISTS;
256 279
257 if (dest_is_directory) { 280 if (dest_is_directory) {
258 // It is an error to copy/move an entry to a non-empty directory. 281 // It is an error to copy/move an entry to a non-empty directory.
259 // Otherwise the copy/move attempt must overwrite the destination, but 282 // Otherwise the copy/move attempt must overwrite the destination, but
260 // the file_util's Copy or Move method doesn't perform overwrite 283 // the file_util's Copy or Move method doesn't perform overwrite
261 // on all platforms, so we delete the destination directory here. 284 // on all platforms, so we delete the destination directory here.
262 // TODO(kinuko): may be better to change the file_util::{Copy,Move}. 285 // TODO(kinuko): may be better to change the file_util::{Copy,Move}.
263 if (base::PLATFORM_FILE_OK != 286 if (base::PLATFORM_FILE_OK !=
264 Delete(context, dest_file_path, false /* recursive */)) { 287 dest_util->Delete(dest_context, dest_file_path,
265 if (!IsDirectoryEmpty(context, dest_file_path)) 288 false /* recursive */)) {
289 if (!dest_util->IsDirectoryEmpty(dest_context, dest_file_path))
266 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; 290 return base::PLATFORM_FILE_ERROR_NOT_EMPTY;
267 return base::PLATFORM_FILE_ERROR_FAILED; 291 return base::PLATFORM_FILE_ERROR_FAILED;
268 } 292 }
269 } 293 }
270 return base::PLATFORM_FILE_OK; 294 return base::PLATFORM_FILE_OK;
271 } 295 }
272 296
273 PlatformFileError FileSystemFileUtil::CopyOrMoveFile( 297 PlatformFileError FileSystemFileUtil::CopyOrMoveFile(
274 FileSystemOperationContext* unused, 298 FileSystemOperationContext* unused,
275 const FilePath& src_file_path, 299 const FilePath& src_file_path,
276 const FilePath& dest_file_path, 300 const FilePath& dest_file_path,
277 bool copy) { 301 bool copy) {
278 if (copy) { 302 if (copy) {
279 if (file_util::CopyFile(src_file_path, dest_file_path)) 303 if (file_util::CopyFile(src_file_path, dest_file_path))
280 return base::PLATFORM_FILE_OK; 304 return base::PLATFORM_FILE_OK;
281 } else { 305 } else {
282 DCHECK(!file_util::DirectoryExists(src_file_path)); 306 DCHECK(!file_util::DirectoryExists(src_file_path));
283 if (file_util::Move(src_file_path, dest_file_path)) 307 if (file_util::Move(src_file_path, dest_file_path))
284 return base::PLATFORM_FILE_OK; 308 return base::PLATFORM_FILE_OK;
285 } 309 }
286 return base::PLATFORM_FILE_ERROR_FAILED; 310 return base::PLATFORM_FILE_ERROR_FAILED;
287 } 311 }
288 312
313 PlatformFileError FileSystemFileUtil::CopyInForeignFile(
314 FileSystemOperationContext* context,
315 const FilePath& src_file_path,
316 const FilePath& dest_file_path) {
317 return CopyOrMoveFile(context, src_file_path, dest_file_path, true);
318 }
319
289 PlatformFileError FileSystemFileUtil::CopyOrMoveDirectory( 320 PlatformFileError FileSystemFileUtil::CopyOrMoveDirectory(
290 FileSystemOperationContext* context, 321 FileSystemOperationContext* context,
291 const FilePath& src_file_path, 322 const FilePath& src_file_path,
292 const FilePath& dest_file_path, 323 const FilePath& dest_file_path,
293 bool copy) { 324 bool copy) {
325 FileSystemFileUtil* dest_util = context->dest_file_system_file_util();
326 FileSystemOperationContext dest_context(
327 context->file_system_context(), dest_util);
328 dest_context.set_src_type(context->dest_type());
329 dest_context.set_src_origin_url(context->dest_origin_url());
330 dest_context.set_src_virtual_path(context->dest_virtual_path());
331 dest_context.set_allowed_bytes_growth(context->allowed_bytes_growth());
332
294 // Re-check PerformCommonCheckAndPreparationForMoveAndCopy() by DCHECK. 333 // Re-check PerformCommonCheckAndPreparationForMoveAndCopy() by DCHECK.
295 DCHECK(DirectoryExists(context, src_file_path)); 334 DCHECK(DirectoryExists(context, src_file_path));
296 DCHECK(DirectoryExists(context, dest_file_path.DirName())); 335 DCHECK((dest_file_path.DirName() == FilePath(FILE_PATH_LITERAL("."))) ||
297 DCHECK(!src_file_path.IsParent(dest_file_path)); 336 dest_util->DirectoryExists(&dest_context, dest_file_path.DirName()));
298 DCHECK(!PathExists(context, dest_file_path)); 337 DCHECK(!dest_util->PathExists(&dest_context, dest_file_path));
338 if ((context->src_origin_url() == context->dest_origin_url()) &&
339 (context->src_type() == context->dest_type()))
340 DCHECK(!src_file_path.IsParent(dest_file_path));
299 341
300 if (!DirectoryExists(context, dest_file_path)) { 342 if (!dest_util->DirectoryExists(&dest_context, dest_file_path)) {
301 PlatformFileError error = CreateDirectory(context, 343 PlatformFileError error = dest_util->CreateDirectory(&dest_context,
302 dest_file_path, false, false); 344 dest_file_path, false, false);
303 if (error != base::PLATFORM_FILE_OK) 345 if (error != base::PLATFORM_FILE_OK)
304 return error; 346 return error;
305 } 347 }
306 348
307 scoped_ptr<AbstractFileEnumerator> file_enum( 349 scoped_ptr<AbstractFileEnumerator> file_enum(
308 CreateFileEnumerator(context, src_file_path)); 350 CreateFileEnumerator(context, src_file_path));
309 FilePath src_file_path_each; 351 FilePath src_file_path_each;
310 while (!(src_file_path_each = file_enum->Next()).empty()) { 352 while (!(src_file_path_each = file_enum->Next()).empty()) {
311 FilePath dest_file_path_each(dest_file_path); 353 FilePath dest_file_path_each(dest_file_path);
312 src_file_path.AppendRelativePath(src_file_path_each, &dest_file_path_each); 354 src_file_path.AppendRelativePath(src_file_path_each, &dest_file_path_each);
313 355
314 if (file_enum->IsDirectory()) { 356 if (file_enum->IsDirectory()) {
315 PlatformFileError error = CreateDirectory(context, 357 PlatformFileError error = dest_util->CreateDirectory(&dest_context,
316 dest_file_path_each, false, false); 358 dest_file_path_each, false, false);
317 if (error != base::PLATFORM_FILE_OK) 359 if (error != base::PLATFORM_FILE_OK)
318 return error; 360 return error;
319 } else { 361 } else {
320 // CopyOrMoveFile here is the virtual overridden member function. 362 PlatformFileError error = CopyOrMoveFileHelper(
321 PlatformFileError error = CopyOrMoveFile(
322 context, src_file_path_each, dest_file_path_each, copy); 363 context, src_file_path_each, dest_file_path_each, copy);
323 if (error != base::PLATFORM_FILE_OK) 364 if (error != base::PLATFORM_FILE_OK)
324 return error; 365 return error;
325 } 366 }
326 } 367 }
327 368
328 if (!copy) { 369 if (!copy) {
329 PlatformFileError error = Delete(context, src_file_path, true); 370 PlatformFileError error = Delete(context, src_file_path, true);
330 if (error != base::PLATFORM_FILE_OK) 371 if (error != base::PLATFORM_FILE_OK)
331 return error; 372 return error;
332 } 373 }
333 return base::PLATFORM_FILE_OK; 374 return base::PLATFORM_FILE_OK;
334 } 375 }
335 376
377 PlatformFileError FileSystemFileUtil::CopyOrMoveFileHelper(
378 FileSystemOperationContext* context,
379 const FilePath& src_file_path,
380 const FilePath& dest_file_path,
381 bool copy) {
382 // CopyOrMoveFile here is the virtual overridden member function.
383 if ((context->src_origin_url() == context->dest_origin_url()) &&
384 (context->src_type() == context->dest_type())) {
385 DCHECK(context->src_file_system_file_util() ==
386 context->dest_file_system_file_util());
387 return CopyOrMoveFile(context, src_file_path, dest_file_path, copy);
388 }
389 base::PlatformFileInfo file_info;
390 FilePath platform_file_path;
391 PlatformFileError error_code;
392 error_code =
393 GetFileInfo(context, src_file_path, &file_info, &platform_file_path);
394 if (error_code != base::PLATFORM_FILE_OK)
395 return error_code;
396
397 DCHECK(context->dest_file_system_file_util());
398 error_code = context->dest_file_system_file_util()->CopyInForeignFile(
399 context, platform_file_path, dest_file_path);
400 if (copy || error_code != base::PLATFORM_FILE_OK)
401 return error_code;
402 return DeleteFile(context, src_file_path);
403 }
404
405
336 PlatformFileError FileSystemFileUtil::DeleteFile( 406 PlatformFileError FileSystemFileUtil::DeleteFile(
337 FileSystemOperationContext* unused, 407 FileSystemOperationContext* unused,
338 const FilePath& file_path) { 408 const FilePath& file_path) {
339 if (!file_util::PathExists(file_path)) 409 if (!file_util::PathExists(file_path))
340 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 410 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
341 if (file_util::DirectoryExists(file_path)) 411 if (file_util::DirectoryExists(file_path))
342 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; 412 return base::PLATFORM_FILE_ERROR_NOT_A_FILE;
343 if (!file_util::Delete(file_path, false)) 413 if (!file_util::Delete(file_path, false))
344 return base::PLATFORM_FILE_ERROR_FAILED; 414 return base::PLATFORM_FILE_ERROR_FAILED;
345 return base::PLATFORM_FILE_OK; 415 return base::PLATFORM_FILE_OK;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 FileSystemFileUtil::CreateFileEnumerator( 515 FileSystemFileUtil::CreateFileEnumerator(
446 FileSystemOperationContext* unused, 516 FileSystemOperationContext* unused,
447 const FilePath& root_path) { 517 const FilePath& root_path) {
448 return new FileSystemFileEnumerator( 518 return new FileSystemFileEnumerator(
449 root_path, true, static_cast<file_util::FileEnumerator::FILE_TYPE>( 519 root_path, true, static_cast<file_util::FileEnumerator::FILE_TYPE>(
450 file_util::FileEnumerator::FILES | 520 file_util::FileEnumerator::FILES |
451 file_util::FileEnumerator::DIRECTORIES)); 521 file_util::FileEnumerator::DIRECTORIES));
452 } 522 }
453 523
454 } // namespace fileapi 524 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698