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 true if Open succeeded and Close has not been called. 85 virtual bool IsOpen() const; 86 87 // Adjust the position from where data is read asynchronously. 88 // Upon success, ERR_IO_PENDING is returned and |callback| will be run 89 // on the thread where Seek() was called with the the stream position 90 // relative to the start of the file. Otherwise, an error code is returned. 91 // It is invalid to request any asynchronous operations while there is an 92 // in-flight asynchronous operation. 93 virtual int Seek(Whence whence, int64 offset, 94 const Int64CompletionCallback& callback); 95 96 // Adjust the position from where data is read synchronously. 97 // Upon success, the stream position relative to the start of the file is 98 // returned. Otherwise, an error code is returned. It is not valid to 99 // call SeekSync while a Read call has a pending completion. 100 virtual int64 SeekSync(Whence whence, int64 offset); 101 102 // Returns the number of bytes available to read from the current stream 103 // position until the end of the file. Otherwise, an error code is returned. 104 virtual int64 Available(); 105 106 // Call this method to read data from the current stream position 107 // asynchronously. Up to buf_len bytes will be copied into buf. (In 108 // other words, partial reads are allowed.) Returns the number of bytes 109 // copied, 0 if at end-of-file, or an error code if the operation could 110 // not be performed. 111 // 112 // The file must be opened with PLATFORM_FILE_ASYNC, and a non-null 113 // callback must be passed to this method. If the read could not 114 // complete synchronously, then ERR_IO_PENDING is returned, and the 115 // callback will be run on the thread where Read() was called, when the 116 // read has completed. 117 // 118 // It is valid to destroy or close the file stream while there is an 119 // asynchronous read in progress. That will cancel the read 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 WRITE_ONLY. 126 virtual int Read(IOBuffer* buf, int buf_len, 127 const CompletionCallback& callback); 128 129 // Call this method to read data from the current stream position 130 // synchronously. Up to buf_len bytes will be copied into buf. (In 131 // other words, partial reads are allowed.) Returns the number of bytes 132 // copied, 0 if at end-of-file, or an error code if the operation could 133 // not be performed. 134 // 135 // The file must not be opened with PLATFORM_FILE_ASYNC. 136 // This method must not be called if the stream was opened WRITE_ONLY. 137 virtual int ReadSync(char* buf, int buf_len); 138 139 // Performs the same as ReadSync, but ensures that exactly buf_len bytes 140 // are copied into buf. A partial read may occur, but only as a result of 141 // end-of-file or fatal error. Returns the number of bytes copied into buf, 142 // 0 if at end-of-file and no bytes have been read into buf yet, 143 // or an error code if the operation could not be performed. 144 virtual int ReadUntilComplete(char *buf, int buf_len); 145 146 // Call this method to write data at the current stream position 147 // asynchronously. Up to buf_len bytes will be written from buf. (In 148 // other words, partial writes are allowed.) Returns the number of 149 // bytes written, or an error code if the operation could not be 150 // performed. 151 // 152 // The file must be opened with PLATFORM_FILE_ASYNC, and a non-null 153 // callback must be passed to this method. If the write could not 154 // complete synchronously, then ERR_IO_PENDING is returned, and the 155 // callback will be run on the thread where Write() was called when 156 // the write has completed. 157 // 158 // It is valid to destroy or close the file stream while there is an 159 // asynchronous write in progress. That will cancel the write and allow 160 // the buffer to be freed. 161 // 162 // It is invalid to request any asynchronous operations while there is an 163 // in-flight asynchronous operation. 164 // 165 // This method must not be called if the stream was opened READ_ONLY. 166 // 167 // Zero byte writes are not allowed. 168 virtual int Write(IOBuffer* buf, int buf_len, 169 const CompletionCallback& callback); 170 171 // Call this method to write data at the current stream position 172 // synchronously. Up to buf_len bytes will be written from buf. (In 173 // other words, partial writes are allowed.) Returns the number of 174 // bytes written, or an error code if the operation could not be 175 // performed. 176 // 177 // The file must not be opened with PLATFORM_FILE_ASYNC. 178 // This method must not be called if the stream was opened READ_ONLY. 179 // 180 // Zero byte writes are not allowed. 181 virtual int WriteSync(const char* buf, int buf_len); 182 183 // Truncates the file to be |bytes| length. This is only valid for writable 184 // files. After truncation the file stream is positioned at |bytes|. The new 185 // position is returned, or a value < 0 on error. 186 // WARNING: one may not truncate a file beyond its current length on any 187 // platform with this call. 188 virtual int64 Truncate(int64 bytes); 189 190 // Forces out a filesystem sync on this file to make sure that the file was 191 // written out to disk and is not currently sitting in the buffer. This does 192 // not have to be called, it just forces one to happen at the time of 193 // calling. 194 // 195 // The file must be opened with PLATFORM_FILE_ASYNC, and a non-null 196 // callback must be passed to this method. If the write could not 197 // complete synchronously, then ERR_IO_PENDING is returned, and the 198 // callback will be run on the thread where Flush() was called when 199 // the write has completed. 200 // 201 // It is valid to destroy or close the file stream while there is an 202 // asynchronous flush in progress. That will cancel the flush and allow 203 // the buffer to be freed. 204 // 205 // It is invalid to request any asynchronous operations while there is an 206 // in-flight asynchronous operation. 207 // 208 // This method should not be called if the stream was opened READ_ONLY. 209 virtual int Flush(const CompletionCallback& callback); 210 211 // Forces out a filesystem sync on this file to make sure that the file was 212 // written out to disk and is not currently sitting in the buffer. This does 213 // not have to be called, it just forces one to happen at the time of 214 // calling. 215 // 216 // Returns an error code if the operation could not be performed. 217 // 218 // This method should not be called if the stream was opened READ_ONLY. 219 virtual int FlushSync(); 220 221 // Turns on UMA error statistics gathering. 222 void EnableErrorStatistics(); 223 224 // Sets the source reference for net-internals logging. 225 // Creates source dependency events between |owner_bound_net_log| and 226 // |bound_net_log_|. Each gets an event showing the dependency on the other. 227 // If only one of those is valid, it gets an event showing that a change 228 // of ownership happened, but without details. 229 void SetBoundNetLogSource(const net::BoundNetLog& owner_bound_net_log); 230 231 // Returns the underlying platform file for testing. 232 base::PlatformFile GetPlatformFileForTesting(); 233 234 private: 235 class Context; 236 237 bool is_async() const { return !!(open_flags_ & base::PLATFORM_FILE_ASYNC); } 238 239 int open_flags_; 240 net::BoundNetLog bound_net_log_; 241 242 // Context performing I/O operations. It was extracted into separate class 243 // to perform asynchronous operations because FileStream can be destroyed 244 // before completion of async operation. Also if async FileStream is destroyed 245 // without explicit closing file should be closed asynchronously without 246 // delaying FileStream's destructor. To perform all that separate object is 247 // necessary. 248 scoped_ptr<Context> context_; 249 250 DISALLOW_COPY_AND_ASSIGN(FileStream); 251 }; 252 253 } // namespace net 254 255 #endif // NET_BASE_FILE_STREAM_H_ 256