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.
IsReadAccessMode(Stream::AccessMode mode)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.
IsWriteAccessMode(Stream::AccessMode mode)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.
MakeAccessMode(bool read,bool write)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