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