LCOV - code coverage report
Current view: top level - boost/buffers - any_read_source.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 70.6 % 51 36
Test Date: 2025-12-06 02:12:43 Functions: 46.2 % 13 6

            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/buffers
       8              : //
       9              : 
      10              : #ifndef BOOST_BUFFERS_ANY_READ_SOURCE_HPP
      11              : #define BOOST_BUFFERS_ANY_READ_SOURCE_HPP
      12              : 
      13              : #include <boost/buffers/detail/config.hpp>
      14              : #include <boost/buffers/error.hpp>
      15              : #include <boost/buffers/read_source.hpp>
      16              : #include <boost/core/span.hpp>
      17              : #include <boost/assert.hpp>
      18              : 
      19              : namespace boost {
      20              : namespace buffers {
      21              : 
      22              : /** Type-erased interface to a read source
      23              : */
      24              : class BOOST_SYMBOL_VISIBLE
      25              :     any_read_source
      26              : {
      27              : public:
      28            2 :     virtual ~any_read_source() = default;
      29              : 
      30              :     virtual bool has_size() const noexcept = 0;
      31              : 
      32              :     virtual bool has_rewind() const noexcept = 0;
      33              : 
      34              :     virtual std::uint64_t size() const = 0;
      35              : 
      36              :     virtual void rewind() = 0;
      37              : 
      38              :     template<class MutableBufferSequence>
      39              :     std::size_t read(
      40              :         MutableBufferSequence const& dest,
      41              :         system::error_code& ec);
      42              : 
      43              : private:
      44              :     virtual std::size_t do_read(
      45              :         mutable_buffer const* p,
      46              :         std::size_t n,
      47              :         system::error_code& ec) = 0;
      48              : };
      49              : 
      50              : //-----------------------------------------------
      51              : 
      52              : template<class MutableBufferSequence>
      53              : std::size_t
      54           54 : any_read_source::
      55              : read(
      56              :     MutableBufferSequence const& dest,
      57              :     system::error_code& ec)
      58              : {
      59           54 :     std::size_t result = 0;
      60           54 :     constexpr std::size_t N = 16;
      61           54 :     std::size_t n = 0;
      62           54 :     mutable_buffer mb[N];
      63           54 :     auto it = buffers::begin(dest);
      64           54 :     auto const end_ = buffers::end(dest);
      65          407 :     while(it != end_)
      66              :     {
      67          354 :         mb[n++] = *it++;
      68          354 :         if(n < N)
      69          338 :             continue;
      70           16 :         auto const nread = do_read(mb, n, ec);
      71           16 :         BOOST_ASSERT(
      72              :             ec.failed() ||
      73              :             nread == buffers::size(
      74              :                 span<mutable_buffer const>(mb, n)));
      75           16 :         result += nread;
      76           16 :         if(ec.failed())
      77            1 :             return result;
      78           15 :         n = 0;
      79              :     }
      80           53 :     if(n > 0)
      81              :     {
      82           53 :         auto const nread = do_read(mb, n, ec);
      83           53 :         BOOST_ASSERT(
      84              :             ec.failed() ||
      85              :             nread == buffers::size(
      86              :                 span<mutable_buffer const>(mb, n)));
      87           53 :         result += nread;
      88           53 :         if(ec.failed())
      89            1 :             return result;
      90              :     }
      91           52 :     return result;
      92              : }
      93              : 
      94              : //-----------------------------------------------
      95              : 
      96              : namespace detail {
      97              : 
      98              : template<class Source>
      99              : class read_source_impl : public any_read_source
     100              : {
     101              : public:
     102              :     template<class Source_>
     103            2 :     explicit read_source_impl(
     104              :         Source_&& source) noexcept
     105            2 :         : source_(std::forward<Source_>(source))
     106              :     {
     107            2 :     }
     108              : 
     109              : private:
     110            0 :     bool has_size() const noexcept override
     111              :     {
     112            0 :         return buffers::has_size<Source>::value;
     113              :     }
     114              : 
     115            0 :     bool has_rewind() const noexcept override
     116              :     {
     117            0 :         return buffers::has_rewind<Source>::value;
     118              :     }
     119              : 
     120            0 :     std::uint64_t size() const override
     121              :     {
     122            0 :         return size(buffers::has_size<Source>{});
     123              :     }
     124              : 
     125              :     std::uint64_t size(std::true_type) const
     126              :     {
     127              :         return source_.size();
     128              :     }
     129              : 
     130            0 :     std::uint64_t size(std::false_type) const
     131              :     {
     132            0 :         detail::throw_invalid_argument();
     133              :     }
     134              : 
     135            0 :     void rewind() override
     136              :     {
     137            0 :         rewind(buffers::has_rewind<Source>{});
     138            0 :     }
     139              : 
     140              :     void rewind(std::true_type)
     141              :     {
     142              :         ec_ = {};
     143              :         source_.rewind();
     144              :     }
     145              : 
     146            0 :     void rewind(std::false_type) const
     147              :     {
     148            0 :         detail::throw_invalid_argument();
     149              :     }
     150              : 
     151           69 :     std::size_t do_read(
     152              :         mutable_buffer const* p,
     153              :         std::size_t n,
     154              :         system::error_code& ec) override
     155              :     {
     156           69 :         if(ec_.failed())
     157              :         {
     158            0 :             ec = ec_;
     159            0 :             return 0;
     160              :         }
     161           69 :         auto const nread = source_.read(
     162           69 :             span<mutable_buffer const>(p, n), ec);
     163           69 :         ec_ = ec;
     164           69 :         return nread;
     165              :     }
     166              : 
     167              :     Source source_;
     168              :     system::error_code ec_;
     169              : };
     170              : 
     171              : } // detail
     172              : 
     173              : //-----------------------------------------------
     174              : 
     175              : template<class ReadSource>
     176              : auto
     177            2 : make_any_read_source(
     178              :     ReadSource&& source) ->
     179              :         detail::read_source_impl<typename
     180              :             std::decay<ReadSource>::type>
     181              : {
     182              :     return detail::read_source_impl<typename
     183              :         std::decay<ReadSource>::type>(
     184            2 :             std::forward<ReadSource>(source));
     185              : }
     186              : 
     187              : } // buffers
     188              : } // boost
     189              : 
     190              : #endif
        

Generated by: LCOV version 2.1