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