Line data Source code
1 : //
2 : // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
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/capy
8 : //
9 :
10 : #ifndef BOOST_CAPY_READ_HPP
11 : #define BOOST_CAPY_READ_HPP
12 :
13 : #include <boost/capy/detail/config.hpp>
14 : #include <boost/capy/io_result.hpp>
15 : #include <boost/capy/task.hpp>
16 : #include <boost/capy/buffers.hpp>
17 : #include <boost/capy/buffers/consuming_buffers.hpp>
18 : #include <boost/capy/concept/read_stream.hpp>
19 : #include <boost/system/error_code.hpp>
20 :
21 : #include <cstddef>
22 :
23 : namespace boost {
24 : namespace capy {
25 :
26 : /** Read data until the buffer sequence is full or an error occurs.
27 :
28 : This function reads data from the stream into the buffer sequence
29 : until either the entire buffer sequence is filled or an error
30 : occurs (including end-of-file).
31 :
32 : @tparam Stream The stream type, must satisfy @ref ReadStream.
33 : @tparam MB The buffer sequence type, must satisfy
34 : @ref MutableBufferSequence.
35 :
36 : @param stream The stream to read from.
37 : @param buffers The buffer sequence to read into.
38 :
39 : @return A task that yields `(system::error_code, std::size_t)`.
40 : On success, `ec` is default-constructed (no error) and `n` is
41 : `buffer_size(buffers)`. On error or EOF, `ec` contains the
42 : error code and `n` is the total number of bytes written before
43 : the error.
44 :
45 : @par Example
46 : @code
47 : task<void> example(ReadStream auto& stream)
48 : {
49 : char buf[1024];
50 : auto [ec, n] = co_await read(stream, mutable_buffer(buf, sizeof(buf)));
51 : if (ec == cond::eof)
52 : {
53 : // Handle end-of-file
54 : }
55 : else if (ec)
56 : {
57 : // Handle other error
58 : }
59 : // n bytes were read into buf
60 : }
61 : @endcode
62 :
63 : @see ReadStream, MutableBufferSequence
64 : */
65 : auto
66 8 : read(
67 : ReadStream auto& stream,
68 : MutableBufferSequence auto const& buffers) ->
69 : task<io_result<std::size_t>>
70 : {
71 : consuming_buffers consuming(buffers);
72 : std::size_t const total_size = buffer_size(buffers);
73 : std::size_t total_read = 0;
74 :
75 : while(total_read < total_size)
76 : {
77 : auto [ec, n] = co_await stream.read_some(consuming);
78 : if(ec)
79 : co_return {ec, total_read};
80 : consuming.consume(n);
81 : total_read += n;
82 : }
83 :
84 : co_return {{}, total_read};
85 16 : }
86 :
87 : } // namespace capy
88 : } // namespace boost
89 :
90 : #endif
|