GCC Code Coverage Report


Directory: ./
File: libs/buffers/include/boost/buffers/any_read_source.hpp
Date: 2025-12-06 02:12:43
Exec Total Coverage
Lines: 36 51 70.6%
Functions: 6 12 50.0%
Branches: 18 24 75.0%

Line Branch Exec Source
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 4 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 108 any_read_source::
55 read(
56 MutableBufferSequence const& dest,
57 system::error_code& ec)
58 {
59 108 std::size_t result = 0;
60 108 constexpr std::size_t N = 16;
61 108 std::size_t n = 0;
62 108 mutable_buffer mb[N];
63 108 auto it = buffers::begin(dest);
64 108 auto const end_ = buffers::end(dest);
65
2/2
✓ Branch 0 taken 354 times.
✓ Branch 1 taken 53 times.
814 while(it != end_)
66 {
67 708 mb[n++] = *it++;
68
2/2
✓ Branch 0 taken 338 times.
✓ Branch 1 taken 16 times.
708 if(n < N)
69 676 continue;
70
1/1
✓ Branch 1 taken 16 times.
32 auto const nread = do_read(mb, n, ec);
71
3/4
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15 times.
32 BOOST_ASSERT(
72 ec.failed() ||
73 nread == buffers::size(
74 span<mutable_buffer const>(mb, n)));
75 32 result += nread;
76
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 15 times.
32 if(ec.failed())
77 2 return result;
78 30 n = 0;
79 }
80
1/2
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
106 if(n > 0)
81 {
82
1/1
✓ Branch 1 taken 53 times.
106 auto const nread = do_read(mb, n, ec);
83
3/4
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 52 times.
106 BOOST_ASSERT(
84 ec.failed() ||
85 nread == buffers::size(
86 span<mutable_buffer const>(mb, n)));
87 106 result += nread;
88
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 52 times.
106 if(ec.failed())
89 2 return result;
90 }
91 104 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 bool has_size() const noexcept override
111 {
112 return buffers::has_size<Source>::value;
113 }
114
115 bool has_rewind() const noexcept override
116 {
117 return buffers::has_rewind<Source>::value;
118 }
119
120 std::uint64_t size() const override
121 {
122 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 std::uint64_t size(std::false_type) const
131 {
132 detail::throw_invalid_argument();
133 }
134
135 void rewind() override
136 {
137 rewind(buffers::has_rewind<Source>{});
138 }
139
140 void rewind(std::true_type)
141 {
142 ec_ = {};
143 source_.rewind();
144 }
145
146 void rewind(std::false_type) const
147 {
148 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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 69 times.
69 if(ec_.failed())
157 {
158 ec = ec_;
159 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
191