TLA Line data Source code
1 : //
2 : // Copyright (c) 2026 Steve Gerbino
3 : // Copyright (c) 2026 Michael Vandeberg
4 : //
5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 : //
8 : // Official repository: https://github.com/cppalliance/corosio
9 : //
10 :
11 : #ifndef BOOST_COROSIO_IO_IO_READ_STREAM_HPP
12 : #define BOOST_COROSIO_IO_IO_READ_STREAM_HPP
13 :
14 : #include <boost/corosio/detail/config.hpp>
15 : #include <boost/corosio/detail/op_base.hpp>
16 : #include <boost/corosio/io/io_object.hpp>
17 : #include <boost/corosio/detail/buffer_param.hpp>
18 : #include <boost/capy/results.hpp>
19 : #include <boost/capy/ex/executor_ref.hpp>
20 : #include <boost/capy/ex/await_context.hpp>
21 :
22 : #include <boost/capy/continuation.hpp>
23 :
24 : #include <coroutine>
25 : #include <cstddef>
26 : #include <stop_token>
27 : #include <system_error>
28 :
29 : namespace boost::corosio {
30 :
31 : /** Reads bytes from a stream asynchronously.
32 :
33 : Provides the `read_some` operation via a pure virtual
34 : `do_read_some` dispatch point. Concrete classes override
35 : `do_read_some` to route through their implementation.
36 :
37 : Uses virtual inheritance from @ref io_object so that
38 : @ref io_stream can combine this with @ref io_write_stream
39 : without duplicating the `io_object` base.
40 :
41 : @par Thread Safety
42 : Distinct objects: Safe.
43 : Shared objects: Unsafe.
44 :
45 : @see @ref io_write_stream, @ref io_stream, @ref io_object
46 : */
47 : class BOOST_COROSIO_DECL io_read_stream : virtual public io_object
48 : {
49 : protected:
50 : /// Awaitable for async read operations.
51 : template<class MutableBufferSequence>
52 : struct read_some_awaitable
53 : : detail::bytes_op_base<read_some_awaitable<MutableBufferSequence>>
54 : {
55 : private:
56 : friend io_read_stream;
57 :
58 HIT 235386 : read_some_awaitable(
59 : io_read_stream& ios, MutableBufferSequence buffers) noexcept
60 235386 : : ios_(ios)
61 235386 : , buffers_(std::move(buffers))
62 : {
63 235386 : }
64 :
65 : friend detail::bytes_op_base<
66 : read_some_awaitable<MutableBufferSequence>>;
67 : io_read_stream& ios_;
68 : MutableBufferSequence buffers_;
69 :
70 : std::coroutine_handle<>
71 235359 : dispatch(capy::continuation& cont, capy::executor_ref ex) const
72 : {
73 470718 : return ios_.do_read_some(
74 706077 : cont, ex, buffers_, this->token_, &this->ec_, &this->bytes_);
75 : }
76 : };
77 :
78 : /** Dispatch a read through the concrete implementation.
79 :
80 : @param cont Continuation to resume on completion; it lives in
81 : the awaiting frame until then.
82 : @param ex Executor for dispatching the completion.
83 : @param buffers Target buffer sequence.
84 : @param token Stop token for cancellation.
85 : @param ec Output error code.
86 : @param bytes Output bytes transferred.
87 :
88 : @return Coroutine handle to resume immediately.
89 : */
90 : virtual std::coroutine_handle<> do_read_some(
91 : capy::continuation& cont,
92 : capy::executor_ref ex,
93 : buffer_param buffers,
94 : std::stop_token token,
95 : std::error_code* ec,
96 : std::size_t* bytes) = 0;
97 :
98 : /// Default construct; the handle is supplied through @ref io_object.
99 25997 : io_read_stream() noexcept = default;
100 :
101 : /// Move construct; the handle moves with @ref io_object.
102 : io_read_stream(io_read_stream&&) noexcept = default;
103 : /// Move assignment is disabled; reseating a live stream is not supported.
104 : io_read_stream& operator=(io_read_stream&&) noexcept = delete;
105 : /// Copy construction is disabled; the handle is uniquely owned.
106 : io_read_stream(io_read_stream const&) = delete;
107 : /// Copy assignment is disabled; the handle is uniquely owned.
108 : io_read_stream& operator=(io_read_stream const&) = delete;
109 :
110 : public:
111 : /** Asynchronously read data from the stream.
112 :
113 : Suspends the calling coroutine and initiates a kernel-level
114 : read. The coroutine resumes when at least one byte is read,
115 : an error occurs, or the operation is cancelled.
116 :
117 : This stream must outlive the returned awaitable. The memory
118 : referenced by @p buffers must remain valid until the operation
119 : completes.
120 :
121 : A closed stream completes with `errc::bad_file_descriptor`.
122 :
123 : @param buffers The buffer sequence to read data into.
124 :
125 : @return An awaitable yielding `(error_code, std::size_t)`.
126 :
127 : @see @ref io_stream::write_some
128 : */
129 : template<capy::MutableBufferSequence MB>
130 235386 : [[nodiscard]] auto read_some(MB const& buffers)
131 : {
132 235386 : return read_some_awaitable<MB>(*this, buffers);
133 : }
134 : };
135 :
136 : } // namespace boost::corosio
137 :
138 : #endif
|