| OLD | NEW | 
|    1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |    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 |    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 "base/file_util_proxy.h" |    5 #include "base/file_util_proxy.h" | 
|    6  |    6  | 
|    7 #include "base/message_loop_proxy.h" |    7 #include "base/message_loop_proxy.h" | 
|    8  |    8  | 
|    9 // TODO(jianli): Move the code from anonymous namespace to base namespace so |    9 // TODO(jianli): Move the code from anonymous namespace to base namespace so | 
|   10 // that all of the base:: prefixes would be unnecessary. |   10 // that all of the base:: prefixes would be unnecessary. | 
|   11 namespace { |   11 namespace { | 
|   12  |   12  | 
 |   13 namespace { | 
 |   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 destination
     ). | 
 |   18 static base::PlatformFileError PerformCommonCheckAndPreparationForMoveAndCopy( | 
 |   19     const FilePath& src_file_path, | 
 |   20     const FilePath& dest_file_path) { | 
 |   21   // Exits earlier if the source path does not exist. | 
 |   22   if (!file_util::PathExists(src_file_path)) | 
 |   23     return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 
 |   24  | 
 |   25   // The parent of the |dest_file_path| does not exist. | 
 |   26   if (!file_util::DirectoryExists(dest_file_path.DirName())) | 
 |   27     return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 
 |   28  | 
 |   29   // It is an error to try to copy/move an entry into its child. | 
 |   30   if (file_util::ContainsPath(src_file_path, dest_file_path)) | 
 |   31     return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; | 
 |   32  | 
 |   33   // Now it is ok to return if the |dest_file_path| does not exist. | 
 |   34   if (!file_util::PathExists(dest_file_path)) | 
 |   35     return base::PLATFORM_FILE_OK; | 
 |   36  | 
 |   37   // |src_file_path| exists and is a directory. | 
 |   38   // |dest_file_path| exists and is a file. | 
 |   39   bool src_is_directory = file_util::DirectoryExists(src_file_path); | 
 |   40   bool dest_is_directory = file_util::DirectoryExists(dest_file_path); | 
 |   41   if (src_is_directory && !dest_is_directory) | 
 |   42     return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | 
 |   43  | 
 |   44   // |src_file_path| exists and is a file. | 
 |   45   // |dest_file_path| exists and is a directory. | 
 |   46   if (!src_is_directory && dest_is_directory) | 
 |   47     return base::PLATFORM_FILE_ERROR_NOT_A_FILE; | 
 |   48  | 
 |   49   // It is an error to copy/move an entry into the same path. | 
 |   50   if (src_file_path.value() == dest_file_path.value()) | 
 |   51     return base::PLATFORM_FILE_ERROR_EXISTS; | 
 |   52  | 
 |   53   if (dest_is_directory) { | 
 |   54     // It is an error to copy/move an entry to a non-empty directory. | 
 |   55     // Otherwise the copy/move attempt must overwrite the destination, but | 
 |   56     // the file_util's Copy or Move method doesn't perform overwrite | 
 |   57     // on all platforms, so we delete the destination directory here. | 
 |   58     // TODO(kinuko): may be better to change the file_util::{Copy,Move}. | 
 |   59     if (!file_util::Delete(dest_file_path, false /* recursive */)) { | 
 |   60       if (!file_util::IsDirectoryEmpty(dest_file_path)) | 
 |   61         return base::PLATFORM_FILE_ERROR_NOT_EMPTY; | 
 |   62       return base::PLATFORM_FILE_ERROR_FAILED; | 
 |   63     } | 
 |   64   } | 
 |   65   return base::PLATFORM_FILE_OK; | 
 |   66 } | 
 |   67  | 
 |   68 } // anonymous namespace | 
 |   69  | 
|   13 class MessageLoopRelay |   70 class MessageLoopRelay | 
|   14     : public base::RefCountedThreadSafe<MessageLoopRelay> { |   71     : public base::RefCountedThreadSafe<MessageLoopRelay> { | 
|   15  public: |   72  public: | 
|   16   MessageLoopRelay() |   73   MessageLoopRelay() | 
|   17       : origin_message_loop_proxy_( |   74       : origin_message_loop_proxy_( | 
|   18             base::MessageLoopProxy::CreateForCurrentThread()), |   75             base::MessageLoopProxy::CreateForCurrentThread()), | 
|   19         error_code_(base::PLATFORM_FILE_OK) { |   76         error_code_(base::PLATFORM_FILE_OK) { | 
|   20   } |   77   } | 
|   21  |   78  | 
|   22   bool Start(scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |   79   bool Start(scoped_refptr<base::MessageLoopProxy> message_loop_proxy, | 
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  198   } |  255   } | 
|  199  |  256  | 
|  200  protected: |  257  protected: | 
|  201   virtual void RunWork() { |  258   virtual void RunWork() { | 
|  202     if (!file_util::PathExists(file_path_)) { |  259     if (!file_util::PathExists(file_path_)) { | 
|  203       set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |  260       set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); | 
|  204       return; |  261       return; | 
|  205     } |  262     } | 
|  206     if (!file_util::Delete(file_path_, recursive_)) { |  263     if (!file_util::Delete(file_path_, recursive_)) { | 
|  207       if (!recursive_ && !file_util::IsDirectoryEmpty(file_path_)) { |  264       if (!recursive_ && !file_util::IsDirectoryEmpty(file_path_)) { | 
|  208         set_error_code(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); |  265         set_error_code(base::PLATFORM_FILE_ERROR_NOT_EMPTY); | 
|  209         return; |  266         return; | 
|  210       } |  267       } | 
|  211       set_error_code(base::PLATFORM_FILE_ERROR_FAILED); |  268       set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | 
|  212     } |  269     } | 
|  213   } |  270   } | 
|  214  |  271  | 
|  215  private: |  272  private: | 
|  216   FilePath file_path_; |  273   FilePath file_path_; | 
|  217   bool recursive_; |  274   bool recursive_; | 
|  218 }; |  275 }; | 
|  219  |  276  | 
|  220 class RelayCopy : public RelayWithStatusCallback { |  277 class RelayCopy : public RelayWithStatusCallback { | 
|  221  public: |  278  public: | 
|  222   RelayCopy(const FilePath& src_file_path, |  279   RelayCopy(const FilePath& src_file_path, | 
|  223             const FilePath& dest_file_path, |  280             const FilePath& dest_file_path, | 
|  224             base::FileUtilProxy::StatusCallback* callback) |  281             base::FileUtilProxy::StatusCallback* callback) | 
|  225       : RelayWithStatusCallback(callback), |  282       : RelayWithStatusCallback(callback), | 
|  226         src_file_path_(src_file_path), |  283         src_file_path_(src_file_path), | 
|  227         dest_file_path_(dest_file_path) { |  284         dest_file_path_(dest_file_path) { | 
|  228   } |  285   } | 
|  229  |  286  | 
|  230  protected: |  287  protected: | 
|  231   virtual void RunWork() { |  288   virtual void RunWork() { | 
|  232     bool dest_path_exists = file_util::PathExists(dest_file_path_); |  289     set_error_code(PerformCommonCheckAndPreparationForMoveAndCopy( | 
|  233     if (!dest_path_exists && |  290         src_file_path_, dest_file_path_)); | 
|  234         !file_util::DirectoryExists(dest_file_path_.DirName())) { |  291     if (error_code() != base::PLATFORM_FILE_OK) | 
|  235       set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |  | 
|  236       return; |  292       return; | 
|  237     } |  293     if (!file_util::CopyDirectory(src_file_path_, dest_file_path_, | 
|  238     // |src_file_path| exists and is a directory. |  294         true /* recursive */)) | 
|  239     // |dest_file_path| exists and is a file. |  | 
|  240     if (file_util::DirectoryExists(src_file_path_) && |  | 
|  241         dest_path_exists && !file_util::DirectoryExists(dest_file_path_)) { |  | 
|  242       set_error_code(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY); |  | 
|  243       return; |  | 
|  244     } |  | 
|  245     if (file_util::ContainsPath(src_file_path_, dest_file_path_)) { |  | 
|  246       set_error_code(base::PLATFORM_FILE_ERROR_FAILED); |  295       set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | 
|  247       return; |  | 
|  248     } |  | 
|  249     if (!file_util::CopyDirectory(src_file_path_, dest_file_path_, |  | 
|  250         true /* recursive */)) { |  | 
|  251       if (!file_util::PathExists(src_file_path_)) { |  | 
|  252         set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |  | 
|  253         return; |  | 
|  254       } |  | 
|  255       if (src_file_path_.value() == dest_file_path_.value()) { |  | 
|  256         set_error_code(base::PLATFORM_FILE_ERROR_EXISTS); |  | 
|  257         return; |  | 
|  258       } |  | 
|  259       // Something else went wrong. |  | 
|  260       set_error_code(base::PLATFORM_FILE_ERROR_FAILED); |  | 
|  261     } |  | 
|  262   } |  296   } | 
|  263  |  297  | 
|  264  private: |  298  private: | 
|  265   FilePath src_file_path_; |  299   FilePath src_file_path_; | 
|  266   FilePath dest_file_path_; |  300   FilePath dest_file_path_; | 
|  267 }; |  301 }; | 
|  268  |  302  | 
|  269 class RelayMove : public RelayWithStatusCallback { |  303 class RelayMove : public RelayWithStatusCallback { | 
|  270  public: |  304  public: | 
|  271   RelayMove(const FilePath& src_file_path, |  305   RelayMove(const FilePath& src_file_path, | 
|  272             const FilePath& dest_file_path, |  306             const FilePath& dest_file_path, | 
|  273             base::FileUtilProxy::StatusCallback* callback) |  307             base::FileUtilProxy::StatusCallback* callback) | 
|  274       : RelayWithStatusCallback(callback), |  308       : RelayWithStatusCallback(callback), | 
|  275         src_file_path_(src_file_path), |  309         src_file_path_(src_file_path), | 
|  276         dest_file_path_(dest_file_path) { |  310         dest_file_path_(dest_file_path) { | 
|  277   } |  311   } | 
|  278  |  312  | 
|  279  protected: |  313  protected: | 
|  280   virtual void RunWork() { |  314   virtual void RunWork() { | 
|  281     bool dest_path_exists = file_util::PathExists(dest_file_path_); |  315     set_error_code(PerformCommonCheckAndPreparationForMoveAndCopy( | 
|  282     if (!dest_path_exists && |  316         src_file_path_, dest_file_path_)); | 
|  283         !file_util::DirectoryExists(dest_file_path_.DirName())) { |  317     if (error_code() != base::PLATFORM_FILE_OK) | 
|  284       set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |  | 
|  285       return; |  318       return; | 
|  286     } |  319     if (!file_util::Move(src_file_path_, dest_file_path_)) | 
|  287     // |src_file_path| exists and is a directory. |  | 
|  288     // |dest_file_path| exists and is a file. |  | 
|  289     if (file_util::DirectoryExists(src_file_path_) && |  | 
|  290           dest_path_exists && |  | 
|  291           !file_util::DirectoryExists(dest_file_path_)) { |  | 
|  292       set_error_code(base::PLATFORM_FILE_ERROR_EXISTS); |  | 
|  293       return; |  | 
|  294     } |  | 
|  295     if (file_util::ContainsPath(src_file_path_, dest_file_path_)) { |  | 
|  296       set_error_code(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); |  | 
|  297       return; |  | 
|  298     } |  | 
|  299     if (!file_util::Move(src_file_path_, dest_file_path_)) { |  | 
|  300       if (!file_util::PathExists(src_file_path_)) { |  | 
|  301         set_error_code(base::PLATFORM_FILE_ERROR_NOT_FOUND); |  | 
|  302         return; |  | 
|  303       } |  | 
|  304       if (src_file_path_.value() == dest_file_path_.value()) { |  | 
|  305         set_error_code(base::PLATFORM_FILE_ERROR_EXISTS); |  | 
|  306         return; |  | 
|  307       } |  | 
|  308       // Something else went wrong. |  | 
|  309       set_error_code(base::PLATFORM_FILE_ERROR_FAILED); |  320       set_error_code(base::PLATFORM_FILE_ERROR_FAILED); | 
|  310     } |  | 
|  311   } |  321   } | 
|  312  |  322  | 
|  313  private: |  323  private: | 
|  314   FilePath src_file_path_; |  324   FilePath src_file_path_; | 
|  315   FilePath dest_file_path_; |  325   FilePath dest_file_path_; | 
|  316 }; |  326 }; | 
|  317  |  327  | 
|  318 class RelayCreateDirectory : public RelayWithStatusCallback { |  328 class RelayCreateDirectory : public RelayWithStatusCallback { | 
|  319  public: |  329  public: | 
|  320   RelayCreateDirectory( |  330   RelayCreateDirectory( | 
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  663 bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy, |  673 bool FileUtilProxy::Close(scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
|  664                           base::PlatformFile file_handle, |  674                           base::PlatformFile file_handle, | 
|  665                           StatusCallback* callback) { |  675                           StatusCallback* callback) { | 
|  666   return Start(FROM_HERE, message_loop_proxy, |  676   return Start(FROM_HERE, message_loop_proxy, | 
|  667                new RelayClose(file_handle, callback)); |  677                new RelayClose(file_handle, callback)); | 
|  668 } |  678 } | 
|  669  |  679  | 
|  670 // static |  680 // static | 
|  671 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, |  681 bool FileUtilProxy::Delete(scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
|  672                            const FilePath& file_path, |  682                            const FilePath& file_path, | 
 |  683                            bool recursive, | 
|  673                            StatusCallback* callback) { |  684                            StatusCallback* callback) { | 
|  674   return Start(FROM_HERE, message_loop_proxy, |  685   return Start(FROM_HERE, message_loop_proxy, | 
|  675                new RelayDelete(file_path, false, callback)); |  686                new RelayDelete(file_path, recursive, callback)); | 
|  676 } |  687 } | 
|  677  |  688  | 
|  678 // static |  689 // static | 
|  679 bool FileUtilProxy::Copy(scoped_refptr<MessageLoopProxy> message_loop_proxy, |  690 bool FileUtilProxy::Copy(scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
|  680                          const FilePath& src_file_path, |  691                          const FilePath& src_file_path, | 
|  681                          const FilePath& dest_file_path, |  692                          const FilePath& dest_file_path, | 
|  682                          StatusCallback* callback) { |  693                          StatusCallback* callback) { | 
|  683   return Start(FROM_HERE, message_loop_proxy, |  694   return Start(FROM_HERE, message_loop_proxy, | 
|  684                new RelayCopy(src_file_path, dest_file_path, callback)); |  695                new RelayCopy(src_file_path, dest_file_path, callback)); | 
|  685 } |  696 } | 
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  790  |  801  | 
|  791 // static |  802 // static | 
|  792 bool FileUtilProxy::Flush( |  803 bool FileUtilProxy::Flush( | 
|  793     scoped_refptr<MessageLoopProxy> message_loop_proxy, |  804     scoped_refptr<MessageLoopProxy> message_loop_proxy, | 
|  794     PlatformFile file, |  805     PlatformFile file, | 
|  795     StatusCallback* callback) { |  806     StatusCallback* callback) { | 
|  796   return Start(FROM_HERE, message_loop_proxy, new RelayFlush(file, callback)); |  807   return Start(FROM_HERE, message_loop_proxy, new RelayFlush(file, callback)); | 
|  797 } |  808 } | 
|  798  |  809  | 
|  799 }  // namespace base |  810 }  // namespace base | 
| OLD | NEW |