GCC Code Coverage Report


Directory: libs/url/
File: boost/url/detail/any_params_iter.hpp
Date: 2024-08-19 20:08:56
Exec Total Coverage
Lines: 58 58 100.0%
Functions: 25 25 100.0%
Branches: 9 10 90.0%

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 #ifndef BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP
11 #define BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP
12
13 #include <boost/url/param.hpp>
14 #include <boost/url/pct_string_view.hpp>
15 #include <boost/static_assert.hpp>
16 #include <cstddef>
17 #include <iterator>
18 #include <type_traits>
19
20 namespace boost {
21 namespace urls {
22 namespace detail {
23
24 //------------------------------------------------
25 //
26 // any_params_iter
27 //
28 //------------------------------------------------
29
30 /* An iterator to a type-erased,
31 possibly encoded sequence of
32 query params_ref.
33 */
34 struct BOOST_SYMBOL_VISIBLE
35 any_params_iter
36 {
37 protected:
38 138 any_params_iter(
39 bool empty_,
40 core::string_view s0_ = {},
41 core::string_view s1_ = {}) noexcept
42 138 : s0(s0_)
43 138 , s1(s1_)
44 138 , empty(empty_)
45 {
46 138 }
47
48 public:
49 // these are adjusted
50 // when self-intersecting
51 core::string_view s0;
52 core::string_view s1;
53
54 // True if the sequence is empty
55 bool empty = false;
56
57 BOOST_URL_DECL
58 virtual
59 ~any_params_iter() noexcept = 0;
60
61 // Rewind the iterator to the beginning
62 virtual
63 void
64 rewind() noexcept = 0;
65
66 // Measure and increment current element
67 // element.
68 // Returns false on end of range.
69 // n is increased by encoded size.
70 // Can throw on bad percent-escape
71 virtual
72 bool
73 measure(std::size_t& n) = 0;
74
75 // Copy and increment the current
76 // element. encoding is performed
77 // if needed.
78 virtual
79 void
80 copy(
81 char*& dest,
82 char const* end) noexcept = 0;
83 };
84
85 //------------------------------------------------
86 //
87 // query_iter
88 //
89 //------------------------------------------------
90
91 // A string of plain query params
92 struct BOOST_SYMBOL_VISIBLE
93 query_iter
94 : any_params_iter
95 {
96 // ne = never empty
97 BOOST_URL_DECL
98 explicit
99 query_iter(
100 core::string_view s,
101 bool ne = false) noexcept;
102
103 private:
104 core::string_view s_;
105 std::size_t n_;
106 char const* p_;
107 bool at_end_;
108
109 void rewind() noexcept override;
110 bool measure(std::size_t&) noexcept override;
111 void copy(char*&, char const*) noexcept override;
112 void increment() noexcept;
113 };
114
115 //------------------------------------------------
116 //
117 // param_iter
118 //
119 //------------------------------------------------
120
121 // A 1-param range allowing
122 // self-intersection
123 struct BOOST_SYMBOL_VISIBLE
124 param_iter
125 : any_params_iter
126 {
127 explicit
128 param_iter(
129 param_view const&) noexcept;
130
131 private:
132 bool has_value_;
133 bool at_end_ = false;
134
135 void rewind() noexcept override;
136 bool measure(std::size_t&) noexcept override;
137 void copy(char*&, char const*) noexcept override;
138 };
139
140 //------------------------------------------------
141 //
142 // params_iter_base
143 //
144 //------------------------------------------------
145
146 struct params_iter_base
147 {
148 protected:
149 // return encoded size
150 BOOST_URL_DECL
151 static
152 void
153 measure_impl(
154 std::size_t& n,
155 param_view const& p) noexcept;
156
157 // encode to dest
158 BOOST_URL_DECL
159 static
160 void
161 copy_impl(
162 char*& dest,
163 char const* end,
164 param_view const& v) noexcept;
165 };
166
167 //------------------------------------------------
168
169 // A range of plain query params_ref
170 template<class FwdIt>
171 struct params_iter
172 : any_params_iter
173 , private params_iter_base
174 {
175 BOOST_STATIC_ASSERT(
176 std::is_convertible<
177 typename std::iterator_traits<
178 FwdIt>::reference,
179 param_view>::value);
180
181 33 params_iter(
182 FwdIt first,
183 FwdIt last) noexcept
184 : any_params_iter(
185 2 first == last)
186 33 , it0_(first)
187 33 , it_(first)
188 35 , end_(last)
189 {
190 33 }
191
192 private:
193 FwdIt it0_;
194 FwdIt it_;
195 FwdIt end_;
196
197 void
198 33 rewind() noexcept override
199 {
200 33 it_ = it0_;
201 33 }
202
203 bool
204 103 measure(
205 std::size_t& n) noexcept override
206 {
207
3/3
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 68 times.
✓ Branch 2 taken 1 times.
103 if(it_ == end_)
208 33 return false;
209 70 measure_impl(n,
210 72 param_view(*it_++));
211 70 return true;
212 }
213
214 void
215 70 copy(
216 char*& dest,
217 char const* end) noexcept override
218 {
219 70 copy_impl(dest, end,
220 72 param_view(*it_++));
221 70 }
222 };
223
224 //------------------------------------------------
225 //
226 // param_encoded_iter
227 //
228 //------------------------------------------------
229
230 // A 1-param encoded range
231 // allowing self-intersection
232 struct BOOST_SYMBOL_VISIBLE
233 param_encoded_iter
234 : any_params_iter
235 {
236 explicit
237 param_encoded_iter(
238 param_pct_view const&) noexcept;
239
240 private:
241 bool has_value_;
242 bool at_end_ = false;
243
244 void rewind() noexcept override;
245 bool measure(std::size_t&) noexcept override;
246 void copy(char*&, char const*) noexcept override;
247 };
248
249 //------------------------------------------------
250 //
251 // params_encoded_iter
252 //
253 //------------------------------------------------
254
255 // Validating and copying from
256 // a string of encoded params
257 struct params_encoded_iter_base
258 {
259 protected:
260 BOOST_URL_DECL
261 static
262 void
263 measure_impl(
264 std::size_t& n,
265 param_view const& v) noexcept;
266
267 BOOST_URL_DECL
268 static
269 void
270 copy_impl(
271 char*& dest,
272 char const* end,
273 param_view const& v) noexcept;
274 };
275
276 //------------------------------------------------
277
278 // A range of encoded query params_ref
279 template<class FwdIt>
280 struct params_encoded_iter
281 : any_params_iter
282 , private params_encoded_iter_base
283 {
284 BOOST_STATIC_ASSERT(
285 std::is_convertible<
286 typename std::iterator_traits<
287 FwdIt>::reference,
288 param_view>::value);
289
290 48 params_encoded_iter(
291 FwdIt first,
292 FwdIt last) noexcept
293 : any_params_iter(
294 2 first == last)
295 48 , it0_(first)
296 48 , it_(first)
297 50 , end_(last)
298 {
299 48 }
300
301 private:
302 FwdIt it0_;
303 FwdIt it_;
304 FwdIt end_;
305
306 void
307 43 rewind() noexcept override
308 {
309 43 it_ = it0_;
310 43 }
311
312 bool
313 137 measure(
314 std::size_t& n) override
315 {
316
3/3
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 1 times.
137 if(it_ == end_)
317 43 return false;
318 // throw on invalid input
319 89 measure_impl(n,
320
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
107 param_pct_view(
321
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 5 times.
94 param_view(*it_++)));
322 89 return true;
323 }
324
325 void
326 89 copy(
327 char*& dest,
328 char const* end
329 ) noexcept override
330 {
331 89 copy_impl(dest, end,
332 89 param_view(*it_++));
333 89 }
334 };
335
336 //------------------------------------------------
337 //
338 // param_value_iter
339 //
340 //------------------------------------------------
341
342 // An iterator which outputs
343 // one value on an existing key
344 struct param_value_iter
345 : any_params_iter
346 {
347 9 param_value_iter(
348 std::size_t nk,
349 core::string_view const& value,
350 bool has_value) noexcept
351 9 : any_params_iter(
352 false,
353 value)
354 9 , nk_(nk)
355 9 , has_value_(has_value)
356 {
357 9 }
358
359 private:
360 std::size_t nk_ = 0;
361 bool has_value_ = false;
362 bool at_end_ = false;
363
364 void rewind() noexcept override;
365 bool measure(std::size_t&) noexcept override;
366 void copy(char*&, char const*) noexcept override;
367 };
368
369 //------------------------------------------------
370 //
371 // param_encoded_value_iter
372 //
373 //------------------------------------------------
374
375 // An iterator which outputs one
376 // encoded value on an existing key
377 struct param_encoded_value_iter
378 : any_params_iter
379 {
380 8 param_encoded_value_iter(
381 std::size_t nk,
382 pct_string_view const& value,
383 bool has_value) noexcept
384 8 : any_params_iter(
385 false,
386 value)
387 8 , nk_(nk)
388 8 , has_value_(has_value)
389 {
390 8 }
391
392 private:
393 std::size_t nk_ = 0;
394 bool has_value_ = false;
395 bool at_end_ = false;
396
397 void rewind() noexcept override;
398 bool measure(std::size_t&) noexcept override;
399 void copy(char*&, char const*) noexcept override;
400 };
401
402 //------------------------------------------------
403
404 template<class FwdIt>
405 params_iter<FwdIt>
406 31 make_params_iter(
407 FwdIt first, FwdIt last)
408 {
409 return params_iter<
410 31 FwdIt>(first, last);
411 }
412
413 template<class FwdIt>
414 params_encoded_iter<FwdIt>
415 29 make_params_encoded_iter(
416 FwdIt first, FwdIt last)
417 {
418 return params_encoded_iter<
419 29 FwdIt>(first, last);
420 }
421
422 } // detail
423 } // urls
424 } // boost
425
426 #endif
427