oveRTOS C++ API
C++20 RAII wrappers for the oveRTOS C API
Loading...
Searching...
No Matches
stream.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 Kamil Lulko <kamil.lulko@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 *
6 * This file is part of oveRTOS.
7 */
8
14#pragma once
15
16#ifdef CONFIG_OVE_STREAM
17
18#include <ove/stream.h>
19#include <ove/types.hpp>
20#include <ove/error.hpp>
21
22namespace ove
23{
24
39template <size_t BufSize = 0> class Stream
40{
41 public:
52 explicit Stream(size_t trigger)
53 requires(BufSize > 0)
54 {
55#ifdef CONFIG_OVE_ZERO_HEAP
56 static_assert(BufSize > 0, "BufSize must be > 0 in zero-heap mode");
57 int err = ove_stream_init(&handle_, &storage_, buffer_, BufSize, trigger);
58#else
59 int err = ove_stream_create(&handle_, BufSize, trigger);
60#endif
61 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
62 }
63
67 ~Stream() noexcept
68 {
69 if (!handle_)
70 return;
71#ifdef CONFIG_OVE_ZERO_HEAP
72 ove_stream_deinit(handle_);
73#else
74 ove_stream_destroy(handle_);
75#endif
76 }
77
78 Stream(const Stream &) = delete;
79 Stream &operator=(const Stream &) = delete;
80
81#ifdef CONFIG_OVE_ZERO_HEAP
82 Stream(Stream &&) = delete;
83 Stream &operator=(Stream &&) = delete;
84#else
89 Stream(Stream &&other) noexcept : handle_(other.handle_)
90 {
91 other.handle_ = nullptr;
92 }
93
99 Stream &operator=(Stream &&other) noexcept
100 {
101 if (this != &other) {
102 if (handle_)
103 ove_stream_destroy(handle_);
104 handle_ = other.handle_;
105 other.handle_ = nullptr;
106 }
107 return *this;
108 }
109#endif
110
124 void send(const void *data, size_t len, size_t &bytes_sent)
125 {
126 const int err = ove_stream_send(handle_, data, len, OVE_WAIT_FOREVER, &bytes_sent);
127 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
128 }
129
136 [[nodiscard]] bool try_send(const void *data, size_t len, size_t &bytes_sent)
137 {
138 return ove_stream_send(handle_, data, len, 0, &bytes_sent) == OVE_OK;
139 }
140
157 template <class Rep, class Period>
158 [[nodiscard]] Result<void> try_send_for(const void *data, size_t len,
159 const std::chrono::duration<Rep, Period> &rel,
160 size_t &bytes_sent) noexcept
161 {
162 return from_rc(
163 ove_stream_send(handle_, data, len, to_timeout_ns(rel), &bytes_sent));
164 }
165
173 template <class Clock, class Duration>
174 [[nodiscard]] Result<void>
175 try_send_until(const void *data, size_t len,
176 const std::chrono::time_point<Clock, Duration> &deadline,
177 size_t &bytes_sent) noexcept
178 {
179 const auto rel = deadline - Clock::now();
180 return from_rc(
181 ove_stream_send(handle_, data, len, to_timeout_ns(rel), &bytes_sent));
182 }
183
195 void receive(void *buf, size_t len, size_t &bytes_received)
196 {
197 const int err =
198 ove_stream_receive(handle_, buf, len, OVE_WAIT_FOREVER, &bytes_received);
199 OVE_STATIC_INIT_ASSERT(err == OVE_OK);
200 }
201
206 [[nodiscard]] bool try_receive(void *buf, size_t len, size_t &bytes_received)
207 {
208 return ove_stream_receive(handle_, buf, len, 0, &bytes_received) == OVE_OK;
209 }
210
225 template <class Rep, class Period>
226 [[nodiscard]] Result<void> try_receive_for(void *buf, size_t len,
227 const std::chrono::duration<Rep, Period> &rel,
228 size_t &bytes_received) noexcept
229 {
230 return from_rc(
231 ove_stream_receive(handle_, buf, len, to_timeout_ns(rel), &bytes_received));
232 }
233
239 template <class Clock, class Duration>
240 [[nodiscard]] Result<void>
241 try_receive_until(void *buf, size_t len,
242 const std::chrono::time_point<Clock, Duration> &deadline,
243 size_t &bytes_received) noexcept
244 {
245 const auto rel = deadline - Clock::now();
246 return from_rc(
247 ove_stream_receive(handle_, buf, len, to_timeout_ns(rel), &bytes_received));
248 }
249
260 [[nodiscard]] Result<void> send_from_isr(const void *data, size_t len,
261 size_t &bytes_sent) noexcept
262 {
263 return from_rc(ove_stream_send_from_isr(handle_, data, len, &bytes_sent));
264 }
265
275 [[nodiscard]] Result<void> receive_from_isr(void *buf, size_t len,
276 size_t &bytes_received) noexcept
277 {
278 return from_rc(ove_stream_receive_from_isr(handle_, buf, len, &bytes_received));
279 }
280
286 [[nodiscard]] Result<void> reset() noexcept
287 {
288 return from_rc(ove_stream_reset(handle_));
289 }
290
295 size_t bytes_available() const
296 {
297 return ove_stream_bytes_available(handle_);
298 }
299
304 bool valid() const
305 {
306 return handle_ != nullptr;
307 }
308
313 ove_stream_t handle() const
314 {
315 return handle_;
316 }
317
318 private:
319 ove_stream_t handle_ = nullptr;
320#ifdef CONFIG_OVE_ZERO_HEAP
321 ove_stream_storage_t storage_ = {};
322 uint8_t buffer_[(BufSize > 0 ? BufSize : 1) + 1];
323#endif
324};
325
326} /* namespace ove */
327
328#endif /* CONFIG_OVE_STREAM */
RAII wrapper around an oveRTOS byte-stream (ring-buffer) object.
Definition stream.hpp:40
Result< void > reset() noexcept
Resets the stream, discarding any buffered data.
Definition stream.hpp:286
Result< void > try_receive_until(void *buf, size_t len, const std::chrono::time_point< Clock, Duration > &deadline, size_t &bytes_received) noexcept
Deadline-based receive templated over the clock.
Definition stream.hpp:241
bool try_receive(void *buf, size_t len, size_t &bytes_received)
Non-blocking receive.
Definition stream.hpp:206
ove_stream_t handle() const
Returns the raw oveRTOS stream handle.
Definition stream.hpp:313
void send(const void *data, size_t len, size_t &bytes_sent)
Sends bytes into the stream, blocking indefinitely.
Definition stream.hpp:124
Stream & operator=(Stream &&other) noexcept
Move-assignment operator — transfers ownership of the kernel handle.
Definition stream.hpp:99
bool try_send(const void *data, size_t len, size_t &bytes_sent)
Non-blocking send.
Definition stream.hpp:136
Result< void > receive_from_isr(void *buf, size_t len, size_t &bytes_received) noexcept
Receives bytes from the stream from an ISR context (non-blocking).
Definition stream.hpp:275
bool valid() const
Returns true if the underlying kernel handle is non-null.
Definition stream.hpp:304
~Stream() noexcept
Destroys the stream, releasing the underlying kernel resource.
Definition stream.hpp:67
size_t bytes_available() const
Returns the number of bytes currently available to read.
Definition stream.hpp:295
Stream(size_t trigger)
Constructs and initialises the stream with the given receive trigger.
Definition stream.hpp:52
Result< void > send_from_isr(const void *data, size_t len, size_t &bytes_sent) noexcept
Sends bytes into the stream from an ISR context (non-blocking).
Definition stream.hpp:260
Result< void > try_send_for(const void *data, size_t len, const std::chrono::duration< Rep, Period > &rel, size_t &bytes_sent) noexcept
Bounded-wait send.
Definition stream.hpp:158
Result< void > try_send_until(const void *data, size_t len, const std::chrono::time_point< Clock, Duration > &deadline, size_t &bytes_sent) noexcept
Deadline-based send templated over the clock.
Definition stream.hpp:175
void receive(void *buf, size_t len, size_t &bytes_received)
Receives bytes from the stream, blocking indefinitely.
Definition stream.hpp:195
Stream(Stream &&other) noexcept
Move constructor — transfers ownership of the kernel handle.
Definition stream.hpp:89
Result< void > try_receive_for(void *buf, size_t len, const std::chrono::duration< Rep, Period > &rel, size_t &bytes_received) noexcept
Bounded-wait receive.
Definition stream.hpp:226
Strong ove::Error type, Result<T> alias, and std::error_code interop for the oveRTOS C++ binding.
Top-level namespace for all oveRTOS C++ abstractions.
Definition app.hpp:20
constexpr uint64_t to_timeout_ns(std::chrono::duration< Rep, Period > d) noexcept
Convert a chrono duration to uint64_t nanoseconds for the C API.
Definition types.hpp:129
Result< void > from_rc(int rc) noexcept
Lifts a substrate rc-code into a Result<void>.
Definition error.hpp:254
std::expected< T, Error > Result
std::expected-based result alias.
Definition error.hpp:139
Common type definitions and concepts for the C++ wrapper layer.