libs/capy/include/boost/capy/io/push_to.hpp

100.0% Lines (4/4) 100.0% Functions (3/3) 100.0% Branches (2/2)
libs/capy/include/boost/capy/io/push_to.hpp
Line Branch Hits 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_IO_PUSH_TO_HPP
11 #define BOOST_CAPY_IO_PUSH_TO_HPP
12
13 #include <boost/capy/detail/config.hpp>
14 #include <boost/capy/buffers.hpp>
15 #include <boost/capy/concept/buffer_source.hpp>
16 #include <boost/capy/concept/write_sink.hpp>
17 #include <boost/capy/concept/write_stream.hpp>
18 #include <boost/capy/io_result.hpp>
19 #include <boost/capy/task.hpp>
20
21 #include <cstddef>
22 #include <span>
23
24 namespace boost {
25 namespace capy {
26
27 /** Transfer data from a BufferSource to a WriteSink.
28
29 This function pulls data from the source and writes it to the
30 sink until the source is exhausted or an error occurs. When
31 the source signals completion, `write_eof()` is called on the
32 sink to finalize the transfer.
33
34 @tparam Src The source type, must satisfy @ref BufferSource.
35 @tparam Sink The sink type, must satisfy @ref WriteSink.
36
37 @param source The source to pull data from.
38 @param sink The sink to write data to.
39
40 @return A task that yields `(std::error_code, std::size_t)`.
41 On success, `ec` is default-constructed (no error) and `n` is
42 the total number of bytes transferred. On error, `ec` contains
43 the error code and `n` is the total number of bytes transferred
44 before the error.
45
46 @par Example
47 @code
48 task<void> transfer_body(BufferSource auto& source, WriteSink auto& sink)
49 {
50 auto [ec, n] = co_await push_to(source, sink);
51 if (ec)
52 {
53 // Handle error
54 }
55 // n bytes were transferred
56 }
57 @endcode
58
59 @see BufferSource, WriteSink
60 */
61 template<BufferSource Src, WriteSink Sink>
62 task<io_result<std::size_t>>
63
1/1
✓ Branch 1 taken 140 times.
140 push_to(Src& source, Sink& sink)
64 {
65 const_buffer arr[detail::max_iovec_];
66 std::size_t total = 0;
67
68 for(;;)
69 {
70 auto [ec, count] = co_await source.pull(arr, detail::max_iovec_);
71 if(ec)
72 co_return {ec, total};
73
74 if(count == 0)
75 {
76 auto [eof_ec] = co_await sink.write_eof();
77 co_return {eof_ec, total};
78 }
79
80 std::span<const_buffer const> bufs(arr, count);
81 auto [write_ec, n] = co_await sink.write(bufs);
82 total += n;
83 source.consume(n);
84 if(write_ec)
85 co_return {write_ec, total};
86 }
87 280 }
88
89 /** Transfer data from a BufferSource to a WriteStream.
90
91 This function pulls data from the source and writes it to the
92 stream until the source is exhausted or an error occurs. The
93 stream uses `write_some()` which may perform partial writes,
94 so this function loops until all pulled data is consumed.
95
96 Unlike the WriteSink overload, this function does not signal
97 EOF explicitly since WriteStream does not provide a write_eof
98 method. The transfer completes when the source is exhausted.
99
100 @tparam Src The source type, must satisfy @ref BufferSource.
101 @tparam Stream The stream type, must satisfy @ref WriteStream.
102
103 @param source The source to pull data from.
104 @param stream The stream to write data to.
105
106 @return A task that yields `(std::error_code, std::size_t)`.
107 On success, `ec` is default-constructed (no error) and `n` is
108 the total number of bytes transferred. On error, `ec` contains
109 the error code and `n` is the total number of bytes transferred
110 before the error.
111
112 @par Example
113 @code
114 task<void> transfer_body(BufferSource auto& source, WriteStream auto& stream)
115 {
116 auto [ec, n] = co_await push_to(source, stream);
117 if (ec)
118 {
119 // Handle error
120 }
121 // n bytes were transferred
122 }
123 @endcode
124
125 @see BufferSource, WriteStream, pull_from
126 */
127 template<BufferSource Src, WriteStream Stream>
128 task<io_result<std::size_t>>
129
1/1
✓ Branch 1 taken 104 times.
104 push_to(Src& source, Stream& stream)
130 {
131 const_buffer arr[detail::max_iovec_];
132 std::size_t total = 0;
133
134 for(;;)
135 {
136 auto [ec, count] = co_await source.pull(arr, detail::max_iovec_);
137 if(ec)
138 co_return {ec, total};
139
140 if(count == 0)
141 co_return {{}, total};
142
143 std::span<const_buffer const> bufs(arr, count);
144 auto [write_ec, n] = co_await stream.write_some(bufs);
145 if(write_ec)
146 co_return {write_ec, total};
147
148 total += n;
149 source.consume(n);
150 }
151 208 }
152
153 } // namespace capy
154 } // namespace boost
155
156 #endif
157