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, bufs] = co_await source.pull(arr);
71 if(ec)
72 co_return {ec, total};
73
74 if(bufs.empty())
75 {
76 auto [eof_ec] = co_await sink.write_eof();
77 co_return {eof_ec, total};
78 }
79
80 auto [write_ec, n] = co_await sink.write(bufs);
81 total += n;
82 source.consume(n);
83 if(write_ec)
84 co_return {write_ec, total};
85 }
86 280 }
87
88 /** Transfer data from a BufferSource to a WriteStream.
89
90 This function pulls data from the source and writes it to the
91 stream until the source is exhausted or an error occurs. The
92 stream uses `write_some()` which may perform partial writes,
93 so this function loops until all pulled data is consumed.
94
95 Unlike the WriteSink overload, this function does not signal
96 EOF explicitly since WriteStream does not provide a write_eof
97 method. The transfer completes when the source is exhausted.
98
99 @tparam Src The source type, must satisfy @ref BufferSource.
100 @tparam Stream The stream type, must satisfy @ref WriteStream.
101
102 @param source The source to pull data from.
103 @param stream The stream to write data to.
104
105 @return A task that yields `(std::error_code, std::size_t)`.
106 On success, `ec` is default-constructed (no error) and `n` is
107 the total number of bytes transferred. On error, `ec` contains
108 the error code and `n` is the total number of bytes transferred
109 before the error.
110
111 @par Example
112 @code
113 task<void> transfer_body(BufferSource auto& source, WriteStream auto& stream)
114 {
115 auto [ec, n] = co_await push_to(source, stream);
116 if (ec)
117 {
118 // Handle error
119 }
120 // n bytes were transferred
121 }
122 @endcode
123
124 @see BufferSource, WriteStream, pull_from
125 */
126 template<BufferSource Src, WriteStream Stream>
127 task<io_result<std::size_t>>
128
1/1
✓ Branch 1 taken 104 times.
104 push_to(Src& source, Stream& stream)
129 {
130 const_buffer arr[detail::max_iovec_];
131 std::size_t total = 0;
132
133 for(;;)
134 {
135 auto [ec, bufs] = co_await source.pull(arr);
136 if(ec)
137 co_return {ec, total};
138
139 if(bufs.empty())
140 co_return {{}, total};
141
142 auto [write_ec, n] = co_await stream.write_some(bufs);
143 if(write_ec)
144 co_return {write_ec, total};
145
146 total += n;
147 source.consume(n);
148 }
149 208 }
150
151 } // namespace capy
152 } // namespace boost
153
154 #endif
155