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