LCOV - code coverage report
Current view: top level - boost/capy/io - push_to.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 4 4
Test Date: 2026-01-30 23:43:15 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, count] = co_await source.pull(arr, detail::max_iovec_);
      71              :         if(ec)
      72              :             co_return {ec, total};
      73              : 
      74              :         if(count == 0)
      75              :         {
      76              :             auto [eof_ec] = co_await sink.write_eof();
      77              :             co_return {eof_ec, total};
      78              :         }
      79              : 
      80              :         std::span<const_buffer const> bufs(arr, count);
      81              :         auto [write_ec, n] = co_await sink.write(bufs);
      82              :         total += n;
      83              :         source.consume(n);
      84              :         if(write_ec)
      85              :             co_return {write_ec, total};
      86              :     }
      87          280 : }
      88              : 
      89              : /** Transfer data from a BufferSource to a WriteStream.
      90              : 
      91              :     This function pulls data from the source and writes it to the
      92              :     stream until the source is exhausted or an error occurs. The
      93              :     stream uses `write_some()` which may perform partial writes,
      94              :     so this function loops until all pulled data is consumed.
      95              : 
      96              :     Unlike the WriteSink overload, this function does not signal
      97              :     EOF explicitly since WriteStream does not provide a write_eof
      98              :     method. The transfer completes when the source is exhausted.
      99              : 
     100              :     @tparam Src The source type, must satisfy @ref BufferSource.
     101              :     @tparam Stream The stream type, must satisfy @ref WriteStream.
     102              : 
     103              :     @param source The source to pull data from.
     104              :     @param stream The stream to write data to.
     105              : 
     106              :     @return A task that yields `(std::error_code, std::size_t)`.
     107              :         On success, `ec` is default-constructed (no error) and `n` is
     108              :         the total number of bytes transferred. On error, `ec` contains
     109              :         the error code and `n` is the total number of bytes transferred
     110              :         before the error.
     111              : 
     112              :     @par Example
     113              :     @code
     114              :     task<void> transfer_body(BufferSource auto& source, WriteStream auto& stream)
     115              :     {
     116              :         auto [ec, n] = co_await push_to(source, stream);
     117              :         if (ec)
     118              :         {
     119              :             // Handle error
     120              :         }
     121              :         // n bytes were transferred
     122              :     }
     123              :     @endcode
     124              : 
     125              :     @see BufferSource, WriteStream, pull_from
     126              : */
     127              : template<BufferSource Src, WriteStream Stream>
     128              : task<io_result<std::size_t>>
     129          104 : push_to(Src& source, Stream& stream)
     130              : {
     131              :     const_buffer arr[detail::max_iovec_];
     132              :     std::size_t total = 0;
     133              : 
     134              :     for(;;)
     135              :     {
     136              :         auto [ec, count] = co_await source.pull(arr, detail::max_iovec_);
     137              :         if(ec)
     138              :             co_return {ec, total};
     139              : 
     140              :         if(count == 0)
     141              :             co_return {{}, total};
     142              : 
     143              :         std::span<const_buffer const> bufs(arr, count);
     144              :         auto [write_ec, n] = co_await stream.write_some(bufs);
     145              :         if(write_ec)
     146              :             co_return {write_ec, total};
     147              : 
     148              :         total += n;
     149              :         source.consume(n);
     150              :     }
     151          208 : }
     152              : 
     153              : } // namespace capy
     154              : } // namespace boost
     155              : 
     156              : #endif
        

Generated by: LCOV version 2.3