include/boost/corosio/io/io_stream.hpp

100.0% Lines (7 / 7) 100.0% Functions (4 / 4)
io_stream.hpp
f(x) Functions (4)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2026 Steve Gerbino
4 // Copyright (c) 2026 Michael Vandeberg
5 //
6 // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // Official repository: https://github.com/cppalliance/corosio
10 //
11
12 #ifndef BOOST_COROSIO_IO_IO_STREAM_HPP
13 #define BOOST_COROSIO_IO_IO_STREAM_HPP
14
15 #include <boost/corosio/detail/config.hpp>
16 #include <boost/corosio/io/io_read_stream.hpp>
17 #include <boost/corosio/io/io_write_stream.hpp>
18 #include <boost/corosio/detail/buffer_param.hpp>
19 #include <boost/capy/ex/executor_ref.hpp>
20
21 #include <boost/capy/continuation.hpp>
22
23 #include <coroutine>
24 #include <cstddef>
25 #include <stop_token>
26 #include <system_error>
27
28 namespace boost::corosio {
29
30 /** Reads and writes bytes through a platform I/O backend.
31
32 Combines @ref io_read_stream and @ref io_write_stream into
33 a single bidirectional stream. The `read_some` and `write_some`
34 operations are inherited from the base classes and dispatch through
35 `do_read_some` / `do_write_some`. This class implements those by
36 forwarding to the platform `implementation`.
37
38 The implementation hierarchy stays linear (no diamond):
39 `io_object::implementation` -> `io_stream::implementation`
40 -> `tcp_socket::implementation` -> backend impl.
41
42 @par Semantics
43 Concrete classes wrap direct platform I/O completed by the kernel.
44 Functions taking `io_stream&` signal that platform implementation
45 is required. Use this when you need actual kernel I/O rather than
46 a mock or test double.
47
48 For generic stream algorithms that work with test mocks,
49 use `template<capy::Stream S>` instead of `io_stream&`.
50
51 @par Thread Safety
52 Distinct objects: Safe.
53 Shared objects: Unsafe. All calls to a single stream must be made
54 from the same implicit or explicit serialization context.
55
56 @par Example
57 @par !example io_stream
58
59 @see io_read_stream, io_write_stream, tcp_socket
60 */
61 class BOOST_COROSIO_DECL io_stream
62 : public io_read_stream
63 , public io_write_stream
64 {
65 public:
66 /** Declares the read and write operations a platform backend
67 must implement.
68
69 Derived classes implement this interface to provide kernel-level
70 read and write operations for each supported platform (IOCP,
71 epoll, kqueue, io_uring).
72 */
73 struct implementation : io_object::implementation
74 {
75 /** Initiate platform read operation.
76
77 @param cont Continuation to resume on completion; it lives in
78 the awaiting frame until then.
79 @param ex Executor for dispatching the completion.
80 @param buffers Target buffer sequence.
81 @param token Stop token for cancellation.
82 @param ec Output error code.
83 @param bytes Output bytes transferred.
84
85 @return Coroutine handle to resume immediately.
86 */
87 virtual std::coroutine_handle<> read_some(
88 capy::continuation& cont,
89 capy::executor_ref ex,
90 buffer_param buffers,
91 std::stop_token token,
92 std::error_code* ec,
93 std::size_t* bytes) = 0;
94
95 /** Initiate platform write operation.
96
97 @param cont Continuation to resume on completion; it lives in
98 the awaiting frame until then.
99 @param ex Executor for dispatching the completion.
100 @param buffers Source buffer sequence.
101 @param token Stop token for cancellation.
102 @param ec Output error code.
103 @param bytes Output bytes transferred.
104
105 @return Coroutine handle to resume immediately.
106 */
107 virtual std::coroutine_handle<> write_some(
108 capy::continuation& cont,
109 capy::executor_ref ex,
110 buffer_param buffers,
111 std::stop_token token,
112 std::error_code* ec,
113 std::size_t* bytes) = 0;
114 };
115
116 protected:
117 /// Default construct; the handle is supplied through @ref io_object.
118 26592x io_stream() noexcept = default;
119
120 /// Construct stream from a handle.
121 explicit io_stream(handle h) noexcept : io_object(std::move(h)) {}
122
123 /** Dispatch read through implementation vtable.
124
125 @param cont Continuation to resume on completion; it lives in
126 the awaiting frame until then.
127 @param ex Executor for dispatching the completion.
128 @param buffers Target buffer sequence.
129 @param token Stop token for cancellation.
130 @param ec Output error code.
131 @param bytes Output bytes transferred.
132
133 @return Coroutine handle to resume immediately.
134 */
135 238184x std::coroutine_handle<> do_read_some(
136 capy::continuation& cont,
137 capy::executor_ref ex,
138 buffer_param buffers,
139 std::stop_token token,
140 std::error_code* ec,
141 std::size_t* bytes) override
142 {
143 238184x return get().read_some(cont, ex, buffers, std::move(token), ec, bytes);
144 }
145
146 /** Dispatch write through implementation vtable.
147
148 @param cont Continuation to resume on completion; it lives in
149 the awaiting frame until then.
150 @param ex Executor for dispatching the completion.
151 @param buffers Source buffer sequence.
152 @param token Stop token for cancellation.
153 @param ec Output error code.
154 @param bytes Output bytes transferred.
155
156 @return Coroutine handle to resume immediately.
157 */
158 236452x std::coroutine_handle<> do_write_some(
159 capy::continuation& cont,
160 capy::executor_ref ex,
161 buffer_param buffers,
162 std::stop_token token,
163 std::error_code* ec,
164 std::size_t* bytes) override
165 {
166 236452x return get().write_some(cont, ex, buffers, std::move(token), ec, bytes);
167 }
168
169 private:
170 /// Return implementation downcasted to stream interface.
171 474636x implementation& get() const noexcept
172 {
173 474636x return *static_cast<implementation*>(h_.get());
174 }
175 };
176
177 } // namespace boost::corosio
178
179 #endif
180