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
12namespace brillo {
13namespace stream_utils {
14
15// Generates "Stream closed" error and returns false.
16BRILLO_EXPORT bool ErrorStreamClosed(
17    const tracked_objects::Location& location, ErrorPtr* error);
18
19// Generates "Not supported" error and returns false.
20BRILLO_EXPORT bool ErrorOperationNotSupported(
21    const tracked_objects::Location& location, ErrorPtr* error);
22
23// Generates "Read past end of stream" error and returns false.
24BRILLO_EXPORT bool ErrorReadPastEndOfStream(
25    const tracked_objects::Location& location, ErrorPtr* error);
26
27// Generates "Operation time out" error and returns false.
28BRILLO_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.
39BRILLO_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.
52BRILLO_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.
62inline 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.
68inline 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.
74inline 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
81using CopyDataSuccessCallback =
82    base::Callback<void(StreamPtr, StreamPtr, uint64_t)>;
83using 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.
92BRILLO_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.
104BRILLO_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