1 // Copyright 2012 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 // This file defines FileStream, a basic interface for reading and writing files 6 // synchronously or asynchronously with support for seeking to an offset. 7 // Note that even when used asynchronously, only one operation is supported at 8 // a time. 9 10 #ifndef NET_BASE_FILE_STREAM_H_ 11 #define NET_BASE_FILE_STREAM_H_ 12 13 #include <stdint.h> 14 15 #include <memory> 16 17 #include "base/files/file.h" 18 #include "build/build_config.h" 19 #include "net/base/completion_once_callback.h" 20 #include "net/base/net_export.h" 21 22 namespace base { 23 class FilePath; 24 class TaskRunner; 25 } 26 27 namespace net { 28 29 class IOBuffer; 30 31 class NET_EXPORT FileStream { 32 public: 33 // Uses |task_runner| for asynchronous operations. 34 explicit FileStream(const scoped_refptr<base::TaskRunner>& task_runner); 35 36 // Construct a FileStream with an already opened file. |file| must be opened 37 // for async reading on Windows, and sync reading everywehere else. To use 38 // ConnectNamedPipe(), `file` must wrap a handle from CreateNamedPipe() with 39 // `FILE_FLAG_OVERLAPPED`. 40 // 41 // Uses |task_runner| for asynchronous operations. 42 FileStream(base::File file, 43 const scoped_refptr<base::TaskRunner>& task_runner); 44 45 FileStream(const FileStream&) = delete; 46 FileStream& operator=(const FileStream&) = delete; 47 // The underlying file is closed automatically. 48 virtual ~FileStream(); 49 50 // Call this method to open the FileStream asynchronously. The remaining 51 // methods cannot be used unless the file is opened successfully. Returns 52 // ERR_IO_PENDING if the operation is started. If the operation cannot be 53 // started then an error code is returned. 54 // 55 // Once the operation is done, |callback| will be run on the thread where 56 // Open() was called, with the result code. open_flags is a bitfield of 57 // base::File::Flags. 58 // 59 // If the file stream is not closed manually, the underlying file will be 60 // automatically closed when FileStream is destructed in an asynchronous 61 // manner (i.e. the file stream is closed in the background but you don't 62 // know when). 63 virtual int Open(const base::FilePath& path, 64 int open_flags, 65 CompletionOnceCallback callback); 66 67 // Returns ERR_IO_PENDING and closes the file asynchronously, calling 68 // |callback| when done. 69 // It is invalid to request any asynchronous operations while there is an 70 // in-flight asynchronous operation. 71 virtual int Close(CompletionOnceCallback callback); 72 73 // Returns true if Open succeeded and Close has not been called. 74 virtual bool IsOpen() const; 75 76 // Adjust the position from the start of the file where data is read 77 // asynchronously. Upon success, ERR_IO_PENDING is returned and |callback| 78 // will be run on the thread where Seek() was called with the the stream 79 // position relative to the start of the file. Otherwise, an error code is 80 // returned. It is invalid to request any asynchronous operations while there 81 // is an in-flight asynchronous operation. 82 virtual int Seek(int64_t offset, Int64CompletionOnceCallback callback); 83 84 // Call this method to read data from the current stream position 85 // asynchronously. Up to buf_len bytes will be copied into buf. (In 86 // other words, partial reads are allowed.) Returns the number of bytes 87 // copied, 0 if at end-of-file, or an error code if the operation could 88 // not be performed. 89 // 90 // The file must be opened with FLAG_ASYNC, and a non-null 91 // callback must be passed to this method. If the read could not 92 // complete synchronously, then ERR_IO_PENDING is returned, and the 93 // callback will be run on the thread where Read() was called, when the 94 // read has completed. 95 // 96 // It is valid to destroy or close the file stream while there is an 97 // asynchronous read in progress. That will cancel the read and allow 98 // the buffer to be freed. 99 // 100 // It is invalid to request any asynchronous operations while there is an 101 // in-flight asynchronous operation. 102 // 103 // This method must not be called if the stream was opened WRITE_ONLY. 104 virtual int Read(IOBuffer* buf, int buf_len, CompletionOnceCallback callback); 105 106 // Call this method to write data at the current stream position 107 // asynchronously. Up to buf_len bytes will be written from buf. (In 108 // other words, partial writes are allowed.) Returns the number of 109 // bytes written, or an error code if the operation could not be 110 // performed. 111 // 112 // The file must be opened with FLAG_ASYNC, and a non-null 113 // callback must be passed to this method. If the write could not 114 // complete synchronously, then ERR_IO_PENDING is returned, and the 115 // callback will be run on the thread where Write() was called when 116 // the write has completed. 117 // 118 // It is valid to destroy or close the file stream while there is an 119 // asynchronous write in progress. That will cancel the write and allow 120 // the buffer to be freed. 121 // 122 // It is invalid to request any asynchronous operations while there is an 123 // in-flight asynchronous operation. 124 // 125 // This method must not be called if the stream was opened READ_ONLY. 126 // 127 // Zero byte writes are not allowed. 128 virtual int Write(IOBuffer* buf, 129 int buf_len, 130 CompletionOnceCallback callback); 131 132 // Gets status information about File. May fail synchronously, but never 133 // succeeds synchronously. 134 // 135 // It is invalid to request any asynchronous operations while there is an 136 // in-flight asynchronous operation. 137 // 138 // |file_info| must remain valid until |callback| is invoked. 139 virtual int GetFileInfo(base::File::Info* file_info, 140 CompletionOnceCallback callback); 141 142 // Forces out a filesystem sync on this file to make sure that the file was 143 // written out to disk and is not currently sitting in the buffer. This does 144 // not have to be called, it just forces one to happen at the time of 145 // calling. 146 // 147 // The file must be opened with FLAG_ASYNC, and a non-null 148 // callback must be passed to this method. If the write could not 149 // complete synchronously, then ERR_IO_PENDING is returned, and the 150 // callback will be run on the thread where Flush() was called when 151 // the write has completed. 152 // 153 // It is valid to destroy or close the file stream while there is an 154 // asynchronous flush in progress. That will cancel the flush and allow 155 // the buffer to be freed. 156 // 157 // It is invalid to request any asynchronous operations while there is an 158 // in-flight asynchronous operation. 159 // 160 // This method should not be called if the stream was opened READ_ONLY. 161 virtual int Flush(CompletionOnceCallback callback); 162 163 #if BUILDFLAG(IS_WIN) 164 // Waits for a client to connect to the named pipe provided to the two-arg 165 // constructor. Returns `OK` if the client has already connected, 166 // `ERR_IO_PENDING` if `callback` will be run later with the result of the 167 // operation once the client connects, or another `Error` value in case of 168 // failure. 169 int ConnectNamedPipe(CompletionOnceCallback callback); 170 #endif // BUILDFLAG(IS_WIN) 171 172 private: 173 class Context; 174 175 // Context performing I/O operations. It was extracted into a separate class 176 // to perform asynchronous operations because FileStream can be destroyed 177 // before completion of an async operation. Also if a FileStream is destroyed 178 // without explicitly calling Close, the file should be closed asynchronously 179 // without delaying FileStream's destructor. 180 std::unique_ptr<Context> context_; 181 }; 182 183 } // namespace net 184 185 #endif // NET_BASE_FILE_STREAM_H_ 186