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