GCC Code Coverage Report


Directory: libs/url/
File: src/params_base.cpp
Date: 2025-11-13 05:23:43
Exec Total Coverage
Lines: 105 105 100.0%
Functions: 20 20 100.0%
Branches: 31 36 86.1%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
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/boostorg/url
9 //
10
11
12 #include <boost/url/detail/config.hpp>
13 #include <boost/url/decode_view.hpp>
14 #include <boost/url/params_base.hpp>
15 #include <boost/url/grammar/ci_string.hpp>
16 #include <ostream>
17 #include <string>
18
19 namespace boost {
20 namespace urls {
21
22 //------------------------------------------------
23
24 310 params_base::
25 iterator::
26 iterator(
27 detail::query_ref const& ref,
28 310 encoding_opts opt) noexcept
29 310 : it_(ref)
30 310 , space_as_plus_(opt.space_as_plus)
31 {
32 310 }
33
34 234 params_base::
35 iterator::
36 iterator(
37 detail::query_ref const& ref,
38 encoding_opts opt,
39 234 int) noexcept
40 234 : it_(ref, 0)
41 234 , space_as_plus_(opt.space_as_plus)
42 {
43 234 }
44
45
46 auto
47 775 params_base::
48 iterator::
49 operator*() const ->
50 reference
51
52 {
53 775 encoding_opts opt;
54 775 opt.space_as_plus =
55 775 space_as_plus_;
56 param_pct_view p =
57 775 it_.dereference();
58 return reference(
59
1/2
✓ Branch 2 taken 775 times.
✗ Branch 3 not taken.
1550 p.key.decode(opt),
60
1/2
✓ Branch 1 taken 775 times.
✗ Branch 2 not taken.
1550 p.value.decode(opt),
61 3875 p.has_value);
62 }
63
64 //------------------------------------------------
65 //
66 // params_base
67 //
68 //------------------------------------------------
69
70 1 params_base::
71 1 params_base() noexcept
72 // space_as_plus = true
73 1 : opt_(true, false, false)
74 {
75 1 }
76
77 bool
78 28 params_base::
79 contains(
80 core::string_view key,
81 ignore_case_param ic) const noexcept
82 {
83 28 return find(
84 56 begin(),key, ic) != end();
85 }
86
87 auto
88 40 params_base::
89 find(
90 core::string_view key,
91 ignore_case_param ic) const noexcept ->
92 iterator
93 {
94 return iterator(
95 40 find_impl(
96 80 begin().it_, key, ic),
97 40 opt_);
98 }
99
100 auto
101 60 params_base::
102 find(
103 iterator it,
104 core::string_view key,
105 ignore_case_param ic) const noexcept ->
106 iterator
107 {
108 return iterator(
109 120 find_impl(
110 it.it_, key, ic),
111 60 opt_);
112 }
113
114 auto
115 4 params_base::
116 find_last(
117 core::string_view key,
118 ignore_case_param ic) const noexcept ->
119 iterator
120 {
121 return iterator(
122 4 find_last_impl(
123 8 end().it_, key, ic),
124 4 opt_);
125 }
126
127 auto
128 9 params_base::
129 find_last(
130 iterator it,
131 core::string_view key,
132 ignore_case_param ic) const noexcept ->
133 iterator
134 {
135 return iterator(
136 18 find_last_impl(
137 it.it_, key, ic),
138 9 opt_);
139 }
140
141 295 params_base::
142 params_base(
143 detail::query_ref const& ref,
144 295 encoding_opts opt) noexcept
145 295 : ref_(ref)
146 295 , opt_(opt)
147 {
148 295 }
149
150 pct_string_view
151 13 params_base::
152 buffer() const noexcept
153 {
154 13 return ref_.buffer();
155 }
156
157 bool
158 5 params_base::
159 empty() const noexcept
160 {
161 5 return ref_.nparam() == 0;
162 }
163
164 std::size_t
165 213 params_base::
166 size() const noexcept
167 {
168 213 return ref_.nparam();
169 }
170
171 auto
172 310 params_base::
173 begin() const noexcept ->
174 iterator
175 {
176 310 return iterator(ref_, opt_);
177 }
178
179 auto
180 234 params_base::
181 end() const noexcept ->
182 iterator
183 {
184 234 return {ref_, opt_, 0};
185 }
186
187 //------------------------------------------------
188
189 std::size_t
190 29 params_base::
191 count(
192 core::string_view key,
193 ignore_case_param ic) const noexcept
194 {
195 29 std::size_t n = 0;
196 29 auto it = find(key, ic);
197 29 auto const end_ = end();
198
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 29 times.
57 while(it != end_)
199 {
200 28 ++n;
201 28 ++it;
202 28 it = find(it, key, ic);
203 }
204 29 return n;
205 }
206
207 std::string
208 8 params_base::
209 get_or(
210 core::string_view key,
211 core::string_view value,
212 ignore_case_param ic) const
213 {
214 8 auto it = find_impl(
215 8 begin().it_, key, ic);
216 8 detail::params_iter_impl end_(ref_, 0);
217
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6 times.
8 if(it.equal(end_))
218
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 return std::string(value);
219
220 6 param_pct_view const p = it.dereference();
221
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if(! p.has_value)
222 1 return std::string();
223
224 5 auto opt = opt_;
225
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 return p.value.decode(opt);
226 }
227
228 //------------------------------------------------
229 //
230 // (implementation)
231 //
232 //------------------------------------------------
233
234 detail::params_iter_impl
235 108 params_base::
236 find_impl(
237 detail::params_iter_impl it,
238 core::string_view key,
239 ignore_case_param ic) const noexcept
240 {
241 108 detail::params_iter_impl end_(ref_, 0);
242
2/2
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 70 times.
108 if(! ic)
243 {
244 for(;;)
245 {
246
2/2
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 287 times.
320 if(it.equal(end_))
247 33 return it;
248
2/2
✓ Branch 3 taken 37 times.
✓ Branch 4 taken 250 times.
287 if(*it.key() == key)
249 37 return it;
250 250 it.increment();
251 }
252 }
253 for(;;)
254 {
255
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 119 times.
129 if(it.equal(end_))
256 10 return it;
257 119 if( grammar::ci_is_equal(
258
2/2
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 91 times.
238 *it.key(), key))
259 28 return it;
260 91 it.increment();
261 }
262 }
263
264 detail::params_iter_impl
265 13 params_base::
266 find_last_impl(
267 detail::params_iter_impl it,
268 core::string_view key,
269 ignore_case_param ic) const noexcept
270 {
271 13 detail::params_iter_impl begin_(ref_);
272
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 7 times.
13 if(! ic)
273 {
274 for(;;)
275 {
276
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 11 times.
13 if(it.equal(begin_))
277 2 return { ref_, 0 };
278 11 it.decrement();
279
2/2
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 6 times.
11 if(*it.key() == key)
280 5 return it;
281 }
282 }
283 for(;;)
284 {
285
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 8 times.
9 if(it.equal(begin_))
286 1 return { ref_, 0 };
287 8 it.decrement();
288 8 if(grammar::ci_is_equal(
289
2/2
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 3 times.
16 *it.key(), key))
290 5 return it;
291 }
292 }
293
294 //------------------------------------------------
295
296 std::ostream&
297 1 operator<<(
298 std::ostream& os,
299 params_base const& qp)
300 {
301
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 os << qp.buffer();
302 1 return os;
303 }
304
305 } // urls
306 } // boost
307