1 // Copyright 2014 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_FILES_FILE_PROXY_H_ 6 #define BASE_FILES_FILE_PROXY_H_ 7 8 #include <stdint.h> 9 10 #include "base/base_export.h" 11 #include "base/containers/span.h" 12 #include "base/files/file.h" 13 #include "base/files/file_path.h" 14 #include "base/functional/callback_forward.h" 15 #include "base/memory/weak_ptr.h" 16 17 namespace base { 18 19 class TaskRunner; 20 class Time; 21 22 // This class provides asynchronous access to a File. All methods follow the 23 // same rules of the equivalent File method, as they are implemented by bouncing 24 // the operation to File using a TaskRunner. 25 // 26 // This class performs automatic proxying to close the underlying file at 27 // destruction. 28 // 29 // The TaskRunner is in charge of any sequencing of the operations, but a single 30 // operation can be proxied at a time, regardless of the use of a callback. 31 // In other words, having a sequence like 32 // 33 // proxy.Write(...); 34 // proxy.Write(...); 35 // 36 // means the second Write will always fail. 37 class BASE_EXPORT FileProxy final { 38 public: 39 // This callback is used by methods that report only an error code. It is 40 // valid to pass a null callback to some functions that takes a 41 // StatusCallback, in which case the operation will complete silently. 42 using StatusCallback = OnceCallback<void(File::Error)>; 43 using CreateTemporaryCallback = 44 OnceCallback<void(File::Error, const FilePath&)>; 45 using GetFileInfoCallback = 46 OnceCallback<void(File::Error, const File::Info&)>; 47 using ReadCallback = 48 OnceCallback<void(File::Error, base::span<const char> data)>; 49 using WriteCallback = OnceCallback<void(File::Error, int bytes_written)>; 50 51 explicit FileProxy(TaskRunner* task_runner); 52 FileProxy(const FileProxy&) = delete; 53 FileProxy& operator=(const FileProxy&) = delete; 54 ~FileProxy(); 55 56 // Creates or opens a file with the given flags. It is invalid to pass a null 57 // callback. If File::FLAG_CREATE is set in |file_flags| it always tries to 58 // create a new file at the given |file_path| and fails if the file already 59 // exists. 60 // 61 // This returns false if task posting to |task_runner| has failed. 62 bool CreateOrOpen(const FilePath& file_path, 63 uint32_t file_flags, 64 StatusCallback callback); 65 66 // Creates a temporary file for writing. The path and an open file are 67 // returned. It is invalid to pass a null callback. These additional file 68 // flags will be added on top of the default file flags: 69 // File::FLAG_CREATE_ALWAYS 70 // File::FLAG_WRITE 71 // File::FLAG_WIN_TEMPORARY. 72 // 73 // This returns false if task posting to |task_runner| has failed. 74 bool CreateTemporary(uint32_t additional_file_flags, 75 CreateTemporaryCallback callback); 76 77 // Returns true if the underlying |file_| is valid. 78 bool IsValid() const; 79 80 // Returns true if a new file was created (or an old one truncated to zero 81 // length to simulate a new file), and false otherwise. created()82 bool created() const { return file_.created(); } 83 84 // Claims ownership of |file|. It is an error to call this method when 85 // IsValid() returns true. 86 void SetFile(File file); 87 88 File TakeFile(); 89 90 // Returns a new File object that is a duplicate of the underlying |file_|. 91 // See the comment at File::Duplicate for caveats. 92 File DuplicateFile(); 93 94 PlatformFile GetPlatformFile() const; 95 96 // Proxies File::Close. The callback can be null. 97 // This returns false if task posting to |task_runner| has failed. 98 bool Close(StatusCallback callback); 99 100 // Proxies File::GetInfo. The callback can't be null. 101 // This returns false if task posting to |task_runner| has failed. 102 bool GetInfo(GetFileInfoCallback callback); 103 104 // Proxies File::Read. The callback can't be null. 105 // This returns false if |bytes_to_read| is less than zero, or 106 // if task posting to |task_runner| has failed. 107 bool Read(int64_t offset, int bytes_to_read, ReadCallback callback); 108 109 // Proxies File::Write. The callback can be null. 110 // This returns false if |bytes_to_write| is less than or equal to zero, 111 // if |buffer| is NULL, or if task posting to |task_runner| has failed. 112 bool Write(int64_t offset, 113 base::span<const uint8_t> data, 114 WriteCallback callback); 115 116 // Proxies File::SetTimes. The callback can be null. 117 // This returns false if task posting to |task_runner| has failed. 118 bool SetTimes(Time last_access_time, 119 Time last_modified_time, 120 StatusCallback callback); 121 122 // Proxies File::SetLength. The callback can be null. 123 // This returns false if task posting to |task_runner| has failed. 124 bool SetLength(int64_t length, StatusCallback callback); 125 126 // Proxies File::Flush. The callback can be null. 127 // This returns false if task posting to |task_runner| has failed. 128 bool Flush(StatusCallback callback); 129 130 private: 131 friend class FileHelper; task_runner()132 TaskRunner* task_runner() { return task_runner_.get(); } 133 134 scoped_refptr<TaskRunner> task_runner_; 135 File file_; 136 137 base::WeakPtrFactory<FileProxy> weak_ptr_factory_{this}; 138 }; 139 140 } // namespace base 141 142 #endif // BASE_FILES_FILE_PROXY_H_ 143