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