LCOV - code coverage report
Current view: top level - capy/io - push_to.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 4 4
Test Date: 2026-02-02 05:00:52 Functions: 100.0 % 3 3

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot 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/concept/buffer_source.hpp>
      16              : #include <boost/capy/concept/write_sink.hpp>
      17              : #include <boost/capy/concept/write_stream.hpp>
      18              : #include <boost/capy/io_result.hpp>
      19              : #include <boost/capy/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              : task<io_result<std::size_t>>
      63          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)
      72              :             co_return {ec, total};
      73              : 
      74              :         if(bufs.empty())
      75              :         {
      76              :             auto [eof_ec] = co_await sink.write_eof();
      77              :             co_return {eof_ec, total};
      78              :         }
      79              : 
      80              :         auto [write_ec, n] = co_await sink.write(bufs);
      81              :         total += n;
      82              :         source.consume(n);
      83              :         if(write_ec)
      84              :             co_return {write_ec, total};
      85              :     }
      86          280 : }
      87              : 
      88              : /** Transfer data from a BufferSource to a WriteStream.
      89              : 
      90              :     This function pulls data from the source and writes it to the
      91              :     stream until the source is exhausted or an error occurs. The
      92              :     stream uses `write_some()` which may perform partial writes,
      93              :     so this function loops until all pulled data is consumed.
      94              : 
      95              :     Unlike the WriteSink overload, this function does not signal
      96              :     EOF explicitly since WriteStream does not provide a write_eof
      97              :     method. The transfer completes when the source is exhausted.
      98              : 
      99              :     @tparam Src The source type, must satisfy @ref BufferSource.
     100              :     @tparam Stream The stream type, must satisfy @ref WriteStream.
     101              : 
     102              :     @param source The source to pull data from.
     103              :     @param stream The stream to write data to.
     104              : 
     105              :     @return A task that yields `(std::error_code, std::size_t)`.
     106              :         On success, `ec` is default-constructed (no error) and `n` is
     107              :         the total number of bytes transferred. On error, `ec` contains
     108              :         the error code and `n` is the total number of bytes transferred
     109              :         before the error.
     110              : 
     111              :     @par Example
     112              :     @code
     113              :     task<void> transfer_body(BufferSource auto& source, WriteStream auto& stream)
     114              :     {
     115              :         auto [ec, n] = co_await push_to(source, stream);
     116              :         if (ec)
     117              :         {
     118              :             // Handle error
     119              :         }
     120              :         // n bytes were transferred
     121              :     }
     122              :     @endcode
     123              : 
     124              :     @see BufferSource, WriteStream, pull_from
     125              : */
     126              : template<BufferSource Src, WriteStream Stream>
     127              : task<io_result<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)
     137              :             co_return {ec, total};
     138              : 
     139              :         if(bufs.empty())
     140              :             co_return {{}, total};
     141              : 
     142              :         auto [write_ec, n] = co_await stream.write_some(bufs);
     143              :         if(write_ec)
     144              :             co_return {write_ec, total};
     145              : 
     146              :         total += n;
     147              :         source.consume(n);
     148              :     }
     149          208 : }
     150              : 
     151              : } // namespace capy
     152              : } // namespace boost
     153              : 
     154              : #endif
        

Generated by: LCOV version 2.3