file_util_proxy.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/file_util_proxy.h" 6 7#include "base/message_loop_proxy.h" 8 9// TODO(jianli): Move the code from anonymous namespace to base namespace so 10// that all of the base:: prefixes would be unnecessary. 11namespace { 12 13namespace { 14 15// Performs common checks for move and copy. 16// This also removes the destination directory if it's non-empty and all other 17// checks are passed (so that the copy/move correctly overwrites the 18// destination). 19static base::PlatformFileError PerformCommonCheckAndPreparationForMoveAndCopy( 20 const FilePath& src_file_path, 21 const FilePath& dest_file_path) { 22 // Exits earlier if the source path does not exist. 23 if (!file_util::PathExists(src_file_path)) 24 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 25 26 // The parent of the |dest_file_path| does not exist. 27 if (!file_util::DirectoryExists(dest_file_path.DirName())) 28 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 29 30 // It is an error to try to copy/move an entry into its child. 31 if (src_file_path.IsParent(dest_file_path)) 32 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; 33 34 // Now it is ok to return if the |dest_file_path| does not exist. 35 if (!file_util::PathExists(dest_file_path)) 36 return base::PLATFORM_FILE_OK; 37 38 // |src_file_path| exists and is a directory. 39 // |dest_file_path| exists and is a file. 40 bool src_is_directory = file_util::DirectoryExists(src_file_path); 41 bool dest_is_directory = file_util::DirectoryExists(dest_file_path); 42 if (src_is_directory && !dest_is_directory) 43 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; 44 45 // |src_file_path| exists and is a file. 46 // |dest_file_path| exists and is a directory. 47 if (!src_is_directory && dest_is_directory) 48 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; 49 50 // It is an error to copy/move an entry into the same path. 51 if (src_file_path.value() == dest_file_path.value()) 52 return base::PLATFORM_FILE_ERROR_EXISTS; 53 54 if (dest_is_directory) { 55 // It is an error to copy/move an entry to a non-empty directory. 56 // Otherwise the copy/move attempt must overwrite the destination, but 57 // the file_util's Copy or Move method doesn't perform overwrite 58 // on all platforms, so we delete the destination directory here. 59 // TODO(kinuko): may be better to change the file_util::{Copy,Move}. 60 if (!file_util::Delete(dest_file_path, false /* recursive */)) { 61 if (!file_util::IsDirectoryEmpty(dest_file_path)) 62 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; 63 return base::PLATFORM_FILE_ERROR_FAILED; 64 } 65 } 66 return base::PLATFORM_FILE_OK; 67} 68 69} // anonymous namespace 70 71class MessageLoopRelay 72 : public base::RefCountedThreadSafe<MessageLoopRelay> { 73 public: 74 MessageLoopRelay() 75 : origin_message_loop_proxy_( 76 base::MessageLoopProxy::CreateForCurrentThread()), 77 error_code_(base::PLATFORM_FILE_OK) { 78 } 79 80 bool Start(scoped_refptr<base::MessageLoopProxy> message_loop_proxy, 81 const tracked_objects::Location& from_here) { 82 return message_loop_proxy->PostTask( 83 from_here, 84 NewRunnableMethod(this, &MessageLoopRelay::ProcessOnTargetThread)); 85 } 86 87 protected: 88 friend class base::RefCountedThreadSafe<MessageLoopRelay>; 89 virtual ~MessageLoopRelay() {} 90 91 // Called to perform work on the FILE thread. 92 virtual void RunWork() = 0; 93 94 // Called to notify the callback on the origin thread. 95 virtual void RunCallback() = 0; 96 97 void set_error_code(base::PlatformFileError error_code) { 98 error_code_ = error_code; 99 } 100 101 base::PlatformFileError error_code() const { 102 return error_code_; 103 } 104 105 private: 106 void ProcessOnTargetThread() { 107 RunWork(); 108 origin_message_loop_proxy_->PostTask( 109 FROM_HERE, 110 NewRunnableMethod(this, &MessageLoopRelay::RunCallback)); 111 } 112 113 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; 114 base::PlatformFileError error_code_; 115}; 116 117class RelayCreateOrOpen : public MessageLoopRelay { 118 public: 119 RelayCreateOrOpen( 120 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, 121 const FilePath& file_path, 122 int file_flags, 123 base::FileUtilProxy::CreateOrOpenCallback* callback) 124 : message_loop_proxy_(message_loop_proxy), 125 file_path_(file_path), 126 file_flags_(file_flags), 127 callback_(callback), 128 file_handle_(base::kInvalidPlatformFileValue), 129 created_(false) { 130 DCHECK(callback); 131 } 132 133 protected: 134 virtual ~RelayCreateOrOpen() { 135 if (file_handle_ != base::kInvalidPlatformFileValue) 136 base::FileUtilProxy::Close(message_loop_proxy_, file_handle_, NULL); 137 } 138 139 virtual void RunWork() { 140 if (!file_util::DirectoryExists(file_path_.DirName())) { 141 // If its parent does not exist, should return NOT_FOUND error. 142 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); 143 return; 144 } 145 base::PlatformFileError error_code = base::PLATFORM_FILE_OK; 146 file_handle_ = base::CreatePlatformFile(file_path_, file_flags_, 147 &created_, &error_code); 148 set_error_code(error_code); 149 } 150 151 virtual void RunCallback() { 152 callback_->Run(error_code(), base::PassPlatformFile(&file_handle_), 153 created_); 154 delete callback_; 155 } 156 157 private: 158 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; 159 FilePath file_path_; 160 int file_flags_; 161 base::FileUtilProxy::CreateOrOpenCallback* callback_; 162 base::PlatformFile file_handle_; 163 bool created_; 164}; 165 166class RelayCreateTemporary : public MessageLoopRelay { 167 public: 168 RelayCreateTemporary( 169 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, 170 base::FileUtilProxy::CreateTemporaryCallback* callback) 171 : message_loop_proxy_(message_loop_proxy), 172 callback_(callback), 173 file_handle_(base::kInvalidPlatformFileValue) { 174 DCHECK(callback); 175 } 176 177 protected: 178 virtual ~RelayCreateTemporary() { 179 if (file_handle_ != base::kInvalidPlatformFileValue) 180 base::FileUtilProxy::Close(message_loop_proxy_, file_handle_, NULL); 181 } 182 183 virtual void RunWork() { 184 // TODO(darin): file_util should have a variant of CreateTemporaryFile 185 // that returns a FilePath and a PlatformFile. 186 file_util::CreateTemporaryFile(&file_path_); 187 188 // Use a fixed set of flags that are appropriate for writing to a temporary 189 // file from the IO thread using a net::FileStream. 190 int file_flags = 191 base::PLATFORM_FILE_CREATE_ALWAYS | 192 base::PLATFORM_FILE_WRITE | 193 base::PLATFORM_FILE_ASYNC | 194 base::PLATFORM_FILE_TEMPORARY; 195 base::PlatformFileError error_code = base::PLATFORM_FILE_OK; 196 file_handle_ = base::CreatePlatformFile(file_path_, file_flags, 197 NULL, &error_code); 198 set_error_code(error_code); 199 } 200 201 virtual void RunCallback() { 202 callback_->Run(error_code(), base::PassPlatformFile(&file_handle_), 203 file_path_); 204 delete callback_; 205 } 206 207 private: 208 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; 209 base::FileUtilProxy::CreateTemporaryCallback* callback_; 210 base::PlatformFile file_handle_; 211 FilePath file_path_; 212}; 213 214class RelayWithStatusCallback : public MessageLoopRelay { 215 public: 216 explicit RelayWithStatusCallback( 217 base::FileUtilProxy::StatusCallback* callback) 218 : callback_(callback) { 219 // It is OK for callback to be NULL. 220 } 221 222 protected: 223 virtual void RunCallback() { 224 // The caller may not have been interested in the result. 225 if (callback_) { 226 callback_->Run(error_code()); 227 delete callback_; 228 } 229 } 230 231 private: 232 base::FileUtilProxy::StatusCallback* callback_; 233}; 234 235class RelayClose : public RelayWithStatusCallback { 236 public: 237 RelayClose(base::PlatformFile file_handle, 238 base::FileUtilProxy::StatusCallback* callback) 239 : RelayWithStatusCallback(callback), 240 file_handle_(file_handle) { 241 } 242 243 protected: 244 virtual void RunWork() { 245 if (!base::ClosePlatformFile(file_handle_)) 246 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 247 } 248 249 private: 250 base::PlatformFile file_handle_; 251}; 252 253class RelayEnsureFileExists : public MessageLoopRelay { 254 public: 255 RelayEnsureFileExists( 256 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, 257 const FilePath& file_path, 258 base::FileUtilProxy::EnsureFileExistsCallback* callback) 259 : message_loop_proxy_(message_loop_proxy), 260 file_path_(file_path), 261 callback_(callback), 262 created_(false) { 263 DCHECK(callback); 264 } 265 266 protected: 267 virtual void RunWork() { 268 if (!file_util::DirectoryExists(file_path_.DirName())) { 269 // If its parent does not exist, should return NOT_FOUND error. 270 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); 271 return; 272 } 273 base::PlatformFileError error_code = base::PLATFORM_FILE_OK; 274 // Tries to create the |file_path_| exclusively. This should fail 275 // with PLATFORM_FILE_ERROR_EXISTS if the path already exists. 276 base::PlatformFile handle = base::CreatePlatformFile( 277 file_path_, 278 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_READ, 279 &created_, &error_code); 280 if (error_code == base::PLATFORM_FILE_ERROR_EXISTS) { 281 // Make sure created_ is false. 282 created_ = false; 283 error_code = base::PLATFORM_FILE_OK; 284 } 285 if (handle != base::kInvalidPlatformFileValue) 286 base::ClosePlatformFile(handle); 287 set_error_code(error_code); 288 } 289 290 virtual void RunCallback() { 291 callback_->Run(error_code(), created_); 292 delete callback_; 293 } 294 295 private: 296 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; 297 FilePath file_path_; 298 base::FileUtilProxy::EnsureFileExistsCallback* callback_; 299 bool created_; 300}; 301 302class RelayDelete : public RelayWithStatusCallback { 303 public: 304 RelayDelete(const FilePath& file_path, 305 bool recursive, 306 base::FileUtilProxy::StatusCallback* callback) 307 : RelayWithStatusCallback(callback), 308 file_path_(file_path), 309 recursive_(recursive) { 310 } 311 312 protected: 313 virtual void RunWork() { 314 if (!file_util::PathExists(file_path_)) { 315 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); 316 return; 317 } 318 if (!file_util::Delete(file_path_, recursive_)) { 319 if (!recursive_ && !file_util::IsDirectoryEmpty(file_path_)) { 320 set_error_code(base::PLATFORM_FILE_ERROR_NOT_EMPTY); 321 return; 322 } 323 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 324 } 325 } 326 327 private: 328 FilePath file_path_; 329 bool recursive_; 330}; 331 332class RelayCopy : public RelayWithStatusCallback { 333 public: 334 RelayCopy(const FilePath& src_file_path, 335 const FilePath& dest_file_path, 336 base::FileUtilProxy::StatusCallback* callback) 337 : RelayWithStatusCallback(callback), 338 src_file_path_(src_file_path), 339 dest_file_path_(dest_file_path) { 340 } 341 342 protected: 343 virtual void RunWork() { 344 set_error_code(PerformCommonCheckAndPreparationForMoveAndCopy( 345 src_file_path_, dest_file_path_)); 346 if (error_code() != base::PLATFORM_FILE_OK) 347 return; 348 if (!file_util::CopyDirectory(src_file_path_, dest_file_path_, 349 true /* recursive */)) 350 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 351 } 352 353 private: 354 FilePath src_file_path_; 355 FilePath dest_file_path_; 356}; 357 358class RelayMove : public RelayWithStatusCallback { 359 public: 360 RelayMove(const FilePath& src_file_path, 361 const FilePath& dest_file_path, 362 base::FileUtilProxy::StatusCallback* callback) 363 : RelayWithStatusCallback(callback), 364 src_file_path_(src_file_path), 365 dest_file_path_(dest_file_path) { 366 } 367 368 protected: 369 virtual void RunWork() { 370 set_error_code(PerformCommonCheckAndPreparationForMoveAndCopy( 371 src_file_path_, dest_file_path_)); 372 if (error_code() != base::PLATFORM_FILE_OK) 373 return; 374 if (!file_util::Move(src_file_path_, dest_file_path_)) 375 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 376 } 377 378 private: 379 FilePath src_file_path_; 380 FilePath dest_file_path_; 381}; 382 383class RelayCreateDirectory : public RelayWithStatusCallback { 384 public: 385 RelayCreateDirectory( 386 const FilePath& file_path, 387 bool exclusive, 388 bool recursive, 389 base::FileUtilProxy::StatusCallback* callback) 390 : RelayWithStatusCallback(callback), 391 file_path_(file_path), 392 exclusive_(exclusive), 393 recursive_(recursive) { 394 } 395 396 protected: 397 virtual void RunWork() { 398 bool path_exists = file_util::PathExists(file_path_); 399 // If parent dir of file doesn't exist. 400 if (!recursive_ && !file_util::PathExists(file_path_.DirName())) { 401 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); 402 return; 403 } 404 if (exclusive_ && path_exists) { 405 set_error_code(base::PLATFORM_FILE_ERROR_EXISTS); 406 return; 407 } 408 // If file exists at the path. 409 if (path_exists && !file_util::DirectoryExists(file_path_)) { 410 set_error_code(base::PLATFORM_FILE_ERROR_EXISTS); 411 return; 412 } 413 if (!file_util::CreateDirectory(file_path_)) 414 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 415 } 416 417 private: 418 FilePath file_path_; 419 bool exclusive_; 420 bool recursive_; 421}; 422 423class RelayReadDirectory : public MessageLoopRelay { 424 public: 425 RelayReadDirectory(const FilePath& file_path, 426 base::FileUtilProxy::ReadDirectoryCallback* callback) 427 : callback_(callback), file_path_(file_path) { 428 DCHECK(callback); 429 } 430 431 protected: 432 virtual void RunWork() { 433 // TODO(kkanetkar): Implement directory read in multiple chunks. 434 if (!file_util::DirectoryExists(file_path_)) { 435 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); 436 return; 437 } 438 439 file_util::FileEnumerator file_enum( 440 file_path_, false, static_cast<file_util::FileEnumerator::FILE_TYPE>( 441 file_util::FileEnumerator::FILES | 442 file_util::FileEnumerator::DIRECTORIES)); 443 FilePath current; 444 while (!(current = file_enum.Next()).empty()) { 445 base::file_util_proxy::Entry entry; 446 file_util::FileEnumerator::FindInfo info; 447 file_enum.GetFindInfo(&info); 448 entry.is_directory = file_enum.IsDirectory(info); 449 // This will just give the entry's name instead of entire path 450 // if we use current.value(). 451 entry.name = file_util::FileEnumerator::GetFilename(info).value(); 452 entries_.push_back(entry); 453 } 454 } 455 456 virtual void RunCallback() { 457 callback_->Run(error_code(), entries_); 458 delete callback_; 459 } 460 461 private: 462 base::FileUtilProxy::ReadDirectoryCallback* callback_; 463 FilePath file_path_; 464 std::vector<base::file_util_proxy::Entry> entries_; 465}; 466 467class RelayGetFileInfo : public MessageLoopRelay { 468 public: 469 RelayGetFileInfo(const FilePath& file_path, 470 base::FileUtilProxy::GetFileInfoCallback* callback) 471 : callback_(callback), 472 file_path_(file_path) { 473 DCHECK(callback); 474 } 475 476 protected: 477 virtual void RunWork() { 478 if (!file_util::PathExists(file_path_)) { 479 set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); 480 return; 481 } 482 if (!file_util::GetFileInfo(file_path_, &file_info_)) 483 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 484 } 485 486 virtual void RunCallback() { 487 callback_->Run(error_code(), file_info_); 488 delete callback_; 489 } 490 491 private: 492 base::FileUtilProxy::GetFileInfoCallback* callback_; 493 FilePath file_path_; 494 base::PlatformFileInfo file_info_; 495}; 496 497class RelayGetFileInfoFromPlatformFile : public MessageLoopRelay { 498 public: 499 RelayGetFileInfoFromPlatformFile( 500 base::PlatformFile file, 501 base::FileUtilProxy::GetFileInfoCallback* callback) 502 : callback_(callback), 503 file_(file) { 504 DCHECK(callback); 505 } 506 507 protected: 508 virtual void RunWork() { 509 if (!base::GetPlatformFileInfo(file_, &file_info_)) 510 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 511 } 512 513 virtual void RunCallback() { 514 callback_->Run(error_code(), file_info_); 515 delete callback_; 516 } 517 518 private: 519 base::FileUtilProxy::GetFileInfoCallback* callback_; 520 base::PlatformFile file_; 521 base::PlatformFileInfo file_info_; 522}; 523 524class RelayRead : public MessageLoopRelay { 525 public: 526 RelayRead(base::PlatformFile file, 527 int64 offset, 528 char* buffer, 529 int bytes_to_read, 530 base::FileUtilProxy::ReadWriteCallback* callback) 531 : file_(file), 532 offset_(offset), 533 buffer_(buffer), 534 bytes_to_read_(bytes_to_read), 535 callback_(callback), 536 bytes_read_(0) { 537 } 538 539 protected: 540 virtual void RunWork() { 541 bytes_read_ = base::ReadPlatformFile(file_, offset_, buffer_, 542 bytes_to_read_); 543 if (bytes_read_ < 0) 544 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 545 } 546 547 virtual void RunCallback() { 548 if (callback_) { 549 callback_->Run(error_code(), bytes_read_); 550 delete callback_; 551 } 552 } 553 554 private: 555 base::PlatformFile file_; 556 int64 offset_; 557 char* buffer_; 558 int bytes_to_read_; 559 base::FileUtilProxy::ReadWriteCallback* callback_; 560 int bytes_read_; 561}; 562 563class RelayWrite : public MessageLoopRelay { 564 public: 565 RelayWrite(base::PlatformFile file, 566 int64 offset, 567 const char* buffer, 568 int bytes_to_write, 569 base::FileUtilProxy::ReadWriteCallback* callback) 570 : file_(file), 571 offset_(offset), 572 buffer_(buffer), 573 bytes_to_write_(bytes_to_write), 574 callback_(callback) { 575 } 576 577 protected: 578 virtual void RunWork() { 579 bytes_written_ = base::WritePlatformFile(file_, offset_, buffer_, 580 bytes_to_write_); 581 if (bytes_written_ < 0) 582 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 583 } 584 585 virtual void RunCallback() { 586 if (callback_) { 587 callback_->Run(error_code(), bytes_written_); 588 delete callback_; 589 } 590 } 591 592 private: 593 base::PlatformFile file_; 594 int64 offset_; 595 const char* buffer_; 596 int bytes_to_write_; 597 base::FileUtilProxy::ReadWriteCallback* callback_; 598 int bytes_written_; 599}; 600 601class RelayTouch : public RelayWithStatusCallback { 602 public: 603 RelayTouch(base::PlatformFile file, 604 const base::Time& last_access_time, 605 const base::Time& last_modified_time, 606 base::FileUtilProxy::StatusCallback* callback) 607 : RelayWithStatusCallback(callback), 608 file_(file), 609 last_access_time_(last_access_time), 610 last_modified_time_(last_modified_time) { 611 } 612 613 protected: 614 virtual void RunWork() { 615 if (!base::TouchPlatformFile(file_, last_access_time_, last_modified_time_)) 616 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 617 } 618 619 private: 620 base::PlatformFile file_; 621 base::Time last_access_time_; 622 base::Time last_modified_time_; 623}; 624 625class RelayTouchFilePath : public RelayWithStatusCallback { 626 public: 627 RelayTouchFilePath(const FilePath& file_path, 628 const base::Time& last_access_time, 629 const base::Time& last_modified_time, 630 base::FileUtilProxy::StatusCallback* callback) 631 : RelayWithStatusCallback(callback), 632 file_path_(file_path), 633 last_access_time_(last_access_time), 634 last_modified_time_(last_modified_time) { 635 } 636 637 protected: 638 virtual void RunWork() { 639 if (!file_util::TouchFile( 640 file_path_, last_access_time_, last_modified_time_)) 641 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 642 } 643 644 private: 645 FilePath file_path_; 646 base::Time last_access_time_; 647 base::Time last_modified_time_; 648}; 649 650class RelayTruncatePlatformFile : public RelayWithStatusCallback { 651 public: 652 RelayTruncatePlatformFile(base::PlatformFile file, 653 int64 length, 654 base::FileUtilProxy::StatusCallback* callback) 655 : RelayWithStatusCallback(callback), 656 file_(file), 657 length_(length) { 658 } 659 660 protected: 661 virtual void RunWork() { 662 if (!base::TruncatePlatformFile(file_, length_)) 663 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 664 } 665 666 private: 667 base::PlatformFile file_; 668 int64 length_; 669}; 670 671class RelayTruncate : public RelayWithStatusCallback { 672 public: 673 RelayTruncate(const FilePath& path, 674 int64 length, 675 base::FileUtilProxy::StatusCallback* callback) 676 : RelayWithStatusCallback(callback), 677 path_(path), 678 length_(length) { 679 } 680 681 protected: 682 virtual void RunWork() { 683 base::PlatformFileError error_code(base::PLATFORM_FILE_ERROR_FAILED); 684 base::PlatformFile file = 685 base::CreatePlatformFile( 686 path_, 687 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE, 688 NULL, 689 &error_code); 690 if (error_code != base::PLATFORM_FILE_OK) { 691 set_error_code(error_code); 692 return; 693 } 694 if (!base::TruncatePlatformFile(file, length_)) 695 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 696 base::ClosePlatformFile(file); 697 } 698 699 private: 700 FilePath path_; 701 int64 length_; 702}; 703 704class RelayFlush : public RelayWithStatusCallback { 705 public: 706 RelayFlush(base::PlatformFile file, 707 base::FileUtilProxy::StatusCallback* callback) 708 : RelayWithStatusCallback(callback), 709 file_(file) { 710 } 711 712 protected: 713 virtual void RunWork() { 714 if (!base::FlushPlatformFile(file_)) 715 set_error_code(base::PLATFORM_FILE_ERROR_FAILED); 716 } 717 718 private: 719 base::PlatformFile file_; 720}; 721 722bool Start(const tracked_objects::Location& from_here, 723 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, 724 scoped_refptr<MessageLoopRelay> relay) { 725 return relay->Start(message_loop_proxy, from_here); 726} 727 728} // namespace 729 730namespace base { 731 732// static 733bool FileUtilProxy::CreateOrOpen( 734 scoped_refptr<MessageLoopProxy> message_loop_proxy, 735 const FilePath& file_path, int file_flags, 736 CreateOrOpenCallback* callback) { 737 return Start(FROM_HERE, message_loop_proxy, new RelayCreateOrOpen( 738 message_loop_proxy, file_path, file_flags, callback)); 739} 740 741// static 742bool FileUtilProxy::CreateTemporary( 743 scoped_refptr<MessageLoopProxy> message_loop_proxy, 744 CreateTemporaryCallback* callback) { 745 return Start(FROM_HERE, message_loop_proxy, 746 new RelayCreateTemporary(message_loop_proxy, callback)); 747} 748 749// static 750bool FileUtilProxy::CreateDirectory( 751 scoped_refptr<MessageLoopProxy> message_loop_proxy, 752 const FilePath& file_path, 753 bool exclusive, 754 bool recursive, 755 StatusCallback* callback) { 756 return Start(FROM_HERE, message_loop_proxy, new RelayCreateDirectory( 757 file_path, exclusive, recursive, callback)); 758} 759 760// static 761bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy, 762 base::PlatformFile file_handle, 763 StatusCallback* callback) { 764 return Start(FROM_HERE, message_loop_proxy, 765 new RelayClose(file_handle, callback)); 766} 767 768// static 769bool FileUtilProxy::EnsureFileExists( 770 scoped_refptr<MessageLoopProxy> message_loop_proxy, 771 const FilePath& file_path, 772 EnsureFileExistsCallback* callback) { 773 return Start(FROM_HERE, message_loop_proxy, new RelayEnsureFileExists( 774 message_loop_proxy, file_path, callback)); 775} 776 777// static 778bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, 779 const FilePath& file_path, 780 bool recursive, 781 StatusCallback* callback) { 782 return Start(FROM_HERE, message_loop_proxy, 783 new RelayDelete(file_path, recursive, callback)); 784} 785 786// static 787bool FileUtilProxy::Copy(scoped_refptr<MessageLoopProxy> message_loop_proxy, 788 const FilePath& src_file_path, 789 const FilePath& dest_file_path, 790 StatusCallback* callback) { 791 return Start(FROM_HERE, message_loop_proxy, 792 new RelayCopy(src_file_path, dest_file_path, callback)); 793} 794 795// static 796bool FileUtilProxy::Move(scoped_refptr<MessageLoopProxy> message_loop_proxy, 797 const FilePath& src_file_path, 798 const FilePath& dest_file_path, 799 StatusCallback* callback) { 800 return Start(FROM_HERE, message_loop_proxy, 801 new RelayMove(src_file_path, dest_file_path, callback)); 802} 803 804// static 805bool FileUtilProxy::ReadDirectory( 806 scoped_refptr<MessageLoopProxy> message_loop_proxy, 807 const FilePath& file_path, 808 ReadDirectoryCallback* callback) { 809 return Start(FROM_HERE, message_loop_proxy, new RelayReadDirectory( 810 file_path, callback)); 811} 812 813// Retrieves the information about a file. It is invalid to pass NULL for the 814// callback. 815bool FileUtilProxy::GetFileInfo( 816 scoped_refptr<MessageLoopProxy> message_loop_proxy, 817 const FilePath& file_path, 818 GetFileInfoCallback* callback) { 819 return Start(FROM_HERE, message_loop_proxy, new RelayGetFileInfo( 820 file_path, callback)); 821} 822 823// static 824bool FileUtilProxy::RecursiveDelete( 825 scoped_refptr<MessageLoopProxy> message_loop_proxy, 826 const FilePath& file_path, 827 StatusCallback* callback) { 828 return Start(FROM_HERE, message_loop_proxy, 829 new RelayDelete(file_path, true, callback)); 830} 831 832// static 833bool FileUtilProxy::GetFileInfoFromPlatformFile( 834 scoped_refptr<MessageLoopProxy> message_loop_proxy, 835 PlatformFile file, 836 GetFileInfoCallback* callback) { 837 return Start(FROM_HERE, message_loop_proxy, 838 new RelayGetFileInfoFromPlatformFile(file, callback)); 839} 840 841// static 842bool FileUtilProxy::Read( 843 scoped_refptr<MessageLoopProxy> message_loop_proxy, 844 PlatformFile file, 845 int64 offset, 846 char* buffer, 847 int bytes_to_read, 848 ReadWriteCallback* callback) { 849 return Start(FROM_HERE, message_loop_proxy, 850 new RelayRead(file, offset, buffer, bytes_to_read, callback)); 851} 852 853// static 854bool FileUtilProxy::Write( 855 scoped_refptr<MessageLoopProxy> message_loop_proxy, 856 PlatformFile file, 857 int64 offset, 858 const char* buffer, 859 int bytes_to_write, 860 ReadWriteCallback* callback) { 861 return Start(FROM_HERE, message_loop_proxy, 862 new RelayWrite(file, offset, buffer, bytes_to_write, callback)); 863} 864 865// static 866bool FileUtilProxy::Touch( 867 scoped_refptr<MessageLoopProxy> message_loop_proxy, 868 PlatformFile file, 869 const base::Time& last_access_time, 870 const base::Time& last_modified_time, 871 StatusCallback* callback) { 872 return Start(FROM_HERE, message_loop_proxy, 873 new RelayTouch(file, last_access_time, last_modified_time, 874 callback)); 875} 876 877// static 878bool FileUtilProxy::Touch( 879 scoped_refptr<MessageLoopProxy> message_loop_proxy, 880 const FilePath& file_path, 881 const base::Time& last_access_time, 882 const base::Time& last_modified_time, 883 StatusCallback* callback) { 884 return Start(FROM_HERE, message_loop_proxy, 885 new RelayTouchFilePath(file_path, last_access_time, 886 last_modified_time, callback)); 887} 888 889// static 890bool FileUtilProxy::Truncate( 891 scoped_refptr<MessageLoopProxy> message_loop_proxy, 892 PlatformFile file, 893 int64 length, 894 StatusCallback* callback) { 895 return Start(FROM_HERE, message_loop_proxy, 896 new RelayTruncatePlatformFile(file, length, callback)); 897} 898 899// static 900bool FileUtilProxy::Truncate( 901 scoped_refptr<MessageLoopProxy> message_loop_proxy, 902 const FilePath& path, 903 int64 length, 904 StatusCallback* callback) { 905 return Start(FROM_HERE, message_loop_proxy, 906 new RelayTruncate(path, length, callback)); 907} 908 909// static 910bool FileUtilProxy::Flush( 911 scoped_refptr<MessageLoopProxy> message_loop_proxy, 912 PlatformFile file, 913 StatusCallback* callback) { 914 return Start(FROM_HERE, message_loop_proxy, new RelayFlush(file, callback)); 915} 916 917} // namespace base 918