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
20namespace base {
21class FilePath;
22}
23
24namespace net {
25
26class IOBuffer;
27
28class 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