include/boost/url/detail/impl/any_params_iter.hpp

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