idfxx 1.0.0
Modern C++23 components for ESP-IDF
Loading...
Searching...
No Matches
buffer.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Chris Leishman
3
4#pragma once
5
17#include "sdkconfig.h"
18
19#include <idfxx/net/endpoint>
20#include <idfxx/net/error>
21
22#include <cstddef>
23#include <iterator>
24#include <optional>
25#include <ranges>
26#include <span>
27
28// Forward declaration from lwIP.
29struct netbuf;
30
32
33class stream_channel;
35class raw_channel;
36namespace detail {
37class connectionless_channel;
38}
39
60class [[nodiscard]] buffer {
61public:
68
71
74
77
80
83
90 [[nodiscard]] ::netbuf* idf_handle() const noexcept { return _buf; }
91
93 [[nodiscard]] bool is_open() const noexcept { return _buf != nullptr; }
94
97
103 [[nodiscard]] std::optional<endpoint> from_endpoint() const noexcept;
104
116 public:
118 class iterator {
119 public:
120 using value_type = std::span<const std::byte>;
121 using difference_type = std::ptrdiff_t;
122 using iterator_concept = std::forward_iterator_tag;
123 // operator* yields a prvalue span, so the C++17 category tops out at
124 // input; iterator_concept above is what makes it a forward_iterator.
125 using iterator_category = std::input_iterator_tag;
126
129
132
135
138 auto tmp = *this;
139 ++*this;
140 return tmp;
141 }
142
144 [[nodiscard]] bool operator==(const iterator& other) const noexcept { return _seg == other._seg; }
145
146 private:
147 friend class segment_view;
148 explicit iterator(const void* seg) noexcept
149 : _seg(seg) {}
150
151 const void* _seg = nullptr;
152 };
153
156
158 [[nodiscard]] iterator end() const noexcept { return iterator{}; }
159
160 private:
161 friend class buffer;
162 explicit segment_view(const ::netbuf* buf) noexcept
163 : _buf(buf) {}
164
165 const ::netbuf* _buf = nullptr;
166 };
167
184
185#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
203 void attach(std::span<const std::byte> data) { idfxx::unwrap(try_attach(data)); }
204#endif
205
212 [[nodiscard]] size_t copy_into(std::span<std::byte> dst) const noexcept;
213
229 [[nodiscard]] result<void> try_attach(std::span<const std::byte> data);
230
231private:
232 friend class stream_channel;
233 friend class datagram_channel;
234 friend class raw_channel;
235 friend class detail::connectionless_channel;
236
237 explicit buffer(::netbuf* buf) noexcept
238 : _buf(buf) {}
239
240 ::netbuf* _buf = nullptr;
241};
242
243} // namespace idfxx::net::netconn
244
246// A `segment_view` iterator points into the owning buffer's netbuf chain, not
247// into the view object itself, so it stays valid after the view is destroyed
248// (as long as the buffer lives). That makes the view a borrowed range: piping a
249// temporary's segments through a view adaptor — `buf.segments() | views::…` —
250// does not dangle.
251template<>
252inline constexpr bool std::ranges::enable_borrowed_range<idfxx::net::netconn::buffer::segment_view> = true;
254
// end of idfxx_net_netconn_buffer
Address/port pair identifying a transport endpoint.
Definition endpoint.hpp:129
Forward iterator over a buffer's data segments.
Definition buffer.hpp:118
bool operator==(const iterator &other) const noexcept
Compares two iterators; equal iff they reference the same segment.
Definition buffer.hpp:144
iterator() noexcept=default
Constructs a past-the-end iterator.
A forward range over a buffer's data segments.
Definition buffer.hpp:115
iterator begin() const noexcept
Returns an iterator to the first segment.
Owning handle for a netconn buffer.
Definition buffer.hpp:60
size_t copy_into(std::span< std::byte > dst) const noexcept
Copies all segments into a destination buffer.
buffer() noexcept=default
Default-constructs an empty (non-owning) buffer handle.
segment_view segments() const noexcept
Returns a forward range over the buffer's data segments.
Definition buffer.hpp:183
size_t len() const noexcept
Returns the total length of all segments.
result< void > try_attach(std::span< const std::byte > data)
Attaches an external (non-owned) buffer for sending.
static result< buffer > make()
Allocates an empty buffer.
void attach(std::span< const std::byte > data)
Attaches an external (non-owned) buffer for sending.
Definition buffer.hpp:203
bool is_open() const noexcept
Returns true if this buffer owns a netbuf (false after move-from).
Definition buffer.hpp:93
A raw IP netconn channel.
T unwrap(result< T > result)
Throws a std::system_error if the result is an error.
Definition error.hpp:307
std::expected< T, std::error_code > result
result type wrapping a value or error code.
Definition error.hpp:120