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