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