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