34#include "pw_async2/dispatcher.h"
35#include "pw_async2/poll.h"
36#include "pw_bytes/span.h"
37#include "pw_channel/properties.h"
38#include "pw_multibuf/multibuf.h"
39#include "pw_result/result.h"
40#include "pw_status/status.h"
42namespace pw::channel {
55template <DataType kDataType, Property... kProperties>
59 [[nodiscard]]
static constexpr DataType
data_type() {
return kDataType; }
62 [[nodiscard]]
static constexpr bool reliable() {
63 return ((kProperties == Property::kReliable) || ...);
66 [[nodiscard]]
static constexpr bool seekable() {
67 return ((kProperties == Property::kSeekable) || ...);
70 [[nodiscard]]
static constexpr bool readable() {
71 return ((kProperties == Property::kReadable) || ...);
74 [[nodiscard]]
static constexpr bool writable() {
75 return ((kProperties == Property::kWritable) || ...);
108 template <
typename Sibling,
109 typename = internal::EnableIfConversionIsValid<Channel, Sibling>>
110 constexpr operator Sibling&() {
111 return as<Sibling>();
113 template <
typename Sibling,
114 typename = internal::EnableIfConversionIsValid<Channel, Sibling>>
115 constexpr operator const Sibling&()
const {
116 return as<Sibling>();
120 template <
typename Sibling>
121 [[nodiscard]] Sibling&
as() {
122 internal::CheckThatConversionIsValid<Channel, Sibling>();
123 return static_cast<Sibling&
>(
static_cast<AnyChannel&
>(*this));
125 template <
typename Sibling>
126 [[nodiscard]]
const Sibling&
as()
const {
127 internal::CheckThatConversionIsValid<Channel, Sibling>();
128 return static_cast<const Sibling&
>(
static_cast<const AnyChannel&
>(*this));
133 template <Property... kOtherChannelProperties>
134 [[nodiscard]]
auto&
as() {
137 template <Property... kOtherChannelProperties>
138 [[nodiscard]]
const auto&
as()
const {
142 [[nodiscard]] Channel<DataType::kByte, kProperties...>&
143 IgnoreDatagramBoundaries() {
144 static_assert(kDataType == DataType::kDatagram,
145 "IgnoreDatagramBoundaries() may only be called to use a "
146 "datagram channel to a byte channel");
147 return static_cast<Channel<DataType::kByte, kProperties...
>&>(
148 static_cast<AnyChannel&
>(*this));
151 [[nodiscard]]
const Channel<DataType::kByte, kProperties...>&
152 IgnoreDatagramBoundaries()
const {
153 static_assert(kDataType == DataType::kDatagram,
154 "IgnoreDatagramBoundaries() may only be called to use a "
155 "datagram channel to a byte channel");
156 return static_cast<const Channel<DataType::kByte, kProperties...
>&>(
157 static_cast<const AnyChannel&
>(*this));
161 static_assert(internal::PropertiesAreValid<kProperties...>());
163 friend class AnyChannel;
165 explicit constexpr Channel() =
default;
183 :
private Channel<DataType::kByte, kReadable>,
184 private Channel<DataType::kByte, kWritable>,
185 private Channel<DataType::kByte, kReadable, kWritable>,
186 private Channel<DataType::kByte, kReliable, kReadable>,
187 private Channel<DataType::kByte, kReliable, kWritable>,
188 private Channel<DataType::kByte, kReliable, kReadable, kWritable>,
189 private Channel<DataType::kDatagram, kReadable>,
190 private Channel<DataType::kDatagram, kWritable>,
191 private Channel<DataType::kDatagram, kReadable, kWritable>,
192 private Channel<DataType::kDatagram, kReliable, kReadable>,
193 private Channel<DataType::kDatagram, kReliable, kWritable>,
194 private Channel<DataType::kDatagram, kReliable, kReadable, kWritable> {
206 [[nodiscard]]
constexpr DataType
data_type()
const {
return data_type_; }
210 return (properties_ & Property::kReliable) != 0;
215 return (properties_ & Property::kSeekable) != 0;
220 return (properties_ & Property::kReadable) != 0;
225 return (properties_ & Property::kWritable) != 0;
230 [[nodiscard]]
constexpr bool is_read_open()
const {
return read_open_; }
238 return read_open_ || write_open_;
270 return Status::FailedPrecondition();
273 if (result.
IsReady() && result->status().IsFailedPrecondition()) {
299 return Status::FailedPrecondition();
302 if (result.
IsReady() && result->IsFailedPrecondition()) {
330 return DoPendAllocateWriteBuffer(cx, min_bytes);
366 return Status::FailedPrecondition();
368 Status status = DoStageWrite(std::move(data));
369 if (status.IsFailedPrecondition()) {
385 return Status::FailedPrecondition();
388 if (status.
IsReady() && status->IsFailedPrecondition()) {
444 return Status::FailedPrecondition();
447 if (result.IsReady()) {
459 void set_read_closed() { read_open_ =
false; }
465 void set_write_closed() { write_open_ =
false; }
468 template <DataType, Property...>
469 friend class Channel;
471 template <DataType, Property...>
472 friend class internal::BaseChannelImpl;
475 explicit constexpr AnyChannel(DataType type, uint8_t properties)
477 properties_(properties),
485 virtual async2::Poll<Result<multibuf::MultiBuf>> DoPendRead(
486 async2::Context& cx) = 0;
490 virtual async2::Poll<std::optional<multibuf::MultiBuf>>
491 DoPendAllocateWriteBuffer(async2::Context& cx,
size_t min_bytes) = 0;
495 virtual Status DoStageWrite(multibuf::MultiBuf&& buffer) = 0;
516template <Property... kProperties>
520template <Property... kProperties>
563template <DataType kDataType, Property... kProperties>
565 static_assert(internal::PropertiesAreValid<kProperties...>());
569template <Property... kProperties>
573template <Property... kProperties>
582template <
typename ChannelType>
587template <DataType kDataType, Property... kProperties>
591 explicit constexpr Implement() =
default;
597#include "pw_channel/internal/channel_specializations.h"
Definition: dispatcher_base.h:52
constexpr bool IsReady() const noexcept
Returns whether or not this value is Ready.
Definition: poll.h:125
Definition: channel.h:194
constexpr bool readable() const
Returns whether the channel implementation is readable.
Definition: channel.h:219
async2::Poll< pw::Status > PendClose(async2::Context &cx)
Definition: channel.h:442
async2::Poll< Status > PendWrite(async2::Context &cx)
Definition: channel.h:383
async2::Poll< Status > PendReadyToWrite(pw::async2::Context &cx)
Definition: channel.h:297
constexpr bool is_read_or_write_open() const
True if the channel is open for either reading or writing.
Definition: channel.h:237
async2::Poll< Result< multibuf::MultiBuf > > PendRead(async2::Context &cx)
Definition: channel.h:268
Status Seek(async2::Context &cx, ptrdiff_t position, Whence whence)
async2::Poll< std::optional< multibuf::MultiBuf > > PendAllocateWriteBuffer(async2::Context &cx, size_t min_bytes)
Definition: channel.h:328
constexpr bool reliable() const
Returns whether the channel implementation is reliable.
Definition: channel.h:209
constexpr bool writable() const
Returns whether the channel implementation is writable.
Definition: channel.h:224
constexpr bool is_read_open() const
Definition: channel.h:230
Status StageWrite(multibuf::MultiBuf &&data)
Definition: channel.h:364
constexpr bool is_write_open() const
Definition: channel.h:234
constexpr bool seekable() const
Returns whether the channel implementation is seekable.
Definition: channel.h:214
virtual async2::Poll< Status > DoPendClose(async2::Context &cx)=0
TODO: b/323622630 - Seek and Position are not yet implemented.
constexpr DataType data_type() const
Returns the data type of the channel implementation.
Definition: channel.h:206
async2::Poll< Status > PendWrite(async2::Context &cx)
constexpr bool is_read_open() const
async2::Poll< Result< multibuf::MultiBuf > > PendRead(async2::Context &cx)
async2::Poll< std::optional< multibuf::MultiBuf > > PendAllocateWriteBuffer(async2::Context &cx, size_t min_bytes)
static constexpr bool seekable()
Returns whether the channel type is seekable.
Definition: channel.h:66
static constexpr bool readable()
Returns whether the channel type is readable.
Definition: channel.h:70
constexpr bool is_write_open() const
Sibling & as()
Returns a reference to this channel as another compatible channel type.
Definition: channel.h:121
static constexpr bool reliable()
Returns whether the channel type is reliable.
Definition: channel.h:62
auto & as()
Definition: channel.h:134
constexpr bool is_read_or_write_open() const
True if the channel is open for reading or writing.
Definition: channel.h:87
async2::Poll< Status > PendReadyToWrite(pw::async2::Context &cx)
Status StageWrite(multibuf::MultiBuf &&data)
async2::Poll< pw::Status > PendClose(async2::Context &cx)
static constexpr DataType data_type()
Returns the data type of this channel.
Definition: channel.h:59
static constexpr bool writable()
Returns whether the channel type is writable.
Definition: channel.h:74
Definition: channel.h:564
Definition: channel.h:583
Definition: multibuf.h:245