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