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_WRITE_HPP
11 : #define BOOST_CAPY_WRITE_HPP
12 :
13 : #include <boost/capy/detail/config.hpp>
14 : #include <boost/capy/io_task.hpp>
15 : #include <boost/capy/buffers.hpp>
16 : #include <boost/capy/buffers/consuming_buffers.hpp>
17 : #include <boost/capy/concept/write_stream.hpp>
18 : #include <system_error>
19 :
20 : #include <cstddef>
21 :
22 : namespace boost {
23 : namespace capy {
24 :
25 : /** Asynchronously write the entire buffer sequence.
26 :
27 : Writes data to the stream by calling `write_some` repeatedly
28 : until the entire buffer sequence is written or an error occurs.
29 :
30 : @li The operation completes when:
31 : @li The entire buffer sequence has been written
32 : @li An error occurs
33 : @li The operation is cancelled
34 :
35 : @par Cancellation
36 : Supports cancellation via `stop_token` propagated through the
37 : IoAwaitable protocol. When cancelled, returns with `cond::canceled`.
38 :
39 : @param stream The stream to write to. The caller retains ownership.
40 : @param buffers The buffer sequence to write. The caller retains
41 : ownership and must ensure validity until the operation completes.
42 :
43 : @return An awaitable yielding `(error_code, std::size_t)`.
44 : On success, `n` equals `buffer_size(buffers)`. On error,
45 : `n` is the number of bytes written before the error. Compare
46 : error codes to conditions:
47 : @li `cond::canceled` - Operation was cancelled
48 : @li `std::errc::broken_pipe` - Peer closed connection
49 :
50 : @par Example
51 :
52 : @code
53 : task<> send_response( WriteStream auto& stream, std::string_view body )
54 : {
55 : auto [ec, n] = co_await write( stream, make_buffer( body ) );
56 : if( ec )
57 : detail::throw_system_error( ec );
58 : // All bytes written successfully
59 : }
60 : @endcode
61 :
62 : @see write_some, WriteStream, ConstBufferSequence
63 : */
64 : auto
65 44 : write(
66 : WriteStream auto& stream,
67 : ConstBufferSequence auto const& buffers) ->
68 : io_task<std::size_t>
69 : {
70 : consuming_buffers consuming(buffers);
71 : std::size_t const total_size = buffer_size(buffers);
72 : std::size_t total_written = 0;
73 :
74 : while(total_written < total_size)
75 : {
76 : auto [ec, n] = co_await stream.write_some(consuming);
77 : if(ec)
78 : co_return {ec, total_written};
79 : consuming.consume(n);
80 : total_written += n;
81 : }
82 :
83 : co_return {{}, total_written};
84 88 : }
85 :
86 : } // namespace capy
87 : } // namespace boost
88 :
89 : #endif
|