blob: 8eb800c4f90259a15311b29a49ac3c0856e20a59 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:261/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 04:47:3111#ifndef RTC_BASE_STREAM_H_
12#define RTC_BASE_STREAM_H_
henrike@webrtc.orgf0488722014-05-13 18:00:2613
Henrik Kjellanderec78f1c2017-06-29 05:52:5014#include <memory>
15
Tommi7e41c062024-04-28 20:40:5616#include "absl/functional/any_invocable.h"
Harald Alvestrand1f609c82022-11-07 17:12:0717#include "api/array_view.h"
Tommid2004882024-04-22 14:50:4018#include "api/sequence_checker.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3119#include "rtc_base/buffer.h"
Tommi7e41c062024-04-28 20:40:5620#include "rtc_base/logging.h"
Tommid2004882024-04-22 14:50:4021#include "rtc_base/system/no_unique_address.h"
Mirko Bonadei35214fc2019-09-23 12:54:2822#include "rtc_base/system/rtc_export.h"
Artem Titove41c4332018-07-25 13:04:2823#include "rtc_base/third_party/sigslot/sigslot.h"
Sebastian Jansson4db28b52020-01-08 13:07:1524#include "rtc_base/thread.h"
Henrik Kjellanderec78f1c2017-06-29 05:52:5025
26namespace rtc {
27
28///////////////////////////////////////////////////////////////////////////////
29// StreamInterface is a generic asynchronous stream interface, supporting read,
30// write, and close operations, and asynchronous signalling of state changes.
31// The interface is designed with file, memory, and socket implementations in
32// mind. Some implementations offer extended operations, such as seeking.
33///////////////////////////////////////////////////////////////////////////////
34
35// The following enumerations are declared outside of the StreamInterface
36// class for brevity in use.
37
38// The SS_OPENING state indicates that the stream will signal open or closed
39// in the future.
40enum StreamState { SS_CLOSED, SS_OPENING, SS_OPEN };
41
42// Stream read/write methods return this value to indicate various success
43// and failure conditions described below.
44enum StreamResult { SR_ERROR, SR_SUCCESS, SR_BLOCK, SR_EOS };
45
46// StreamEvents are used to asynchronously signal state transitionss. The flags
47// may be combined.
48// SE_OPEN: The stream has transitioned to the SS_OPEN state
49// SE_CLOSE: The stream has transitioned to the SS_CLOSED state
50// SE_READ: Data is available, so Read is likely to not return SR_BLOCK
51// SE_WRITE: Data can be written, so Write is likely to not return SR_BLOCK
52enum StreamEvent { SE_OPEN = 1, SE_READ = 2, SE_WRITE = 4, SE_CLOSE = 8 };
53
Tommi04482982020-10-05 12:43:5354class RTC_EXPORT StreamInterface {
Henrik Kjellanderec78f1c2017-06-29 05:52:5055 public:
Tommi04482982020-10-05 12:43:5356 virtual ~StreamInterface() {}
Henrik Kjellanderec78f1c2017-06-29 05:52:5057
Byoungchan Lee14af7622022-01-11 20:24:5858 StreamInterface(const StreamInterface&) = delete;
59 StreamInterface& operator=(const StreamInterface&) = delete;
60
Henrik Kjellanderec78f1c2017-06-29 05:52:5061 virtual StreamState GetState() const = 0;
62
63 // Read attempts to fill buffer of size buffer_len. Write attempts to send
64 // data_len bytes stored in data. The variables read and write are set only
65 // on SR_SUCCESS (see below). Likewise, error is only set on SR_ERROR.
66 // Read and Write return a value indicating:
67 // SR_ERROR: an error occurred, which is returned in a non-null error
68 // argument. Interpretation of the error requires knowledge of the
69 // stream's concrete type, which limits its usefulness.
70 // SR_SUCCESS: some number of bytes were successfully written, which is
71 // returned in a non-null read/write argument.
72 // SR_BLOCK: the stream is in non-blocking mode, and the operation would
73 // block, or the stream is in SS_OPENING state.
74 // SR_EOS: the end-of-stream has been reached, or the stream is in the
75 // SS_CLOSED state.
Harald Alvestrand11840ce2022-11-10 10:50:5076
Harald Alvestrand1f609c82022-11-07 17:12:0777 virtual StreamResult Read(rtc::ArrayView<uint8_t> buffer,
78 size_t& read,
Harald Alvestrandcf707762022-11-17 10:50:4579 int& error) = 0;
Harald Alvestrand1f609c82022-11-07 17:12:0780 virtual StreamResult Write(rtc::ArrayView<const uint8_t> data,
81 size_t& written,
Harald Alvestrandcf707762022-11-17 10:50:4582 int& error) = 0;
Harald Alvestrand11840ce2022-11-10 10:50:5083
Henrik Kjellanderec78f1c2017-06-29 05:52:5084 // Attempt to transition to the SS_CLOSED state. SE_CLOSE will not be
85 // signalled as a result of this call.
86 virtual void Close() = 0;
87
Tommi7e41c062024-04-28 20:40:5688 // Streams may issue one or more events to indicate state changes to a
89 // provided callback.
90 // The first argument is a bit-wise combination of `StreamEvent` flags.
91 // If SE_CLOSE is set, then the second argument is the associated error code.
92 // Otherwise, the value of the second parameter is undefined and should be
93 // set to 0.
94 // Note: Not all streams support callbacks. However, SS_OPENING and
95 // SR_BLOCK returned from member functions imply that certain callbacks will
96 // be made in the future.
97 void SetEventCallback(absl::AnyInvocable<void(int, int)> callback) {
98 RTC_DCHECK_RUN_ON(&callback_sequence_);
99 RTC_DCHECK(!callback_ || !callback);
100 callback_ = std::move(callback);
101 }
102
103 // TODO(bugs.webrtc.org/11943): Remove after updating downstream code.
104 sigslot::signal3<StreamInterface*, int, int> SignalEvent
105 [[deprecated("Use SetEventCallback instead")]];
Henrik Kjellanderec78f1c2017-06-29 05:52:50106
Henrik Kjellanderec78f1c2017-06-29 05:52:50107 // Return true if flush is successful.
108 virtual bool Flush();
109
Henrik Kjellanderec78f1c2017-06-29 05:52:50110 //
111 // CONVENIENCE METHODS
112 //
113 // These methods are implemented in terms of other methods, for convenience.
114 //
115
Henrik Kjellanderec78f1c2017-06-29 05:52:50116 // WriteAll is a helper function which repeatedly calls Write until all the
117 // data is written, or something other than SR_SUCCESS is returned. Note that
118 // unlike Write, the argument 'written' is always set, and may be non-zero
119 // on results other than SR_SUCCESS. The remaining arguments have the
120 // same semantics as Write.
Harald Alvestrand11840ce2022-11-10 10:50:50121 [[deprecated("Use version with ArrayView")]] StreamResult
122 WriteAll(const void* data, size_t data_len, size_t* written, int* error);
Henrik Kjellanderec78f1c2017-06-29 05:52:50123
Harald Alvestrand11840ce2022-11-10 10:50:50124#pragma clang diagnostic push
125#pragma clang diagnostic ignored "-Wdeprecated-declarations"
126 // TODO(bugs.webrc.org/14632): Remove pragmas and change underlying
127 // implementation when downstream code is converted.
128 StreamResult WriteAll(ArrayView<const uint8_t> data,
129 size_t& written,
130 int& error) {
Harald Alvestrand1f609c82022-11-07 17:12:07131 return WriteAll(data.data(), data.size(), &written, &error);
132 }
Harald Alvestrand11840ce2022-11-10 10:50:50133#pragma clang diagnostic pop
Harald Alvestrand1f609c82022-11-07 17:12:07134
Henrik Kjellanderec78f1c2017-06-29 05:52:50135 protected:
136 StreamInterface();
Tommid2004882024-04-22 14:50:40137
138 // Utility function for derived classes.
139 void FireEvent(int stream_events, int err) RTC_RUN_ON(&callback_sequence_) {
Tommi7e41c062024-04-28 20:40:56140 if (callback_) {
141 callback_(stream_events, err);
142 }
143#pragma clang diagnostic push
144#pragma clang diagnostic ignored "-Wdeprecated-declarations"
Tommid2004882024-04-22 14:50:40145 // TODO(tommi): This is for backwards compatibility only while `SignalEvent`
Tommi7e41c062024-04-28 20:40:56146 // is being replaced by `SetEventCallback`.
Tommid2004882024-04-22 14:50:40147 SignalEvent(this, stream_events, err);
Tommi7e41c062024-04-28 20:40:56148#pragma clang diagnostic pop
Tommid2004882024-04-22 14:50:40149 }
150
151 RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker callback_sequence_{
152 webrtc::SequenceChecker::kDetached};
Tommi7e41c062024-04-28 20:40:56153
154 private:
155 absl::AnyInvocable<void(int, int)> callback_
156 RTC_GUARDED_BY(&callback_sequence_) = nullptr;
Henrik Kjellanderec78f1c2017-06-29 05:52:50157};
158
Henrik Kjellanderec78f1c2017-06-29 05:52:50159} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26160
Mirko Bonadei92ea95e2017-09-15 04:47:31161#endif // RTC_BASE_STREAM_H_