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/buffer_slice.hpp> 16   #include <boost/capy/buffers/buffer_slice.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 - /** Write an entire buffer sequence to a stream. 25 + /** Asynchronously write the entire buffer sequence.
26 -  
27 - @par Await-effects  
28 -  
29 - Writes the contents of `buffers` to `stream` via awaiting on  
30 - `stream.write_some` with consecutive portions of data from `buffers`  
31 - until:  
32 -  
33 - @li either the full content of @c buffers is processed,  
34 - @li or a contingency occurs.  
35 -  
36 - If `buffer_size(buffers) == 0` then no awaiting on `stream.write_some`  
37 - is performed. This is not a contingency.  
38 -  
39 -  
40 - @par Await-returns  
41 -  
42 - An object of type `io_result<std::size_t>` destructuring as `[ec, n]`.  
43 -  
44 - Upon a contingency, `n` represents the number of bytes written  
45 - so far.  
46 -  
47 - Otherwise `n` represents the number of bytes written.  
48 -  
49 - Contingencies:  
50 -  
51 - @li The first contingency reported from  
52 - awaiting on @c stream.write_some .  
53 -  
54 - Notable conditions:  
55 -  
56 - @li @c cond::canceled — Operation was cancelled,  
57 - @li @c std::errc::broken_pipe — Peer closed connection.  
58 -  
59 -  
60 - @par Await-postcondition  
61   26  
62 - `ec || n == buffer_size(buffers)`. 27 + Writes data to the stream by calling `write_some` repeatedly
  28 + until the entire buffer sequence is written or an error occurs.
63   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
64   34  
65   @par Cancellation 35   @par Cancellation
66   Supports cancellation via `stop_token` propagated through the 36   Supports cancellation via `stop_token` propagated through the
67 - `IoAwaitable` protocol. When cancelled, returns with `cond::canceled`. 37 + IoAwaitable protocol. When cancelled, returns with `cond::canceled`.
68 -  
69 - @param stream The stream to write to. If the lifetime of `stream` ends  
70 - before the coroutine finishes, the behavior is undefined.  
71   38  
72 - @param buffers The buffer sequence to write. If the lifetime of the buffer 39 + @param stream The stream to write to. The caller retains ownership.
73 - sequence represented by `buffers` ends 40 + @param buffers The buffer sequence to write. The caller retains
74 - before the coroutine finishes, the behavior is undefined. 41 + ownership and must ensure validity until the operation completes.
75   42  
  43 + @return An awaitable that await-returns `(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
76   49  
77   @par Example 50   @par Example
78   51  
79   @code 52   @code
80 - capy::task<> send_response(capy::WriteStream auto& stream, std::string_view body) 53 + task<> send_response( WriteStream auto& stream, std::string_view body )
81   { 54   {
82 - auto [ec, n] = co_await capy::write(stream, capy::make_buffer(body)); 55 + auto [ec, n] = co_await write( stream, make_buffer( body ) );
83 - if (ec) 56 + if( ec )
84 - throw std::system_error(ec); 57 + detail::throw_system_error( ec );
85 -  
86   // All bytes written successfully 58   // All bytes written successfully
87   } 59   }
88   @endcode 60   @endcode
89   61  
90 - @return 62 + @see write_some, WriteStream, ConstBufferSequence
91 -  
92 - @see WriteStream, ConstBufferSequence, IoAwaitable, io_result, cond.  
93   */ 63   */
94 - template <WriteStream S, ConstBufferSequence CB> 64 + auto
HITCBC 95 - 50 auto write(S& stream, CB buffers) -> io_task<std::size_t> 65 + 50 write(
  66 + WriteStream auto& stream,
  67 + ConstBufferSequence auto buffers) ->
  68 + io_task<std::size_t>
96   { 69   {
97   auto consuming = buffer_slice(buffers); 70   auto consuming = buffer_slice(buffers);
98   std::size_t const total_size = buffer_size(buffers); 71   std::size_t const total_size = buffer_size(buffers);
99   std::size_t total_written = 0; 72   std::size_t total_written = 0;
100   73  
101   while(total_written < total_size) 74   while(total_written < total_size)
102   { 75   {
103   auto [ec, n] = co_await stream.write_some(consuming.data()); 76   auto [ec, n] = co_await stream.write_some(consuming.data());
104   consuming.remove_prefix(n); 77   consuming.remove_prefix(n);
105   total_written += n; 78   total_written += n;
106   if(ec) 79   if(ec)
107   co_return {ec, total_written}; 80   co_return {ec, total_written};
108   } 81   }
109   82  
110   co_return {{}, total_written}; 83   co_return {{}, total_written};
HITCBC 111   100 } 84   100 }
112   85  
113   } // namespace capy 86   } // namespace capy
114   } // namespace boost 87   } // namespace boost
115   88  
116   #endif 89   #endif