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 <coroutine>
22 #include <cstddef>
23 #include <stop_token>
24 #include <system_error>
25
26 namespace boost::corosio {
27
28 /** Reads and writes bytes through a platform I/O backend.
29
30 Combines @ref io_read_stream and @ref io_write_stream into
31 a single bidirectional stream. The `read_some` and `write_some`
32 operations are inherited from the base classes and dispatch through
33 `do_read_some` / `do_write_some`. This class implements those by
34 forwarding to the platform `implementation`.
35
36 The implementation hierarchy stays linear (no diamond):
37 `io_object::implementation` -> `io_stream::implementation`
38 -> `tcp_socket::implementation` -> backend impl.
39
40 @par Semantics
41 Concrete classes wrap direct platform I/O completed by the kernel.
42 Functions taking `io_stream&` signal that platform implementation
43 is required. Use this when you need actual kernel I/O rather than
44 a mock or test double.
45
46 For generic stream algorithms that work with test mocks,
47 use `template<capy::Stream S>` instead of `io_stream&`.
48
49 @par Thread Safety
50 Distinct objects: Safe.
51 Shared objects: Unsafe. All calls to a single stream must be made
52 from the same implicit or explicit serialization context.
53
54 @par Example
55 @par !example io_stream
56
57 @see io_read_stream, io_write_stream, tcp_socket
58 */
59 class BOOST_COROSIO_DECL io_stream
60 : public io_read_stream
61 , public io_write_stream
62 {
63 public:
64 /** Declares the read and write operations a platform backend
65 must implement.
66
67 Derived classes implement this interface to provide kernel-level
68 read and write operations for each supported platform (IOCP,
69 epoll, kqueue, io_uring).
70 */
71 struct implementation : io_object::implementation
72 {
73 /** Initiate platform read operation.
74
75 @param h Coroutine handle to resume on completion.
76 @param ex Executor for dispatching the completion.
77 @param buffers Target buffer sequence.
78 @param token Stop token for cancellation.
79 @param ec Output error code.
80 @param bytes Output bytes transferred.
81
82 @return Coroutine handle to resume immediately.
83 */
84 virtual std::coroutine_handle<> read_some(
85 std::coroutine_handle<> h,
86 capy::executor_ref ex,
87 buffer_param buffers,
88 std::stop_token token,
89 std::error_code* ec,
90 std::size_t* bytes) = 0;
91
92 /** Initiate platform write operation.
93
94 @param h Coroutine handle to resume on completion.
95 @param ex Executor for dispatching the completion.
96 @param buffers Source buffer sequence.
97 @param token Stop token for cancellation.
98 @param ec Output error code.
99 @param bytes Output bytes transferred.
100
101 @return Coroutine handle to resume immediately.
102 */
103 virtual std::coroutine_handle<> write_some(
104 std::coroutine_handle<> h,
105 capy::executor_ref ex,
106 buffer_param buffers,
107 std::stop_token token,
108 std::error_code* ec,
109 std::size_t* bytes) = 0;
110 };
111
112 protected:
113 /// Default construct; the handle is supplied through @ref io_object.
114 10651x io_stream() noexcept = default;
115
116 /// Construct stream from a handle.
117 explicit io_stream(handle h) noexcept : io_object(std::move(h)) {}
118
119 /** Dispatch read through implementation vtable.
120
121 @param h Coroutine handle to resume on completion.
122 @param ex Executor for dispatching the completion.
123 @param buffers Target buffer sequence.
124 @param token Stop token for cancellation.
125 @param ec Output error code.
126 @param bytes Output bytes transferred.
127
128 @return Coroutine handle to resume immediately.
129 */
130 205597x std::coroutine_handle<> do_read_some(
131 std::coroutine_handle<> h,
132 capy::executor_ref ex,
133 buffer_param buffers,
134 std::stop_token token,
135 std::error_code* ec,
136 std::size_t* bytes) override
137 {
138 205597x return get().read_some(h, ex, buffers, std::move(token), ec, bytes);
139 }
140
141 /** Dispatch write through implementation vtable.
142
143 @param h Coroutine handle to resume on completion.
144 @param ex Executor for dispatching the completion.
145 @param buffers Source buffer sequence.
146 @param token Stop token for cancellation.
147 @param ec Output error code.
148 @param bytes Output bytes transferred.
149
150 @return Coroutine handle to resume immediately.
151 */
152 204828x std::coroutine_handle<> do_write_some(
153 std::coroutine_handle<> h,
154 capy::executor_ref ex,
155 buffer_param buffers,
156 std::stop_token token,
157 std::error_code* ec,
158 std::size_t* bytes) override
159 {
160 204828x return get().write_some(h, ex, buffers, std::move(token), ec, bytes);
161 }
162
163 private:
164 /// Return implementation downcasted to stream interface.
165 410425x implementation& get() const noexcept
166 {
167 410425x return *static_cast<implementation*>(h_.get());
168 }
169 };
170
171 } // namespace boost::corosio
172
173 #endif
174