include/boost/capy/write.hpp

100.0% Lines (2 / 2) 70.0% Functions (7 / 10)
write.hpp
f(x) Functions (10)
Function Calls Lines Blocks
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::capy::write<boost::capy::any_stream, boost::capy::const_buffer>(boost::capy::any_stream&, boost::capy::const_buffer) :92 3x 100.0% 44.0% boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::capy::write<boost::capy::any_stream, std::array<boost::capy::const_buffer, 5ul> >(boost::capy::any_stream&, std::array<boost::capy::const_buffer, 5ul>) :92 1x 100.0% 44.0% boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::capy::write<boost::capy::contingent_write_stream, boost::capy::const_buffer>(boost::capy::contingent_write_stream&, boost::capy::const_buffer) :92 2x 100.0% 44.0% boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::capy::write<boost::capy::test::stream, boost::capy::const_buffer>(boost::capy::test::stream&, boost::capy::const_buffer) :92 1x 100.0% 44.0% boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::capy::write<boost::capy::test::stream, boost::capy::detail::slice_of<std::array<boost::capy::const_buffer, 2ul> > >(boost::capy::test::stream&, boost::capy::detail::slice_of<std::array<boost::capy::const_buffer, 2ul> >) :92 2x 100.0% 44.0% boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::capy::write<boost::capy::test::stream, std::array<boost::capy::const_buffer, 100ul> >(boost::capy::test::stream&, std::array<boost::capy::const_buffer, 100ul>) :92 0 0.0% 0.0% boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::capy::write<boost::capy::test::stream, std::array<boost::capy::const_buffer, 4ul> >(boost::capy::test::stream&, std::array<boost::capy::const_buffer, 4ul>) :92 0 0.0% 0.0% boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::capy::write<boost::capy::test::stream, std::array<boost::capy::mutable_buffer, 2ul> >(boost::capy::test::stream&, std::array<boost::capy::mutable_buffer, 2ul>) :92 0 0.0% 0.0% boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::capy::write<boost::capy::test::write_stream, boost::capy::const_buffer>(boost::capy::test::write_stream&, boost::capy::const_buffer) :92 20x 100.0% 44.0% boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::capy::write<boost::capy::test::write_stream, std::array<boost::capy::const_buffer, 2ul> >(boost::capy::test::write_stream&, std::array<boost::capy::const_buffer, 2ul>) :92 30x 100.0% 44.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
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/capy
9 //
10
11 #ifndef BOOST_CAPY_WRITE_HPP
12 #define BOOST_CAPY_WRITE_HPP
13
14 #include <boost/capy/detail/config.hpp>
15 #include <boost/capy/results.hpp>
16 #include <boost/capy/task.hpp>
17 #include <boost/capy/buffers.hpp>
18 #include <boost/capy/buffers/consuming_buffers.hpp>
19 #include <boost/capy/concept/write_stream.hpp>
20 #include <system_error>
21
22 #include <cstddef>
23
24 namespace boost {
25 namespace capy {
26
27 /** Write an entire buffer sequence to a stream.
28
29 @par Await-effects
30
31 Writes the contents of `buffers` to `stream` via awaiting
32 `stream.write_some` with consecutive portions of data from `buffers`
33 until:
34
35 @li either the full content of @c buffers is processed,
36 @li or a contingency in `stream.write_some` occurs.
37
38 If `buffer_size(buffers) == 0` then no awaiting `stream.write_some`
39 is performed. This is not a contingency.
40
41
42 @par Await-returns
43
44 An object of type `results<std::size_t>` destructuring as `[ec, n]`.
45
46 Upon a contingency, `n` represents the number of bytes written
47 so far.
48
49 Otherwise `n` represents the number of bytes written.
50
51 Contingencies:
52
53 @li The first contingency reported from awaiting @c stream.write_some
54 while not all bytes have been written. A contingency that accompanies
55 the write which transfers the last bytes is not reported: a completed
56 transfer is a success.
57
58 Notable conditions:
59
60 @li @c cond::canceled — Operation was cancelled,
61 @li @c std::errc::broken_pipe — Peer closed connection.
62
63
64 @par Await-postcondition
65
66 If `n == buffer_size(buffers)` the transfer completed and `ec` is
67 success; otherwise `ec` is set.
68
69
70 @param stream The stream to write to. If the lifetime of `stream` ends
71 before the coroutine finishes, the behavior is undefined.
72
73 @param buffers The buffer sequence to write. If the lifetime of the buffer
74 sequence represented by `buffers` ends
75 before the coroutine finishes, the behavior is undefined.
76
77 @return A task yielding `results<std::size_t>` whose second element
78 is the number of bytes written.
79
80 @par Remarks
81
82 Supports _ContextAwaitable cancellation_.
83
84 @par Example
85
86 @par !example example
87
88
89 @see WriteStream, ConstBufferSequence, ContextAwaitable, results, cond.
90 */
91 template <WriteStream S, ConstBufferSequence CB>
92 59x auto write(S& stream, CB buffers) -> task<results<std::size_t>>
93 {
94 consuming_buffers consuming(buffers);
95 std::size_t const total_size = buffer_size(buffers);
96 std::size_t total_written = 0;
97
98 while(total_written < total_size)
99 {
100 auto [ec, n] = co_await stream.write_some(consuming.data());
101 consuming.consume(n);
102 total_written += n;
103 // A contingency that still completed the transfer is a success:
104 // report it only when not all bytes were written.
105 if(ec && total_written < total_size)
106 co_return {ec, total_written};
107 }
108
109 co_return {std::error_code(), total_written};
110 118x }
111
112 } // namespace capy
113 } // namespace boost
114
115 #endif
116