GCC Code Coverage Report


Directory: ./
File: libs/http_proto/include/boost/http_proto/impl/serializer.hpp
Date: 2025-12-22 14:47:58
Exec Total Coverage
Lines: 35 35 100.0%
Functions: 15 26 57.7%
Branches: 12 17 70.6%

Line Branch Exec Source
1 //
2 // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2025 Mohammad Nejati
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/http_proto
9 //
10
11 #ifndef BOOST_HTTP_PROTO_IMPL_SERIALIZER_HPP
12 #define BOOST_HTTP_PROTO_IMPL_SERIALIZER_HPP
13
14 #include <boost/http_proto/detail/except.hpp>
15
16 namespace boost {
17 namespace http_proto {
18
19 class serializer::cbs_gen
20 {
21 public:
22 struct stats_t
23 {
24 std::size_t size = 0;
25 std::size_t count = 0;
26 };
27
28 // Return the next non-empty buffer or an
29 // empty buffer if none remain.
30 virtual
31 buffers::const_buffer
32 next() = 0;
33
34 // Return the total size and count of
35 // remaining non-empty buffers.
36 virtual
37 stats_t
38 stats() const = 0;
39
40 // Return true if there are no remaining
41 // non-empty buffers.
42 virtual
43 bool
44 is_empty() const = 0;
45 };
46
47 template<class ConstBufferSequence>
48 class serializer::cbs_gen_impl
49 : public cbs_gen
50 {
51 using it_t = decltype(buffers::begin(
52 std::declval<ConstBufferSequence>()));
53
54 ConstBufferSequence cbs_;
55 it_t curr_;
56
57 public:
58 using const_buffer =
59 buffers::const_buffer;
60
61 explicit
62 32 cbs_gen_impl(ConstBufferSequence cbs)
63 48 : cbs_(std::move(cbs))
64 48 , curr_(buffers::begin(cbs_))
65 {
66 32 }
67
68 const_buffer
69 2104 next() override
70 {
71
3/3
✓ Branch 2 taken 1998 times.
✓ Branch 3 taken 16 times.
✓ Branch 1 taken 46 times.
2108 while(curr_ != buffers::end(cbs_))
72 {
73 // triggers conversion operator
74 2088 const_buffer buf = *curr_++;
75
2/2
✓ Branch 1 taken 2038 times.
✓ Branch 2 taken 4 times.
2088 if(buf.size() != 0)
76 2084 return buf;
77 }
78 20 return {};
79 }
80
81 stats_t
82 16 stats() const override
83 {
84 16 stats_t r;
85
2/4
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 1 taken 96 times.
✓ Branch 2 taken 8 times.
208 for(auto it = curr_; it != buffers::end(cbs_); ++it)
86 {
87 // triggers conversion operator
88 192 const_buffer buf = *it;
89
2/2
✓ Branch 1 taken 46 times.
✓ Branch 2 taken 50 times.
192 if(buf.size() != 0)
90 {
91 92 r.size += buf.size();
92 92 r.count += 1;
93 }
94 }
95 16 return r;
96 }
97
98 bool
99 8 is_empty() const override
100 {
101
2/4
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
8 for(auto it = curr_; it != buffers::end(cbs_); ++it)
102 {
103 // triggers conversion operator
104 4 const_buffer buf = *it;
105
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 if(buf.size() != 0)
106 4 return false;
107 }
108 4 return true;
109 }
110 };
111
112 //---------------------------------------------------------
113
114 template<
115 class ConstBufferSequence,
116 class>
117 void
118 32 serializer::
119 start(
120 message_base const& m,
121 ConstBufferSequence&& cbs)
122 {
123 static_assert(buffers::is_const_buffer_sequence<
124 ConstBufferSequence>::value,
125 "ConstBufferSequence type requirements not met");
126
127 32 set_headers(m);
128 32 start_buffers_impl(
129 32 ws().emplace<cbs_gen_impl<typename
130 32 std::decay<ConstBufferSequence>::type>>(
131 std::forward<ConstBufferSequence>(cbs)));
132 32 }
133
134 template<
135 class ConstBufferSequence,
136 class>
137 void
138 serializer::
139 start(
140 ConstBufferSequence&& cbs)
141 {
142 static_assert(buffers::is_const_buffer_sequence<
143 ConstBufferSequence>::value,
144 "ConstBufferSequence type requirements not met");
145
146 start_buffers_impl(
147 ws().emplace<cbs_gen_impl<typename
148 std::decay<ConstBufferSequence>::type>>(
149 std::forward<ConstBufferSequence>(cbs)));
150 }
151
152 template<
153 class Source,
154 class... Args,
155 class>
156 Source&
157 25 serializer::
158 start(
159 message_base const& m,
160 Args&&... args)
161 {
162 static_assert(
163 !std::is_abstract<Source>::value, "");
164 static_assert(
165 std::is_constructible<Source, Args...>::value ||
166 std::is_constructible<Source, detail::workspace&, Args...>::value,
167 "The Source cannot be constructed with the given arguments");
168
169 25 set_headers(m);
170 25 auto& source = ws().emplace<Source>(
171 std::forward<Args>(args)...);
172 25 start_source_impl(source);
173 25 return source;
174 }
175
176 template<
177 class Source,
178 class Arg0,
179 class... Args,
180 class>
181 Source&
182 serializer::
183 start(
184 Arg0&& arg0,
185 Args&&... args)
186 {
187 static_assert(
188 !std::is_abstract<Source>::value, "");
189 static_assert(
190 std::is_constructible<Source, Arg0, Args...>::value ||
191 std::is_constructible<Source, detail::workspace&, Arg0, Args...>::value,
192 "The Source cannot be constructed with the given arguments");
193
194 auto& source = ws().emplace<Source>(
195 std::forward<Arg0>(arg0),
196 std::forward<Args>(args)...);
197 start_source_impl(source);
198 return source;
199 }
200
201 template<
202 class Source,
203 class>
204 Source&
205 serializer::
206 start()
207 {
208 static_assert(
209 !std::is_abstract<Source>::value, "");
210 static_assert(
211 std::is_default_constructible<Source>::value ||
212 std::is_constructible<Source, detail::workspace&>::value,
213 "The Source cannot be default-constructed");
214
215 auto& source = ws().emplace<Source>();
216 start_source_impl(source);
217 return source;
218 }
219
220 } // http_proto
221 } // boost
222
223 #endif
224