LCOV - code coverage report
Current view: top level - capy/io - push_to.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 4 4
Test Date: 2026-02-17 18:14:47 Functions: 100.0 % 3 3

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.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_IO_PUSH_TO_HPP
      11                 : #define BOOST_CAPY_IO_PUSH_TO_HPP
      12                 : 
      13                 : #include <boost/capy/detail/config.hpp>
      14                 : #include <boost/capy/buffers.hpp>
      15                 : #include <boost/capy/cond.hpp>
      16                 : #include <boost/capy/concept/buffer_source.hpp>
      17                 : #include <boost/capy/concept/write_sink.hpp>
      18                 : #include <boost/capy/concept/write_stream.hpp>
      19                 : #include <boost/capy/io_task.hpp>
      20                 : 
      21                 : #include <cstddef>
      22                 : #include <span>
      23                 : 
      24                 : namespace boost {
      25                 : namespace capy {
      26                 : 
      27                 : /** Transfer data from a BufferSource to a WriteSink.
      28                 : 
      29                 :     This function pulls data from the source and writes it to the
      30                 :     sink until the source is exhausted or an error occurs. When
      31                 :     the source signals completion, `write_eof()` is called on the
      32                 :     sink to finalize the transfer.
      33                 : 
      34                 :     @tparam Src The source type, must satisfy @ref BufferSource.
      35                 :     @tparam Sink The sink type, must satisfy @ref WriteSink.
      36                 : 
      37                 :     @param source The source to pull data from.
      38                 :     @param sink The sink to write data to.
      39                 : 
      40                 :     @return A task that yields `(std::error_code, std::size_t)`.
      41                 :         On success, `ec` is default-constructed (no error) and `n` is
      42                 :         the total number of bytes transferred. On error, `ec` contains
      43                 :         the error code and `n` is the total number of bytes transferred
      44                 :         before the error.
      45                 : 
      46                 :     @par Example
      47                 :     @code
      48                 :     task<void> transfer_body(BufferSource auto& source, WriteSink auto& sink)
      49                 :     {
      50                 :         auto [ec, n] = co_await push_to(source, sink);
      51                 :         if (ec)
      52                 :         {
      53                 :             // Handle error
      54                 :         }
      55                 :         // n bytes were transferred
      56                 :     }
      57                 :     @endcode
      58                 : 
      59                 :     @see BufferSource, WriteSink
      60                 : */
      61                 : template<BufferSource Src, WriteSink Sink>
      62                 : io_task<std::size_t>
      63 HIT         140 : push_to(Src& source, Sink& sink)
      64                 : {
      65                 :     const_buffer arr[detail::max_iovec_];
      66                 :     std::size_t total = 0;
      67                 : 
      68                 :     for(;;)
      69                 :     {
      70                 :         auto [ec, bufs] = co_await source.pull(arr);
      71                 :         if(ec == cond::eof)
      72                 :         {
      73                 :             auto [eof_ec] = co_await sink.write_eof();
      74                 :             co_return {eof_ec, total};
      75                 :         }
      76                 :         if(ec)
      77                 :             co_return {ec, total};
      78                 : 
      79                 :         auto [write_ec, n] = co_await sink.write(bufs);
      80                 :         total += n;
      81                 :         source.consume(n);
      82                 :         if(write_ec)
      83                 :             co_return {write_ec, total};
      84                 :     }
      85             280 : }
      86                 : 
      87                 : /** Transfer data from a BufferSource to a WriteStream.
      88                 : 
      89                 :     This function pulls data from the source and writes it to the
      90                 :     stream until the source is exhausted or an error occurs. The
      91                 :     stream uses `write_some()` which may perform partial writes,
      92                 :     so this function loops until all pulled data is consumed.
      93                 : 
      94                 :     Unlike the WriteSink overload, this function does not signal
      95                 :     EOF explicitly since WriteStream does not provide a write_eof
      96                 :     method. The transfer completes when the source is exhausted.
      97                 : 
      98                 :     @tparam Src The source type, must satisfy @ref BufferSource.
      99                 :     @tparam Stream The stream type, must satisfy @ref WriteStream.
     100                 : 
     101                 :     @param source The source to pull data from.
     102                 :     @param stream The stream to write data to.
     103                 : 
     104                 :     @return A task that yields `(std::error_code, std::size_t)`.
     105                 :         On success, `ec` is default-constructed (no error) and `n` is
     106                 :         the total number of bytes transferred. On error, `ec` contains
     107                 :         the error code and `n` is the total number of bytes transferred
     108                 :         before the error.
     109                 : 
     110                 :     @par Example
     111                 :     @code
     112                 :     task<void> transfer_body(BufferSource auto& source, WriteStream auto& stream)
     113                 :     {
     114                 :         auto [ec, n] = co_await push_to(source, stream);
     115                 :         if (ec)
     116                 :         {
     117                 :             // Handle error
     118                 :         }
     119                 :         // n bytes were transferred
     120                 :     }
     121                 :     @endcode
     122                 : 
     123                 :     @see BufferSource, WriteStream, pull_from
     124                 : */
     125                 : template<BufferSource Src, WriteStream Stream>
     126                 :     requires (!WriteSink<Stream>)
     127                 : io_task<std::size_t>
     128             104 : push_to(Src& source, Stream& stream)
     129                 : {
     130                 :     const_buffer arr[detail::max_iovec_];
     131                 :     std::size_t total = 0;
     132                 : 
     133                 :     for(;;)
     134                 :     {
     135                 :         auto [ec, bufs] = co_await source.pull(arr);
     136                 :         if(ec == cond::eof)
     137                 :             co_return {{}, total};
     138                 :         if(ec)
     139                 :             co_return {ec, total};
     140                 : 
     141                 :         auto [write_ec, n] = co_await stream.write_some(bufs);
     142                 :         if(write_ec)
     143                 :             co_return {write_ec, total};
     144                 : 
     145                 :         total += n;
     146                 :         source.consume(n);
     147                 :     }
     148             208 : }
     149                 : 
     150                 : } // namespace capy
     151                 : } // namespace boost
     152                 : 
     153                 : #endif
        

Generated by: LCOV version 2.3