xref: /aosp_15_r20/external/libbrillo/brillo/streams/stream.h (revision 1a96fba65179ea7d3f56207137718607415c5953)
1*1a96fba6SXin Li // Copyright 2015 The Chromium OS Authors. All rights reserved.
2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be
3*1a96fba6SXin Li // found in the LICENSE file.
4*1a96fba6SXin Li 
5*1a96fba6SXin Li #ifndef LIBBRILLO_BRILLO_STREAMS_STREAM_H_
6*1a96fba6SXin Li #define LIBBRILLO_BRILLO_STREAMS_STREAM_H_
7*1a96fba6SXin Li 
8*1a96fba6SXin Li #include <cstdint>
9*1a96fba6SXin Li #include <memory>
10*1a96fba6SXin Li 
11*1a96fba6SXin Li #include <base/callback.h>
12*1a96fba6SXin Li #include <base/macros.h>
13*1a96fba6SXin Li #include <base/memory/weak_ptr.h>
14*1a96fba6SXin Li #include <base/time/time.h>
15*1a96fba6SXin Li #include <brillo/brillo_export.h>
16*1a96fba6SXin Li #include <brillo/errors/error.h>
17*1a96fba6SXin Li 
18*1a96fba6SXin Li namespace brillo {
19*1a96fba6SXin Li 
20*1a96fba6SXin Li // Stream is a base class that specific stream storage implementations must
21*1a96fba6SXin Li // derive from to provide I/O facilities.
22*1a96fba6SXin Li // The stream class provides general streaming I/O primitives to read, write and
23*1a96fba6SXin Li // seek within a stream. It has methods for asynchronous (callback-based) as
24*1a96fba6SXin Li // well as synchronous (both blocking and non-blocking) operations.
25*1a96fba6SXin Li // The Stream class is abstract and cannot be created by itself.
26*1a96fba6SXin Li // In order to construct a stream, you must use one of the derived classes'
27*1a96fba6SXin Li // factory methods which return a stream smart pointer (StreamPtr):
28*1a96fba6SXin Li //
29*1a96fba6SXin Li //    StreamPtr input_stream = FileStream::Open(path, AccessMode::READ);
30*1a96fba6SXin Li //    StreamPtr output_stream = MemoryStream::Create();
31*1a96fba6SXin Li //    uint8_t buf[1000];
32*1a96fba6SXin Li //    size_t read = 0;
33*1a96fba6SXin Li //    while (input_stream->ReadBlocking(buf, sizeof(buf), &read, nullptr)) {
34*1a96fba6SXin Li //      if (read == 0) break;
35*1a96fba6SXin Li //      output_stream->WriteAllBlocking(buf, read, nullptr);
36*1a96fba6SXin Li //    }
37*1a96fba6SXin Li //
38*1a96fba6SXin Li // NOTE ABOUT ASYNCHRONOUS OPERATIONS: Asynchronous I/O relies on a MessageLoop
39*1a96fba6SXin Li // instance to be present on the current thread. Using Stream::ReadAsync(),
40*1a96fba6SXin Li // Stream::WriteAsync() and similar will call MessageLoop::current() to access
41*1a96fba6SXin Li // the current message loop and abort if there isn't one for the current thread.
42*1a96fba6SXin Li // Also, only one outstanding asynchronous operation of particular kind (reading
43*1a96fba6SXin Li // or writing) at a time is supported. Trying to call ReadAsync() while another
44*1a96fba6SXin Li // asynchronous read operation is pending will fail with an error
45*1a96fba6SXin Li // ("operation_not_supported").
46*1a96fba6SXin Li //
47*1a96fba6SXin Li // NOTE ABOUT READING FROM/WRITING TO STREAMS: In many cases underlying streams
48*1a96fba6SXin Li // use buffered I/O. Using all read/write methods other than ReadAllAsync(),
49*1a96fba6SXin Li // ReadAllBlocking(), WriteAllAsync(), WriteAllBlocking() will return
50*1a96fba6SXin Li // immediately if there is any data available in the underlying buffer. That is,
51*1a96fba6SXin Li // trying to read 1000 bytes while the internal buffer contains only 100 will
52*1a96fba6SXin Li // return immediately with just those 100 bytes and no blocking or other I/O
53*1a96fba6SXin Li // traffic will be incurred. This guarantee is important for efficient and
54*1a96fba6SXin Li // correct implementation of duplex communication over pipes and sockets.
55*1a96fba6SXin Li //
56*1a96fba6SXin Li // NOTE TO IMPLEMENTERS: When creating new stream types, you must derive
57*1a96fba6SXin Li // from this class and provide the implementation for its pure virtual methods.
58*1a96fba6SXin Li // For operations that do not apply to your stream, make sure the corresponding
59*1a96fba6SXin Li // methods return "false" and set the error to "operation_not_supported".
60*1a96fba6SXin Li // You should use stream_utils::ErrorOperationNotSupported() for this. Also
61*1a96fba6SXin Li // Make sure the stream capabilities functions like CanRead(), etc return
62*1a96fba6SXin Li // correct values:
63*1a96fba6SXin Li //
64*1a96fba6SXin Li //    bool MyReadOnlyStream::CanRead() const { return true; }
65*1a96fba6SXin Li //    bool MyReadOnlyStream::CanWrite() const { return false; }
66*1a96fba6SXin Li //    bool MyReadOnlyStream::WriteBlocking(const void* buffer,
67*1a96fba6SXin Li //                                         size_t size_to_write,
68*1a96fba6SXin Li //                                         size_t* size_written,
69*1a96fba6SXin Li //                                         ErrorPtr* error) {
70*1a96fba6SXin Li //      return stream_utils::ErrorOperationNotSupported(error);
71*1a96fba6SXin Li //    }
72*1a96fba6SXin Li //
73*1a96fba6SXin Li // The class should also provide a static factory methods to create/open
74*1a96fba6SXin Li // a new stream:
75*1a96fba6SXin Li //
76*1a96fba6SXin Li //    static StreamPtr MyReadOnlyStream::Open(..., ErrorPtr* error) {
77*1a96fba6SXin Li //      auto my_stream = std::make_unique<MyReadOnlyStream>(...);
78*1a96fba6SXin Li //      if (!my_stream->Initialize(..., error))
79*1a96fba6SXin Li //        my_stream.reset();
80*1a96fba6SXin Li //      }
81*1a96fba6SXin Li //      return my_stream;
82*1a96fba6SXin Li //    }
83*1a96fba6SXin Li //
84*1a96fba6SXin Li class BRILLO_EXPORT Stream {
85*1a96fba6SXin Li  public:
86*1a96fba6SXin Li   // When seeking in streams, whence specifies the origin of the seek operation.
87*1a96fba6SXin Li   enum class Whence { FROM_BEGIN, FROM_CURRENT, FROM_END };
88*1a96fba6SXin Li   // Stream access mode for open operations (used in derived classes).
89*1a96fba6SXin Li   enum class AccessMode { READ, WRITE, READ_WRITE };
90*1a96fba6SXin Li 
91*1a96fba6SXin Li   // Standard error callback for asynchronous operations.
92*1a96fba6SXin Li   using ErrorCallback = base::Callback<void(const Error*)>;
93*1a96fba6SXin Li 
94*1a96fba6SXin Li   virtual ~Stream() = default;
95*1a96fba6SXin Li 
96*1a96fba6SXin Li   // == Stream capabilities ===================================================
97*1a96fba6SXin Li 
98*1a96fba6SXin Li   // Returns true while stream is open. Closing the last reference to the stream
99*1a96fba6SXin Li   // will make this method return false.
100*1a96fba6SXin Li   virtual bool IsOpen() const = 0;
101*1a96fba6SXin Li 
102*1a96fba6SXin Li   // Called to determine if read operations are supported on the stream (stream
103*1a96fba6SXin Li   // is readable). This method does not check if there is actually any data to
104*1a96fba6SXin Li   // read, only the fact that the stream is open in read mode and can be read
105*1a96fba6SXin Li   // from in general.
106*1a96fba6SXin Li   // If CanRead() returns false, it is guaranteed that the stream can't be
107*1a96fba6SXin Li   // read from. However, if it returns true, there is no guarantee that the
108*1a96fba6SXin Li   // subsequent read operation will actually succeed (for example, the stream
109*1a96fba6SXin Li   // position could be at the end of the data stream, or the access mode of
110*1a96fba6SXin Li   // the stream is unknown beforehand).
111*1a96fba6SXin Li   virtual bool CanRead() const = 0;
112*1a96fba6SXin Li 
113*1a96fba6SXin Li   // Called to determine if write operations are supported on the stream (stream
114*1a96fba6SXin Li   // is writable).
115*1a96fba6SXin Li   // If CanWrite() returns false, it is guaranteed that the stream can't be
116*1a96fba6SXin Li   // written to. However, if it returns true, the subsequent write operation
117*1a96fba6SXin Li   // is not guaranteed to succeed (e.g. the output media could be out of free
118*1a96fba6SXin Li   // space or a transport error could occur).
119*1a96fba6SXin Li   virtual bool CanWrite() const = 0;
120*1a96fba6SXin Li 
121*1a96fba6SXin Li   // Called to determine if random access I/O operations are supported on
122*1a96fba6SXin Li   // the stream. Sequential streams should return false.
123*1a96fba6SXin Li   // If CanSeek() returns false, it is guaranteed that the stream can't use
124*1a96fba6SXin Li   // Seek(). However, if it returns true, it might be possible to seek, but this
125*1a96fba6SXin Li   // is not guaranteed since the actual underlying stream capabilities might
126*1a96fba6SXin Li   // not be known.
127*1a96fba6SXin Li   // Note that non-seekable streams might still maintain the current stream
128*1a96fba6SXin Li   // position and GetPosition method might still be used even if CanSeek()
129*1a96fba6SXin Li   // returns false. However SetPosition() will almost always fail in such
130*1a96fba6SXin Li   // a case.
131*1a96fba6SXin Li   virtual bool CanSeek() const = 0;
132*1a96fba6SXin Li 
133*1a96fba6SXin Li   // Called to determine if the size of the stream is known. Size of some
134*1a96fba6SXin Li   // sequential streams (e.g. based on pipes) is unknown beforehand, so this
135*1a96fba6SXin Li   // method can be used to check how reliable a call to GetSize() is.
136*1a96fba6SXin Li   virtual bool CanGetSize() const = 0;
137*1a96fba6SXin Li 
138*1a96fba6SXin Li   // == Stream size operations ================================================
139*1a96fba6SXin Li 
140*1a96fba6SXin Li   // Returns the size of stream data.
141*1a96fba6SXin Li   // If the stream size is unavailable/unknown, it returns 0.
142*1a96fba6SXin Li   virtual uint64_t GetSize() const = 0;
143*1a96fba6SXin Li 
144*1a96fba6SXin Li   // Resizes the stream storage to |size|. Stream must be writable and support
145*1a96fba6SXin Li   // this operation.
146*1a96fba6SXin Li   virtual bool SetSizeBlocking(uint64_t size, ErrorPtr* error) = 0;
147*1a96fba6SXin Li 
148*1a96fba6SXin Li   // Truncates the stream at the current stream pointer.
149*1a96fba6SXin Li   // Calls SetSizeBlocking(GetPosition(), ...).
150*1a96fba6SXin Li   bool TruncateBlocking(ErrorPtr* error);
151*1a96fba6SXin Li 
152*1a96fba6SXin Li   // Returns the amount of data remaining in the stream. If the size of the
153*1a96fba6SXin Li   // stream is unknown, or if the stream pointer is at or past the end of the
154*1a96fba6SXin Li   // stream, the function returns 0.
155*1a96fba6SXin Li   virtual uint64_t GetRemainingSize() const = 0;
156*1a96fba6SXin Li 
157*1a96fba6SXin Li   // == Seek operations =======================================================
158*1a96fba6SXin Li 
159*1a96fba6SXin Li   // Gets the position of the stream I/O pointer from the beginning of the
160*1a96fba6SXin Li   // stream. If the stream position is unavailable/unknown, it returns 0.
161*1a96fba6SXin Li   virtual uint64_t GetPosition() const = 0;
162*1a96fba6SXin Li 
163*1a96fba6SXin Li   // Moves the stream pointer to the specified position, relative to the
164*1a96fba6SXin Li   // beginning of the stream. This calls Seek(position, Whence::FROM_BEGIN),
165*1a96fba6SXin Li   // however it also provides proper |position| validation to ensure that
166*1a96fba6SXin Li   // it doesn't overflow the range of signed int64_t used by Seek.
167*1a96fba6SXin Li   bool SetPosition(uint64_t position, ErrorPtr* error);
168*1a96fba6SXin Li 
169*1a96fba6SXin Li   // Moves the stream pointer by |offset| bytes relative to |whence|.
170*1a96fba6SXin Li   // When successful, returns true and sets the new pointer position from the
171*1a96fba6SXin Li   // beginning of the stream to |new_position|. If |new_position| is nullptr,
172*1a96fba6SXin Li   // new stream position is not returned.
173*1a96fba6SXin Li   // On error, returns false and specifies additional details in |error| if it
174*1a96fba6SXin Li   // is not nullptr.
175*1a96fba6SXin Li   virtual bool Seek(int64_t offset,
176*1a96fba6SXin Li                     Whence whence,
177*1a96fba6SXin Li                     uint64_t* new_position,
178*1a96fba6SXin Li                     ErrorPtr* error) = 0;
179*1a96fba6SXin Li 
180*1a96fba6SXin Li   // == Read operations =======================================================
181*1a96fba6SXin Li 
182*1a96fba6SXin Li   // -- Asynchronous ----------------------------------------------------------
183*1a96fba6SXin Li 
184*1a96fba6SXin Li   // Reads up to |size_to_read| bytes from the stream asynchronously. It is not
185*1a96fba6SXin Li   // guaranteed that all requested data will be read. It is not an error for
186*1a96fba6SXin Li   // this function to read fewer bytes than requested. If the function reads
187*1a96fba6SXin Li   // zero bytes, it means that the end of stream is reached.
188*1a96fba6SXin Li   // Upon successful read, the |success_callback| will be invoked with the
189*1a96fba6SXin Li   // actual number of bytes read.
190*1a96fba6SXin Li   // If an error occurs during the asynchronous operation, the |error_callback|
191*1a96fba6SXin Li   // is invoked with the error details. The error object pointer passed in as a
192*1a96fba6SXin Li   // parameter to the |error_callback| is valid only for the duration of that
193*1a96fba6SXin Li   // callback.
194*1a96fba6SXin Li   // If this function successfully schedules an asynchronous operation, it
195*1a96fba6SXin Li   // returns true. If it fails immediately, it will return false and set the
196*1a96fba6SXin Li   // error details to |error| object and will not call the success or error
197*1a96fba6SXin Li   // callbacks.
198*1a96fba6SXin Li   // The |buffer| must be at least |size_to_read| in size and must remain
199*1a96fba6SXin Li   // valid for the duration of the asynchronous operation (until either
200*1a96fba6SXin Li   // |success_callback| or |error_callback| is called).
201*1a96fba6SXin Li   // Only one asynchronous operation at a time is allowed on the stream (read
202*1a96fba6SXin Li   // and/or write)
203*1a96fba6SXin Li   // Uses ReadNonBlocking() and MonitorDataAvailable().
204*1a96fba6SXin Li   virtual bool ReadAsync(void* buffer,
205*1a96fba6SXin Li                          size_t size_to_read,
206*1a96fba6SXin Li                          const base::Callback<void(size_t)>& success_callback,
207*1a96fba6SXin Li                          const ErrorCallback& error_callback,
208*1a96fba6SXin Li                          ErrorPtr* error);
209*1a96fba6SXin Li 
210*1a96fba6SXin Li   // Similar to ReadAsync() operation above but reads exactly |size_to_read|
211*1a96fba6SXin Li   // bytes from the stream into the |buffer|. Attempt to read past the end of
212*1a96fba6SXin Li   // the stream is considered an error in this case and will trigger the
213*1a96fba6SXin Li   // |error_callback|. The rest of restrictions and conditions of ReadAsync()
214*1a96fba6SXin Li   // method applies to ReadAllAsync() as well.
215*1a96fba6SXin Li   // Uses ReadNonBlocking() and MonitorDataAvailable().
216*1a96fba6SXin Li   virtual bool ReadAllAsync(void* buffer,
217*1a96fba6SXin Li                             size_t size_to_read,
218*1a96fba6SXin Li                             const base::Closure& success_callback,
219*1a96fba6SXin Li                             const ErrorCallback& error_callback,
220*1a96fba6SXin Li                             ErrorPtr* error);
221*1a96fba6SXin Li 
222*1a96fba6SXin Li   // -- Synchronous non-blocking ----------------------------------------------
223*1a96fba6SXin Li 
224*1a96fba6SXin Li   // Reads up to |size_to_read| bytes from the stream without blocking.
225*1a96fba6SXin Li   // The |buffer| must be at least |size_to_read| in size. It is not an error
226*1a96fba6SXin Li   // for this function to return without reading all (or any) the data.
227*1a96fba6SXin Li   // The actual amount of data read (which could be 0 bytes) is returned in
228*1a96fba6SXin Li   // |size_read|.
229*1a96fba6SXin Li   // On error, the function returns false and specifies additional error details
230*1a96fba6SXin Li   // in |error|.
231*1a96fba6SXin Li   // If end of stream is reached or if no data is currently available to be read
232*1a96fba6SXin Li   // without blocking, |size_read| will contain 0 and the function will still
233*1a96fba6SXin Li   // return true (success). In case of end-of-stream scenario, |end_of_stream|
234*1a96fba6SXin Li   // will also be set to true to indicate that no more data is available.
235*1a96fba6SXin Li   virtual bool ReadNonBlocking(void* buffer,
236*1a96fba6SXin Li                                size_t size_to_read,
237*1a96fba6SXin Li                                size_t* size_read,
238*1a96fba6SXin Li                                bool* end_of_stream,
239*1a96fba6SXin Li                                ErrorPtr* error) = 0;
240*1a96fba6SXin Li 
241*1a96fba6SXin Li   // -- Synchronous blocking --------------------------------------------------
242*1a96fba6SXin Li 
243*1a96fba6SXin Li   // Reads up to |size_to_read| bytes from the stream. This function will block
244*1a96fba6SXin Li   // until at least one byte is read or the end of stream is reached or until
245*1a96fba6SXin Li   // the stream is closed.
246*1a96fba6SXin Li   // The |buffer| must be at least |size_to_read| in size. It is not an error
247*1a96fba6SXin Li   // for this function to return without reading all the data. The actual amount
248*1a96fba6SXin Li   // of data read (which could be 0 bytes) is returned in |size_read|.
249*1a96fba6SXin Li   // On error, the function returns false and specifies additional error details
250*1a96fba6SXin Li   // in |error|. In this case, the state of the stream pointer is undefined,
251*1a96fba6SXin Li   // since some bytes might have been read successfully (and the pointer moved)
252*1a96fba6SXin Li   // before the error has occurred and |size_read| is not updated.
253*1a96fba6SXin Li   // If end of stream is reached, |size_read| will contain 0 and the function
254*1a96fba6SXin Li   // will still return true (success).
255*1a96fba6SXin Li   virtual bool ReadBlocking(void* buffer,
256*1a96fba6SXin Li                             size_t size_to_read,
257*1a96fba6SXin Li                             size_t* size_read,
258*1a96fba6SXin Li                             ErrorPtr* error);
259*1a96fba6SXin Li 
260*1a96fba6SXin Li   // Reads exactly |size_to_read| bytes to |buffer|. Returns false on error
261*1a96fba6SXin Li   // (reading fewer than requested bytes is treated as an error as well).
262*1a96fba6SXin Li   // Calls ReadAllBlocking() repeatedly until all the data is read.
263*1a96fba6SXin Li   virtual bool ReadAllBlocking(void* buffer,
264*1a96fba6SXin Li                                size_t size_to_read,
265*1a96fba6SXin Li                                ErrorPtr* error);
266*1a96fba6SXin Li 
267*1a96fba6SXin Li   // == Write operations ======================================================
268*1a96fba6SXin Li 
269*1a96fba6SXin Li   // -- Asynchronous ----------------------------------------------------------
270*1a96fba6SXin Li 
271*1a96fba6SXin Li   // Writes up to |size_to_write| bytes from |buffer| to the stream
272*1a96fba6SXin Li   // asynchronously. It is not guaranteed that all requested data will be
273*1a96fba6SXin Li   // written. It is not an error for this function to write fewer bytes than
274*1a96fba6SXin Li   // requested.
275*1a96fba6SXin Li   // Upon successful write, the |success_callback| will be invoked with the
276*1a96fba6SXin Li   // actual number of bytes written.
277*1a96fba6SXin Li   // If an error occurs during the asynchronous operation, the |error_callback|
278*1a96fba6SXin Li   // is invoked with the error details. The error object pointer is valid only
279*1a96fba6SXin Li   // for the duration of the error callback.
280*1a96fba6SXin Li   // If this function successfully schedules an asynchronous operation, it
281*1a96fba6SXin Li   // returns true. If it fails immediately, it will return false and set the
282*1a96fba6SXin Li   // error details to |error| object and will not call the success or error
283*1a96fba6SXin Li   // callbacks.
284*1a96fba6SXin Li   // The |buffer| must be at least |size_to_write| in size and must remain
285*1a96fba6SXin Li   // valid for the duration of the asynchronous operation (until either
286*1a96fba6SXin Li   // |success_callback| or |error_callback| is called).
287*1a96fba6SXin Li   // Only one asynchronous operation at a time is allowed on the stream (read
288*1a96fba6SXin Li   // and/or write).
289*1a96fba6SXin Li   // Uses WriteNonBlocking() and MonitorDataAvailable().
290*1a96fba6SXin Li   virtual bool WriteAsync(const void* buffer,
291*1a96fba6SXin Li                           size_t size_to_write,
292*1a96fba6SXin Li                           const base::Callback<void(size_t)>& success_callback,
293*1a96fba6SXin Li                           const ErrorCallback& error_callback,
294*1a96fba6SXin Li                           ErrorPtr* error);
295*1a96fba6SXin Li 
296*1a96fba6SXin Li   // Similar to WriteAsync() operation above but writes exactly |size_to_write|
297*1a96fba6SXin Li   // bytes from |buffet| to the stream. When all the data is written
298*1a96fba6SXin Li   // successfully, the |success_callback| is invoked.
299*1a96fba6SXin Li   // The rest of restrictions and conditions of WriteAsync() method applies to
300*1a96fba6SXin Li   // WriteAllAsync() as well.
301*1a96fba6SXin Li   // Uses WriteNonBlocking() and MonitorDataAvailable().
302*1a96fba6SXin Li   virtual bool WriteAllAsync(const void* buffer,
303*1a96fba6SXin Li                              size_t size_to_write,
304*1a96fba6SXin Li                              const base::Closure& success_callback,
305*1a96fba6SXin Li                              const ErrorCallback& error_callback,
306*1a96fba6SXin Li                              ErrorPtr* error);
307*1a96fba6SXin Li 
308*1a96fba6SXin Li   // -- Synchronous non-blocking ----------------------------------------------
309*1a96fba6SXin Li 
310*1a96fba6SXin Li   // Writes up to |size_to_write| bytes to the stream. The |buffer| must be at
311*1a96fba6SXin Li   // least |size_to_write| in size. It is not an error for this function to
312*1a96fba6SXin Li   // return without writing all the data requested (or any data at all).
313*1a96fba6SXin Li   // The actual amount of data written is returned in |size_written|.
314*1a96fba6SXin Li   // On error, the function returns false and specifies additional error details
315*1a96fba6SXin Li   // in |error|.
316*1a96fba6SXin Li   virtual bool WriteNonBlocking(const void* buffer,
317*1a96fba6SXin Li                                 size_t size_to_write,
318*1a96fba6SXin Li                                 size_t* size_written,
319*1a96fba6SXin Li                                 ErrorPtr* error) = 0;
320*1a96fba6SXin Li 
321*1a96fba6SXin Li   // -- Synchronous blocking --------------------------------------------------
322*1a96fba6SXin Li 
323*1a96fba6SXin Li   // Writes up to |size_to_write| bytes to the stream. The |buffer| must be at
324*1a96fba6SXin Li   // least |size_to_write| in size. It is not an error for this function to
325*1a96fba6SXin Li   // return without writing all the data requested. The actual amount of data
326*1a96fba6SXin Li   // written is returned in |size_written|.
327*1a96fba6SXin Li   // On error, the function returns false and specifies additional error details
328*1a96fba6SXin Li   // in |error|.
329*1a96fba6SXin Li   virtual bool WriteBlocking(const void* buffer,
330*1a96fba6SXin Li                              size_t size_to_write,
331*1a96fba6SXin Li                              size_t* size_written,
332*1a96fba6SXin Li                              ErrorPtr* error);
333*1a96fba6SXin Li 
334*1a96fba6SXin Li   // Writes exactly |size_to_write| bytes to |buffer|. Returns false on error
335*1a96fba6SXin Li   // (writing fewer than requested bytes is treated as an error as well).
336*1a96fba6SXin Li   // Calls WriteBlocking() repeatedly until all the data is written.
337*1a96fba6SXin Li   virtual bool WriteAllBlocking(const void* buffer,
338*1a96fba6SXin Li                                 size_t size_to_write,
339*1a96fba6SXin Li                                 ErrorPtr* error);
340*1a96fba6SXin Li 
341*1a96fba6SXin Li   // == Finalizing/closing streams  ===========================================
342*1a96fba6SXin Li 
343*1a96fba6SXin Li   // Flushes all the user-space data from cache output buffers to storage
344*1a96fba6SXin Li   // medium. For read-only streams this is a no-op, however it is still valid
345*1a96fba6SXin Li   // to call this method on read-only streams.
346*1a96fba6SXin Li   // If an error occurs, the function returns false and specifies additional
347*1a96fba6SXin Li   // error details in |error|.
348*1a96fba6SXin Li   virtual bool FlushBlocking(ErrorPtr* error) = 0;
349*1a96fba6SXin Li 
350*1a96fba6SXin Li   // Flushes all the user-space data from the cache output buffer
351*1a96fba6SXin Li   // asynchronously. When all the data is successfully flushed, the
352*1a96fba6SXin Li   // |success_callback| is invoked. If an error occurs while flushing, partial
353*1a96fba6SXin Li   // data might be flushed and |error_callback| is invoked. If there's an error
354*1a96fba6SXin Li   // scheduling the flush operation, it returns false and neither callback will
355*1a96fba6SXin Li   // be called.
356*1a96fba6SXin Li   virtual bool FlushAsync(const base::Closure& success_callback,
357*1a96fba6SXin Li                           const ErrorCallback& error_callback,
358*1a96fba6SXin Li                           ErrorPtr* error);
359*1a96fba6SXin Li 
360*1a96fba6SXin Li   // Closes the underlying stream. The stream is also automatically closed
361*1a96fba6SXin Li   // when the stream object is destroyed, but since closing a stream is
362*1a96fba6SXin Li   // an operation that may fail, in situations when it is important to detect
363*1a96fba6SXin Li   // the failure to close the stream, CloseBlocking() should be used explicitly
364*1a96fba6SXin Li   // before destroying the stream object.
365*1a96fba6SXin Li   virtual bool CloseBlocking(ErrorPtr* error) = 0;
366*1a96fba6SXin Li 
367*1a96fba6SXin Li   // == Data availability monitoring ==========================================
368*1a96fba6SXin Li 
369*1a96fba6SXin Li   // Overloaded by derived classes to provide stream monitoring for read/write
370*1a96fba6SXin Li   // data availability for the stream. Calls |callback| when data can be read
371*1a96fba6SXin Li   // and/or written without blocking.
372*1a96fba6SXin Li   // |mode| specifies the type of operation to monitor for (read, write, both).
373*1a96fba6SXin Li   virtual bool WaitForData(AccessMode mode,
374*1a96fba6SXin Li                            const base::Callback<void(AccessMode)>& callback,
375*1a96fba6SXin Li                            ErrorPtr* error) = 0;
376*1a96fba6SXin Li 
377*1a96fba6SXin Li   // Helper function for implementing blocking I/O. Blocks until the
378*1a96fba6SXin Li   // non-blocking operation specified by |in_mode| can be performed.
379*1a96fba6SXin Li   // If |out_mode| is not nullptr, it receives the actual operation that can be
380*1a96fba6SXin Li   // performed. For example, watching a stream for READ_WRITE while only
381*1a96fba6SXin Li   // READ can be performed, |out_mode| would contain READ even though |in_mode|
382*1a96fba6SXin Li   // was set to READ_WRITE.
383*1a96fba6SXin Li   // |timeout| is the maximum amount of time to wait. Set it to TimeDelta::Max()
384*1a96fba6SXin Li   // to wait indefinitely.
385*1a96fba6SXin Li   virtual bool WaitForDataBlocking(AccessMode in_mode,
386*1a96fba6SXin Li                                    base::TimeDelta timeout,
387*1a96fba6SXin Li                                    AccessMode* out_mode,
388*1a96fba6SXin Li                                    ErrorPtr* error) = 0;
389*1a96fba6SXin Li 
390*1a96fba6SXin Li   // Cancels pending asynchronous read/write operations.
391*1a96fba6SXin Li   virtual void CancelPendingAsyncOperations();
392*1a96fba6SXin Li 
393*1a96fba6SXin Li  protected:
394*1a96fba6SXin Li   Stream() = default;
395*1a96fba6SXin Li 
396*1a96fba6SXin Li  private:
397*1a96fba6SXin Li   // Simple wrapper to call the externally exposed |success_callback| that only
398*1a96fba6SXin Li   // receives a size_t.
399*1a96fba6SXin Li   BRILLO_PRIVATE static void IgnoreEOSCallback(
400*1a96fba6SXin Li       const base::Callback<void(size_t)>& success_callback,
401*1a96fba6SXin Li       size_t read,
402*1a96fba6SXin Li       bool eos);
403*1a96fba6SXin Li 
404*1a96fba6SXin Li   // The internal implementation of ReadAsync() and ReadAllAsync().
405*1a96fba6SXin Li   // Calls ReadNonBlocking and if there's no data available waits for it calling
406*1a96fba6SXin Li   // WaitForData(). The extra |force_async_callback| tell whether the success
407*1a96fba6SXin Li   // callback should be called from the main loop instead of directly from this
408*1a96fba6SXin Li   // method. This method only calls WaitForData() if ReadNonBlocking() returns a
409*1a96fba6SXin Li   // situation in which it would block (bytes_read = 0 and eos = false),
410*1a96fba6SXin Li   // preventing us from calling WaitForData() on streams that don't support such
411*1a96fba6SXin Li   // feature.
412*1a96fba6SXin Li   BRILLO_PRIVATE bool ReadAsyncImpl(
413*1a96fba6SXin Li       void* buffer,
414*1a96fba6SXin Li       size_t size_to_read,
415*1a96fba6SXin Li       const base::Callback<void(size_t, bool)>& success_callback,
416*1a96fba6SXin Li       const ErrorCallback& error_callback,
417*1a96fba6SXin Li       ErrorPtr* error,
418*1a96fba6SXin Li       bool force_async_callback);
419*1a96fba6SXin Li 
420*1a96fba6SXin Li   // Called from the main loop when the ReadAsyncImpl finished right away
421*1a96fba6SXin Li   // without waiting for data. We use this callback to call the
422*1a96fba6SXin Li   // |sucess_callback| but invalidate the callback if the Stream is destroyed
423*1a96fba6SXin Li   // while this call is waiting in the main loop.
424*1a96fba6SXin Li   BRILLO_PRIVATE void OnReadAsyncDone(
425*1a96fba6SXin Li       const base::Callback<void(size_t, bool)>& success_callback,
426*1a96fba6SXin Li       size_t bytes_read,
427*1a96fba6SXin Li       bool eos);
428*1a96fba6SXin Li 
429*1a96fba6SXin Li   // Called from WaitForData() when read operations can be performed
430*1a96fba6SXin Li   // without blocking (the type of operation is provided in |mode|).
431*1a96fba6SXin Li   BRILLO_PRIVATE void OnReadAvailable(
432*1a96fba6SXin Li       void* buffer,
433*1a96fba6SXin Li       size_t size_to_read,
434*1a96fba6SXin Li       const base::Callback<void(size_t, bool)>& success_callback,
435*1a96fba6SXin Li       const ErrorCallback& error_callback,
436*1a96fba6SXin Li       AccessMode mode);
437*1a96fba6SXin Li 
438*1a96fba6SXin Li   // The internal implementation of WriteAsync() and WriteAllAsync().
439*1a96fba6SXin Li   // Calls WriteNonBlocking and if the write would block for it to not block
440*1a96fba6SXin Li   // calling WaitForData(). The extra |force_async_callback| tell whether the
441*1a96fba6SXin Li   // success callback should be called from the main loop instead of directly
442*1a96fba6SXin Li   // from this method. This method only calls WaitForData() if
443*1a96fba6SXin Li   // WriteNonBlocking() returns a situation in which it would block
444*1a96fba6SXin Li   // (size_written = 0 and eos = false), preventing us from calling
445*1a96fba6SXin Li   // WaitForData() on streams that don't support such feature.
446*1a96fba6SXin Li   BRILLO_PRIVATE bool WriteAsyncImpl(
447*1a96fba6SXin Li       const void* buffer,
448*1a96fba6SXin Li       size_t size_to_write,
449*1a96fba6SXin Li       const base::Callback<void(size_t)>& success_callback,
450*1a96fba6SXin Li       const ErrorCallback& error_callback,
451*1a96fba6SXin Li       ErrorPtr* error,
452*1a96fba6SXin Li       bool force_async_callback);
453*1a96fba6SXin Li 
454*1a96fba6SXin Li   // Called from the main loop when the WriteAsyncImpl finished right away
455*1a96fba6SXin Li   // without waiting for data. We use this callback to call the
456*1a96fba6SXin Li   // |sucess_callback| but invalidate the callback if the Stream is destroyed
457*1a96fba6SXin Li   // while this call is waiting in the main loop.
458*1a96fba6SXin Li   BRILLO_PRIVATE void OnWriteAsyncDone(
459*1a96fba6SXin Li       const base::Callback<void(size_t)>& success_callback,
460*1a96fba6SXin Li       size_t size_written);
461*1a96fba6SXin Li 
462*1a96fba6SXin Li   // Called from WaitForData() when write operations can be performed
463*1a96fba6SXin Li   // without blocking (the type of operation is provided in |mode|).
464*1a96fba6SXin Li   BRILLO_PRIVATE void OnWriteAvailable(
465*1a96fba6SXin Li       const void* buffer,
466*1a96fba6SXin Li       size_t size,
467*1a96fba6SXin Li       const base::Callback<void(size_t)>& success_callback,
468*1a96fba6SXin Li       const ErrorCallback& error_callback,
469*1a96fba6SXin Li       AccessMode mode);
470*1a96fba6SXin Li 
471*1a96fba6SXin Li   // Helper callbacks to implement ReadAllAsync/WriteAllAsync.
472*1a96fba6SXin Li   BRILLO_PRIVATE void ReadAllAsyncCallback(
473*1a96fba6SXin Li       void* buffer,
474*1a96fba6SXin Li       size_t size_to_read,
475*1a96fba6SXin Li       const base::Closure& success_callback,
476*1a96fba6SXin Li       const ErrorCallback& error_callback,
477*1a96fba6SXin Li       size_t size_read,
478*1a96fba6SXin Li       bool eos);
479*1a96fba6SXin Li   BRILLO_PRIVATE void WriteAllAsyncCallback(
480*1a96fba6SXin Li       const void* buffer,
481*1a96fba6SXin Li       size_t size_to_write,
482*1a96fba6SXin Li       const base::Closure& success_callback,
483*1a96fba6SXin Li       const ErrorCallback& error_callback,
484*1a96fba6SXin Li       size_t size_written);
485*1a96fba6SXin Li 
486*1a96fba6SXin Li   // Helper callbacks to implement FlushAsync().
487*1a96fba6SXin Li   BRILLO_PRIVATE void FlushAsyncCallback(
488*1a96fba6SXin Li       const base::Closure& success_callback,
489*1a96fba6SXin Li       const ErrorCallback& error_callback);
490*1a96fba6SXin Li 
491*1a96fba6SXin Li   // Data members for asynchronous read operations.
492*1a96fba6SXin Li   bool is_async_read_pending_{false};
493*1a96fba6SXin Li 
494*1a96fba6SXin Li   // Data members for asynchronous write operations.
495*1a96fba6SXin Li   bool is_async_write_pending_{false};
496*1a96fba6SXin Li 
497*1a96fba6SXin Li   base::WeakPtrFactory<Stream> weak_ptr_factory_{this};
498*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(Stream);
499*1a96fba6SXin Li };
500*1a96fba6SXin Li 
501*1a96fba6SXin Li // A smart pointer to the stream used to pass the stream object around.
502*1a96fba6SXin Li using StreamPtr = std::unique_ptr<Stream>;
503*1a96fba6SXin Li 
504*1a96fba6SXin Li }  // namespace brillo
505*1a96fba6SXin Li 
506*1a96fba6SXin Li #endif  // LIBBRILLO_BRILLO_STREAMS_STREAM_H_
507