Home | History | Annotate | Download | only in streams
      1 // Copyright 2015 The Chromium OS 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 #ifndef LIBBRILLO_BRILLO_STREAMS_STREAM_UTILS_H_
      6 #define LIBBRILLO_BRILLO_STREAMS_STREAM_UTILS_H_
      7 
      8 #include <base/location.h>
      9 #include <brillo/brillo_export.h>
     10 #include <brillo/streams/stream.h>
     11 
     12 namespace brillo {
     13 namespace stream_utils {
     14 
     15 // Generates "Stream closed" error and returns false.
     16 BRILLO_EXPORT bool ErrorStreamClosed(
     17     const tracked_objects::Location& location, ErrorPtr* error);
     18 
     19 // Generates "Not supported" error and returns false.
     20 BRILLO_EXPORT bool ErrorOperationNotSupported(
     21     const tracked_objects::Location& location, ErrorPtr* error);
     22 
     23 // Generates "Read past end of stream" error and returns false.
     24 BRILLO_EXPORT bool ErrorReadPastEndOfStream(
     25     const tracked_objects::Location& location, ErrorPtr* error);
     26 
     27 // Generates "Operation time out" error and returns false.
     28 BRILLO_EXPORT bool ErrorOperationTimeout(
     29     const tracked_objects::Location& location, ErrorPtr* error);
     30 
     31 // Checks if |position| + |offset| fit within the constraint of positive
     32 // signed int64_t type. We use uint64_t for absolute stream pointer positions,
     33 // however many implementations, including file-descriptor-based I/O do not
     34 // support the full extent of unsigned 64 bit numbers. So we restrict the file
     35 // positions to what can fit in the signed 64 bit value (that is, we support
     36 // "only" up to 9 exabytes, instead of the possible 18).
     37 // The |location| parameter will be used to report the origin of the error
     38 // if one is generated/triggered.
     39 BRILLO_EXPORT bool CheckInt64Overflow(
     40     const tracked_objects::Location& location,
     41     uint64_t position,
     42     int64_t offset,
     43     ErrorPtr* error);
     44 
     45 // Helper function to calculate the stream position based on the current
     46 // stream position and offset. Returns true and the new calculated stream
     47 // position in |new_position| if successful. In case of invalid stream
     48 // position (negative values or out of range of signed 64 bit values), returns
     49 // false and "invalid_parameter" |error|.
     50 // The |location| parameter will be used to report the origin of the error
     51 // if one is generated/triggered.
     52 BRILLO_EXPORT bool CalculateStreamPosition(
     53     const tracked_objects::Location& location,
     54     int64_t offset,
     55     Stream::Whence whence,
     56     uint64_t current_position,
     57     uint64_t stream_size,
     58     uint64_t* new_position,
     59     ErrorPtr* error);
     60 
     61 // Checks if |mode| allows read access.
     62 inline bool IsReadAccessMode(Stream::AccessMode mode) {
     63   return mode == Stream::AccessMode::READ ||
     64          mode == Stream::AccessMode::READ_WRITE;
     65 }
     66 
     67 // Checks if |mode| allows write access.
     68 inline bool IsWriteAccessMode(Stream::AccessMode mode) {
     69   return mode == Stream::AccessMode::WRITE ||
     70          mode == Stream::AccessMode::READ_WRITE;
     71 }
     72 
     73 // Make the access mode based on read/write rights requested.
     74 inline Stream::AccessMode MakeAccessMode(bool read, bool write) {
     75   CHECK(read || write);  // Either read or write (or both) must be specified.
     76   if (read && write)
     77     return Stream::AccessMode::READ_WRITE;
     78   return write ? Stream::AccessMode::WRITE : Stream::AccessMode::READ;
     79 }
     80 
     81 using CopyDataSuccessCallback =
     82     base::Callback<void(StreamPtr, StreamPtr, uint64_t)>;
     83 using CopyDataErrorCallback =
     84     base::Callback<void(StreamPtr, StreamPtr, const brillo::Error*)>;
     85 
     86 // Asynchronously copies data from input stream to output stream until all the
     87 // data from the input stream is read. The function takes ownership of both
     88 // streams for the duration of the operation and then gives them back when
     89 // either the |success_callback| or |error_callback| is called.
     90 // |success_callback| also provides the number of bytes actually copied.
     91 // This variant of CopyData uses internal buffer of 4 KiB for the operation.
     92 BRILLO_EXPORT void CopyData(StreamPtr in_stream,
     93                             StreamPtr out_stream,
     94                             const CopyDataSuccessCallback& success_callback,
     95                             const CopyDataErrorCallback& error_callback);
     96 
     97 // Asynchronously copies data from input stream to output stream until the
     98 // maximum amount of data specified in |max_size_to_copy| is copied or the end
     99 // of the input stream is encountered. The function takes ownership of both
    100 // streams for the duration of the operation and then gives them back when
    101 // either the |success_callback| or |error_callback| is called.
    102 // |success_callback| also provides the number of bytes actually copied.
    103 // |buffer_size| specifies the size of the read buffer to use for the operation.
    104 BRILLO_EXPORT void CopyData(StreamPtr in_stream,
    105                             StreamPtr out_stream,
    106                             uint64_t max_size_to_copy,
    107                             size_t buffer_size,
    108                             const CopyDataSuccessCallback& success_callback,
    109                             const CopyDataErrorCallback& error_callback);
    110 
    111 }  // namespace stream_utils
    112 }  // namespace brillo
    113 
    114 #endif  // LIBBRILLO_BRILLO_STREAMS_STREAM_UTILS_H_
    115