GCC Code Coverage Report


Directory: libs/url/
File: src/detail/any_params_iter.cpp
Date: 2025-11-10 19:06:22
Exec Total Coverage
Lines: 167 168 99.4%
Functions: 24 24 100.0%
Branches: 45 52 86.5%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/boostorg/url
8 //
9
10
11 #include <boost/url/detail/config.hpp>
12 #include <boost/url/detail/any_params_iter.hpp>
13 #include <boost/url/encode.hpp>
14 #include <boost/core/detail/string_view.hpp>
15 #include "../rfc/detail/charsets.hpp"
16
17 namespace boost {
18 namespace urls {
19 namespace detail {
20
21 /*
22 When a string is transformed into a range of
23 params, the empty string becomes ambiguous:
24 it can be an empty range, or a range with
25 one param. The value `not_empty` is used on
26 construction to inform the transformation
27 that the empty string should be treated as
28 a one-element range. This simplifies
29 edit_params().
30 */
31
32 //------------------------------------------------
33 //
34 // any_params_iter
35 //
36 //------------------------------------------------
37
38 286 any_params_iter::
39 ~any_params_iter() noexcept = default;
40
41 //------------------------------------------------
42 //
43 // query_iter
44 //
45 //------------------------------------------------
46
47 32 query_string_iter::
48 query_string_iter(
49 core::string_view s,
50 32 bool ne) noexcept
51 : any_params_iter(
52
4/4
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 22 times.
✓ Branch 5 taken 3 times.
32 s.empty() && ! ne, s)
53 {
54 32 rewind();
55 32 }
56
57 void
58 42 query_string_iter::
59 rewind() noexcept
60 {
61
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 20 times.
42 if(empty)
62 {
63 22 at_end_ = true;
64 22 return;
65 }
66 20 p_ = s0.begin();
67
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 6 times.
20 if(! s0.empty())
68 {
69 auto pos =
70 14 s0.find_first_of('&');
71
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
14 if(pos != core::string_view::npos)
72 2 n_ = pos;
73 else
74 12 n_ = s0.size();
75 }
76 else
77 {
78 6 n_ = 0;
79 }
80 20 at_end_ = false;
81 }
82
83 bool
84 43 query_string_iter::
85 measure(
86 std::size_t& n) noexcept
87 {
88
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 11 times.
43 if(at_end_)
89 32 return false;
90 // When interacting with the query as
91 // an intact string, we do not treat
92 // the plus sign as an encoded space.
93 11 encoding_opts opt;
94 11 opt.space_as_plus = false;
95 11 n += encoded_size(
96 core::string_view(p_, n_),
97 query_chars,
98 opt);
99 11 increment();
100 11 return true;
101 }
102
103 void
104 11 query_string_iter::
105 copy(
106 char*& dest,
107 char const* end) noexcept
108 {
109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 BOOST_ASSERT(! at_end_);
110 // When interacting with the query as
111 // an intact string, we do not treat
112 // the plus sign as an encoded space.
113 11 encoding_opts opt;
114 11 opt.space_as_plus = false;
115 11 dest += encode_unsafe(
116 dest,
117 11 end - dest,
118 core::string_view(p_, n_),
119 query_chars,
120 opt);
121 11 increment();
122 11 }
123
124 void
125 22 query_string_iter::
126 increment() noexcept
127 {
128 22 p_ += n_;
129
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 2 times.
22 if(p_ == s0.end())
130 {
131 20 at_end_ = true;
132 20 return;
133 }
134 2 ++p_;
135 2 core::string_view s(p_, s0.end() - p_);
136 2 auto pos = s.find_first_of('&');
137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(pos != core::string_view::npos)
138 n_ = pos;
139 else
140 2 n_ = s.size();
141 }
142
143 //------------------------------------------------
144 //
145 // param_iter
146 //
147 //------------------------------------------------
148
149 21 single_param_iter::
150 single_param_iter(
151 param_view const& p,
152 21 bool space_as_plus) noexcept
153 : any_params_iter(
154 false,
155 p.key,
156 p.value)
157 21 , has_value_(p.has_value)
158 21 , space_as_plus_(space_as_plus)
159 {
160 21 }
161
162 void
163 21 single_param_iter::
164 rewind() noexcept
165 {
166 21 at_end_ = false;
167 21 }
168
169 bool
170 42 single_param_iter::
171 measure(std::size_t& n) noexcept
172 {
173
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 21 times.
42 if(at_end_)
174 21 return false;
175 21 encoding_opts opt;
176 21 opt.space_as_plus = space_as_plus_;
177 21 n += encoded_size(
178 s0,
179 detail::param_key_chars,
180 opt);
181
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 if(has_value_)
182 {
183 21 ++n; // '='
184 21 n += encoded_size(
185 s1,
186 detail::param_value_chars,
187 opt);
188 }
189 21 at_end_ = true;
190 21 return true;
191 }
192
193 void
194 21 single_param_iter::
195 copy(
196 char*& dest,
197 char const* end) noexcept
198 {
199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 BOOST_ASSERT(! at_end_);
200 21 encoding_opts opt;
201 21 opt.space_as_plus = space_as_plus_;
202 42 dest += encode(
203 dest,
204 21 end - dest,
205 s0,
206 detail::param_key_chars,
207 opt);
208
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 if (has_value_)
209 {
210 21 *dest++ = '=';
211 21 dest += encode(
212 dest,
213 21 end - dest,
214 s1,
215 detail::param_value_chars,
216 opt);
217 }
218 21 }
219
220 //------------------------------------------------
221 //
222 // params_iter_base
223 //
224 //------------------------------------------------
225
226 void
227 70 params_iter_base::
228 measure_impl(
229 std::size_t& n,
230 param_view const& p) noexcept
231 {
232 70 encoding_opts opt;
233 70 opt.space_as_plus = space_as_plus_;
234 70 n += encoded_size(
235 p.key,
236 detail::param_key_chars,
237 opt);
238
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 12 times.
70 if(p.has_value)
239 {
240 58 ++n; // '='
241 58 n += encoded_size(
242 p.value,
243 detail::param_value_chars,
244 opt);
245 }
246 70 }
247
248 void
249 70 params_iter_base::
250 copy_impl(
251 char*& dest,
252 char const* end,
253 param_view const& p) noexcept
254 {
255 70 encoding_opts opt;
256 70 opt.space_as_plus = space_as_plus_;
257 140 dest += encode(
258 dest,
259 70 end - dest,
260 p.key,
261 detail::param_key_chars,
262 opt);
263
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 12 times.
70 if(p.has_value)
264 {
265 58 *dest++ = '=';
266 58 dest += encode(
267 dest,
268 58 end - dest,
269 p.value,
270 detail::param_value_chars,
271 opt);
272 }
273 70 }
274
275 //------------------------------------------------
276 //
277 // param_encoded_iter
278 //
279 //------------------------------------------------
280
281 12 param_encoded_iter::
282 param_encoded_iter(
283 12 param_pct_view const& p) noexcept
284 : any_params_iter(
285 false,
286 p.key,
287 p.value)
288 12 , has_value_(p.has_value)
289 {
290 12 }
291
292 void
293 12 param_encoded_iter::
294 rewind() noexcept
295 {
296 12 at_end_ = false;
297 12 }
298
299 bool
300 24 param_encoded_iter::
301 measure(std::size_t& n) noexcept
302 {
303
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 if(at_end_)
304 12 return false;
305 12 n += detail::re_encoded_size_unsafe(
306 s0,
307 detail::param_key_chars);
308
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(has_value_)
309 12 n += detail::re_encoded_size_unsafe(
310 s1,
311 12 detail::param_value_chars) + 1; // for '='
312 12 at_end_ = true;
313 12 return true;
314 }
315
316 void
317 12 param_encoded_iter::
318 copy(
319 char*& dest,
320 char const* end) noexcept
321 {
322 12 detail::re_encode_unsafe(
323 dest,
324 end,
325 s0,
326 detail::param_key_chars);
327
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(has_value_)
328 {
329 12 *dest++ = '=';
330 12 detail::re_encode_unsafe(
331 dest,
332 end,
333 s1,
334 detail::param_value_chars);
335 }
336 12 }
337
338
339 //------------------------------------------------
340 //
341 // params_encoded_iter_base
342 //
343 //------------------------------------------------
344
345 void
346 51 params_encoded_iter_base::
347 measure_impl(
348 std::size_t& n,
349 param_view const& p) noexcept
350 {
351 51 n += detail::re_encoded_size_unsafe(
352 p.key,
353 detail::param_key_chars);
354
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 9 times.
51 if(p.has_value)
355 42 n += detail::re_encoded_size_unsafe(
356 p.value,
357 42 detail::param_value_chars) + 1; // for '='
358 51 }
359
360 void
361 51 params_encoded_iter_base::
362 copy_impl(
363 char*& dest,
364 char const* end,
365 param_view const& p) noexcept
366 {
367 51 detail::re_encode_unsafe(
368 dest,
369 end,
370 p.key,
371 detail::param_key_chars);
372
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 9 times.
51 if(p.has_value)
373 {
374 42 *dest++ = '=';
375 42 detail::re_encode_unsafe(
376 dest,
377 end,
378 p.value,
379 detail::param_value_chars);
380 }
381 51 }
382
383 //------------------------------------------------
384 //
385 // param_value_iter
386 //
387 //------------------------------------------------
388
389 void
390 9 param_value_iter::
391 rewind() noexcept
392 {
393 9 at_end_ = false;
394 9 }
395
396 bool
397 18 param_value_iter::
398 measure(
399 std::size_t& n) noexcept
400 {
401
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 if(at_end_)
402 9 return false;
403 9 n += nk_; // skip key
404
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if(has_value_)
405 {
406 5 encoding_opts opt;
407 5 opt.space_as_plus = false;
408 5 n += encoded_size(
409 s0,
410 detail::param_value_chars,
411 5 opt) + 1; // for '='
412 }
413 9 at_end_ = true;
414 9 return true;
415 }
416
417 void
418 9 param_value_iter::
419 copy(char*& it, char const* end) noexcept
420 {
421 9 it += nk_; // skip key
422
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5 times.
9 if(! has_value_)
423 4 return;
424 5 *it++ = '=';
425 5 encoding_opts opt;
426 5 opt.space_as_plus = false;
427 5 it += encode(
428 it,
429 5 end - it,
430 s0,
431 detail::param_value_chars,
432 opt);
433 }
434
435 //------------------------------------------------
436 //
437 // param_encoded_value_iter
438 //
439 //------------------------------------------------
440
441 void
442 8 param_encoded_value_iter::
443 rewind() noexcept
444 {
445 8 at_end_ = false;
446 8 }
447
448 bool
449 16 param_encoded_value_iter::
450 measure(
451 std::size_t& n) noexcept
452 {
453
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if(at_end_)
454 8 return false;
455 8 n += nk_; // skip key
456
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if(has_value_)
457 {
458 4 n += detail::re_encoded_size_unsafe(
459 s0,
460 4 detail::param_value_chars) + 1; // for '='
461 }
462 8 at_end_ = true;
463 8 return true;
464 }
465
466 void
467 8 param_encoded_value_iter::
468 copy(
469 char*& dest,
470 char const* end) noexcept
471 {
472 8 dest += nk_; // skip key
473
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if(! has_value_)
474 4 return;
475 4 *dest++ = '=';
476 4 detail::re_encode_unsafe(
477 dest,
478 end,
479 s0,
480 detail::param_value_chars);
481 }
482
483 } // detail
484 } // urls
485 } // boost
486
487