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