1 // Copyright (c) 2012 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 // 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 "base/platform_file.h" 14 #include "base/task_runner.h" 15 #include "net/base/completion_callback.h" 16 #include "net/base/file_stream_whence.h" 17 #include "net/base/net_export.h" 18 #include "net/base/net_log.h" 19 20 namespace base { 21 class FilePath; 22 } 23 24 namespace net { 25 26 class IOBuffer; 27 28 class NET_EXPORT FileStream { 29 public: 30 // Creates a |FileStream| with a new |BoundNetLog| (based on |net_log|) 31 // attached. |net_log| may be NULL if no logging is needed. 32 // Uses |task_runner| for asynchronous operations. 33 FileStream(net::NetLog* net_log, 34 const scoped_refptr<base::TaskRunner>& task_runner); 35 36 // Same as above, but runs async tasks in base::WorkerPool. 37 explicit FileStream(net::NetLog* net_log); 38 39 // Construct a FileStream with an existing file handle and opening flags. 40 // |file| is valid file handle. 41 // |flags| is a bitfield of base::PlatformFileFlags when the file handle was 42 // opened. 43 // |net_log| is the net log pointer to use to create a |BoundNetLog|. May be 44 // NULL if logging is not needed. 45 // Uses |task_runner| for asynchronous operations. 46 // Note: the new FileStream object takes ownership of the PlatformFile and 47 // will close it on destruction. 48 FileStream(base::PlatformFile file, 49 int flags, 50 net::NetLog* net_log, 51 const scoped_refptr<base::TaskRunner>& task_runner); 52 53 // Same as above, but runs async tasks in base::WorkerPool. 54 FileStream(base::PlatformFile file, int flags, net::NetLog* net_log); 55 56 // The underlying file is closed automatically. 57 virtual ~FileStream(); 58 59 // Call this method to open the FileStream asynchronously. The remaining 60 // methods cannot be used unless the file is opened successfully. Returns 61 // ERR_IO_PENDING if the operation is started. If the operation cannot be 62 // started then an error code is returned. 63 // 64 // Once the operation is done, |callback| will be run on the thread where 65 // Open() was called, with the result code. open_flags is a bitfield of 66 // base::PlatformFileFlags. 67 // 68 // If the file stream is not closed manually, the underlying file will be 69 // automatically closed when FileStream is destructed in an asynchronous 70 // manner (i.e. the file stream is closed in the background but you don't 71 // know when). 72 virtual int Open(const base::FilePath& path, int open_flags, 73 const CompletionCallback& callback); 74 75 // Call this method to open the FileStream synchronously. 76 // The remaining methods cannot be used unless this method returns OK. If 77 // the file cannot be opened then an error code is returned. open_flags is 78 // a bitfield of base::PlatformFileFlags 79 // 80 // If the file stream is not closed manually, the underlying file will be 81 // automatically closed when FileStream is destructed. 82 virtual int OpenSync(const base::FilePath& path, int open_flags); 83 84 // Returns ERR_IO_PENDING and closes the file asynchronously, calling 85 // |callback| when done. 86 // It is invalid to request any asynchronous operations while there is an 87 // in-flight asynchronous operation. 88 virtual int Close(const CompletionCallback& callback); 89 90 // Closes the file immediately and returns OK. If the file is open 91 // asynchronously, Close(const CompletionCallback&) should be used instead. 92 virtual int CloseSync(); 93 94 // Returns true if Open succeeded and Close has not been called. 95 virtual bool IsOpen() const; 96 97 // Adjust the position from where data is read asynchronously. 98 // Upon success, ERR_IO_PENDING is returned and |callback| will be run 99 // on the thread where Seek() was called with the the stream position 100 // relative to the start of the file. Otherwise, an error code is returned. 101 // It is invalid to request any asynchronous operations while there is an 102 // in-flight asynchronous operation. 103 virtual int Seek(Whence whence, int64 offset, 104 const Int64CompletionCallback& callback); 105 106 // Adjust the position from where data is read synchronously. 107 // Upon success, the stream position relative to the start of the file is 108 // returned. Otherwise, an error code is returned. It is not valid to 109 // call SeekSync while a Read call has a pending completion. 110 virtual int64 SeekSync(Whence whence, int64 offset); 111 112 // Returns the number of bytes available to read from the current stream 113 // position until the end of the file. Otherwise, an error code is returned. 114 virtual int64 Available(); 115 116 // Call this method to read data from the current stream position 117 // asynchronously. Up to buf_len bytes will be copied into buf. (In 118 // other words, partial reads are allowed.) Returns the number of bytes 119 // copied, 0 if at end-of-file, or an error code if the operation could 120 // not be performed. 121 // 122 // The file must be opened with PLATFORM_FILE_ASYNC, and a non-null 123 // callback must be passed to this method. If the read could not 124 // complete synchronously, then ERR_IO_PENDING is returned, and the 125 // callback will be run on the thread where Read() was called, when the 126 // read has completed. 127 // 128 // It is valid to destroy or close the file stream while there is an 129 // asynchronous read in progress. That will cancel the read and allow 130 // the buffer to be freed. 131 // 132 // It is invalid to request any asynchronous operations while there is an 133 // in-flight asynchronous operation. 134 // 135 // This method must not be called if the stream was opened WRITE_ONLY. 136 virtual int Read(IOBuffer* buf, int buf_len, 137 const CompletionCallback& callback); 138 139 // Call this method to read data from the current stream position 140 // synchronously. Up to buf_len bytes will be copied into buf. (In 141 // other words, partial reads are allowed.) Returns the number of bytes 142 // copied, 0 if at end-of-file, or an error code if the operation could 143 // not be performed. 144 // 145 // The file must not be opened with PLATFORM_FILE_ASYNC. 146 // This method must not be called if the stream was opened WRITE_ONLY. 147 virtual int ReadSync(char* buf, int buf_len); 148 149 // Performs the same as ReadSync, but ensures that exactly buf_len bytes 150 // are copied into buf. A partial read may occur, but only as a result of 151 // end-of-file or fatal error. Returns the number of bytes copied into buf, 152 // 0 if at end-of-file and no bytes have been read into buf yet, 153 // or an error code if the operation could not be performed. 154 virtual int ReadUntilComplete(char *buf, int buf_len); 155 156 // Call this method to write data at the current stream position 157 // asynchronously. Up to buf_len bytes will be written from buf. (In 158 // other words, partial writes are allowed.) Returns the number of 159 // bytes written, or an error code if the operation could not be 160 // performed. 161 // 162 // The file must be opened with PLATFORM_FILE_ASYNC, and a non-null 163 // callback must be passed to this method. If the write could not 164 // complete synchronously, then ERR_IO_PENDING is returned, and the 165 // callback will be run on the thread where Write() was called when 166 // the write has completed. 167 // 168 // It is valid to destroy or close the file stream while there is an 169 // asynchronous write in progress. That will cancel the write and allow 170 // the buffer to be freed. 171 // 172 // It is invalid to request any asynchronous operations while there is an 173 // in-flight asynchronous operation. 174 // 175 // This method must not be called if the stream was opened READ_ONLY. 176 // 177 // Zero byte writes are not allowed. 178 virtual int Write(IOBuffer* buf, int buf_len, 179 const CompletionCallback& callback); 180 181 // Call this method to write data at the current stream position 182 // synchronously. Up to buf_len bytes will be written from buf. (In 183 // other words, partial writes are allowed.) Returns the number of 184 // bytes written, or an error code if the operation could not be 185 // performed. 186 // 187 // The file must not be opened with PLATFORM_FILE_ASYNC. 188 // This method must not be called if the stream was opened READ_ONLY. 189 // 190 // Zero byte writes are not allowed. 191 virtual int WriteSync(const char* buf, int buf_len); 192 193 // Truncates the file to be |bytes| length. This is only valid for writable 194 // files. After truncation the file stream is positioned at |bytes|. The new 195 // position is returned, or a value < 0 on error. 196 // WARNING: one may not truncate a file beyond its current length on any 197 // platform with this call. 198 virtual int64 Truncate(int64 bytes); 199 200 // Forces out a filesystem sync on this file to make sure that the file was 201 // written out to disk and is not currently sitting in the buffer. This does 202 // not have to be called, it just forces one to happen at the time of 203 // calling. 204 // 205 // The file must be opened with PLATFORM_FILE_ASYNC, and a non-null 206 // callback must be passed to this method. If the write could not 207 // complete synchronously, then ERR_IO_PENDING is returned, and the 208 // callback will be run on the thread where Flush() was called when 209 // the write has completed. 210 // 211 // It is valid to destroy or close the file stream while there is an 212 // asynchronous flush in progress. That will cancel the flush and allow 213 // the buffer to be freed. 214 // 215 // It is invalid to request any asynchronous operations while there is an 216 // in-flight asynchronous operation. 217 // 218 // This method should not be called if the stream was opened READ_ONLY. 219 virtual int Flush(const CompletionCallback& callback); 220 221 // Forces out a filesystem sync on this file to make sure that the file was 222 // written out to disk and is not currently sitting in the buffer. This does 223 // not have to be called, it just forces one to happen at the time of 224 // calling. 225 // 226 // Returns an error code if the operation could not be performed. 227 // 228 // This method should not be called if the stream was opened READ_ONLY. 229 virtual int FlushSync(); 230 231 // Turns on UMA error statistics gathering. 232 void EnableErrorStatistics(); 233 234 // Sets the source reference for net-internals logging. 235 // Creates source dependency events between |owner_bound_net_log| and 236 // |bound_net_log_|. Each gets an event showing the dependency on the other. 237 // If only one of those is valid, it gets an event showing that a change 238 // of ownership happened, but without details. 239 void SetBoundNetLogSource(const net::BoundNetLog& owner_bound_net_log); 240 241 // Returns the underlying platform file for testing. 242 base::PlatformFile GetPlatformFileForTesting(); 243 244 private: 245 class Context; 246 247 bool is_async() const { return !!(open_flags_ & base::PLATFORM_FILE_ASYNC); } 248 249 int open_flags_; 250 net::BoundNetLog bound_net_log_; 251 252 // Context performing I/O operations. It was extracted into separate class 253 // to perform asynchronous operations because FileStream can be destroyed 254 // before completion of async operation. Also if async FileStream is destroyed 255 // without explicit closing file should be closed asynchronously without 256 // delaying FileStream's destructor. To perform all that separate object is 257 // necessary. 258 scoped_ptr<Context> context_; 259 260 DISALLOW_COPY_AND_ASSIGN(FileStream); 261 }; 262 263 } // namespace net 264 265 #endif // NET_BASE_FILE_STREAM_H_ 266