Pigweed
C/C++ API Reference
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
test_packet_channel.h
1// Copyright 2025 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include <iterator>
17
18#include "pw_allocator/allocator.h"
19#include "pw_assert/assert.h"
20#include "pw_async2/waker.h"
21#include "pw_channel/packet_channel.h"
22#include "pw_containers/dynamic_deque.h"
23#include "pw_containers/dynamic_vector.h"
24#include "pw_span/span.h"
25
26namespace pw::channel {
27
29template <typename Packet>
31 : public Implement<PacketReaderWriter<Packet>> {
32 public:
33 explicit constexpr TestPacketReaderWriter(allocator::Allocator& allocator)
34 : read_queue_(allocator), staged_(allocator), written_(allocator) {}
35
37 span<const Packet> written_packets() const { return written_; }
38
40 void EnqueueReadPacket(Packet&& packet) {
41 read_queue_.push_back(std::move(packet));
42 std::move(read_waker_).Wake();
43 }
44
45 private:
46 using AnyPacketChannel<Packet>::write_waker;
47
48 async2::Poll<Result<Packet>> DoPendRead(async2::Context& cx) override {
49 if (read_queue_.empty()) {
50 PW_ASYNC_STORE_WAKER(
51 cx, read_waker_, "TestPacketReaderWriter::DoPendRead");
52 return async2::Pending();
53 }
55 async2::Ready(std::move(read_queue_.front()));
56 read_queue_.pop_front();
57 return result;
58 }
59
60 async2::Poll<Status> DoPendReadyToWrite(async2::Context& cx,
61 size_t count) override {
62 // The staged_ queue capacity represents a write reservation.
63 if (staged_.capacity() != 0u) {
64 PW_ASYNC_STORE_WAKER(
65 cx, write_waker(), "TestPacketReaderWriter::DoPendReadyToWrite");
66 return async2::Pending();
67 }
68 staged_.reserve_exact(
69 static_cast<typename decltype(staged_)::size_type>(count));
70 return async2::Ready(OkStatus());
71 }
72
73 void DoStageWrite(Packet&& packet) override {
74 PW_ASSERT(staged_.size() < staged_.capacity());
75 staged_.push_back(std::move(packet));
76 }
77
78 async2::Poll<> DoPendWrite(async2::Context&) override {
79 FlushStaged();
80 return async2::Ready();
81 }
82
83 async2::Poll<Status> DoPendClose(async2::Context&) override {
84 FlushStaged();
85 return async2::Ready(OkStatus());
86 }
87
88 void FlushStaged() {
89 // TODO: b/424613355 - use `insert` instead of repeated `push_back`
90 auto it = std::make_move_iterator(staged_.begin());
91 const auto end = std::make_move_iterator(staged_.end());
92 while (it != end) {
93 written_.push_back(std::move(*it++));
94 }
95 staged_.clear();
96 staged_.shrink_to_fit();
97 std::move(write_waker()).Wake();
98 }
99
100 async2::Waker read_waker_;
101 DynamicDeque<Packet> read_queue_;
102 DynamicDeque<Packet> staged_;
103 DynamicVector<Packet> written_;
104};
105
106} // namespace pw::channel
Definition: allocator.h:34
void reserve_exact(size_type new_capacity)
Increases capacity() to exactly new_capacity. Crashes on failure.
Definition: dynamic_deque.h:162
void shrink_to_fit()
Attempts to reduce capacity() to size(). Not guaranteed to succeed.
Definition: dynamic_deque.h:256
void push_back(const value_type &value)
Definition: dynamic_vector.h:255
Definition: context.h:53
Definition: poll.h:54
Definition: packet_channel.h:217
Definition: channel.h:583
pw::channel::PacketReadWriter implementation for testing use.
Definition: test_packet_channel.h:31
void EnqueueReadPacket(Packet &&packet)
Enqueues packets to be returned from future PendRead calls.
Definition: test_packet_channel.h:40
span< const Packet > written_packets() const
Returns all packets that have been written to this packet channel.
Definition: test_packet_channel.h:37
constexpr size_type size() const noexcept
Returns the number of elements in the deque.
Definition: generic_deque.h:58
constexpr size_type capacity() const noexcept
Returns the maximum number of elements in the deque.
Definition: generic_deque.h:63
constexpr Status OkStatus()
Definition: status.h:234