GCC Code Coverage Report


Directory: libs/url/
File: libs/url/src/url_view_base.cpp
Date: 2024-02-29 20:02:56
Exec Total Coverage
Lines: 304 314 96.8%
Functions: 40 41 97.6%
Branches: 118 168 70.2%

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 #ifndef BOOST_URL_IMPL_URL_VIEW_BASE_IPP
12 #define BOOST_URL_IMPL_URL_VIEW_BASE_IPP
13
14 #include <boost/url/detail/config.hpp>
15 #include <boost/url/url_view_base.hpp>
16 #include <boost/url/url_view.hpp>
17 #include <boost/url/detail/except.hpp>
18 #include "detail/normalize.hpp"
19 #include "detail/over_allocator.hpp"
20
21 namespace boost {
22 namespace urls {
23
24 // construct empty view
25 4085 url_view_base::
26 4085 url_view_base() noexcept
27 : impl_(from::url)
28 4085 , pi_(&impl_)
29 {
30 4085 }
31
32 // construct reference
33 20700 url_view_base::
34 url_view_base(
35 20700 detail::url_impl const& impl) noexcept
36 : impl_(impl)
37 20700 , pi_(&impl_)
38 {
39 20700 }
40
41 //------------------------------------------------
42
43 std::size_t
44 276 url_view_base::
45 digest(std::size_t salt) const noexcept
46 {
47 276 detail::fnv_1a h(salt);
48 276 detail::ci_digest(pi_->get(id_scheme), h);
49 276 detail::digest_encoded(pi_->get(id_user), h);
50 276 detail::digest_encoded(pi_->get(id_pass), h);
51 276 detail::ci_digest_encoded(pi_->get(id_host), h);
52 276 h.put(pi_->get(id_port));
53 276 detail::normalized_path_digest(
54 276 pi_->get(id_path), is_path_absolute(), h);
55 276 detail::digest_encoded(pi_->get(id_query), h);
56 276 detail::digest_encoded(pi_->get(id_frag), h);
57 276 return h.digest();
58 }
59
60 //------------------------------------------------
61 //
62 // Observers
63 //
64 //------------------------------------------------
65
66 struct url_view_base::shared_impl
67 : url_view
68 {
69 virtual
70 4 ~shared_impl()
71 4 {
72 4 }
73
74 2 shared_impl(
75 url_view const& u) noexcept
76 2 : url_view(u)
77 {
78 2 impl_.cs_ = reinterpret_cast<
79 char const*>(this + 1);
80 2 }
81 };
82
83 std::shared_ptr<url_view const>
84 2 url_view_base::
85 persist() const
86 {
87 using T = shared_impl;
88 using Alloc = std::allocator<char>;
89 4 Alloc a;
90 auto p = std::allocate_shared<T>(
91
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 detail::over_allocator<T, Alloc>(
92
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
6 size(), a), url_view(*pi_));
93 2 std::memcpy(
94 reinterpret_cast<char*>(
95 2 p.get() + 1), data(), size());
96 4 return p;
97 }
98
99 //------------------------------------------------
100 //
101 // Scheme
102 //
103 //------------------------------------------------
104
105 bool
106 2715 url_view_base::
107 has_scheme() const noexcept
108 {
109 2715 auto const n = pi_->len(
110 id_scheme);
111
2/2
✓ Branch 0 taken 579 times.
✓ Branch 1 taken 2136 times.
2715 if(n == 0)
112 579 return false;
113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2136 times.
2136 BOOST_ASSERT(n > 1);
114
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 2136 times.
2136 BOOST_ASSERT(
115 pi_->get(id_scheme
116 ).ends_with(':'));
117 2136 return true;
118 }
119
120 core::string_view
121 1352 url_view_base::
122 scheme() const noexcept
123 {
124 1352 auto s = pi_->get(id_scheme);
125
2/2
✓ Branch 1 taken 1256 times.
✓ Branch 2 taken 96 times.
1352 if(! s.empty())
126 {
127
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1256 times.
1256 BOOST_ASSERT(s.size() > 1);
128
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1256 times.
1256 BOOST_ASSERT(s.ends_with(':'));
129 1256 s.remove_suffix(1);
130 }
131 1352 return s;
132 }
133
134 urls::scheme
135 44 url_view_base::
136 scheme_id() const noexcept
137 {
138 44 return pi_->scheme_;
139 }
140
141 //------------------------------------------------
142 //
143 // Authority
144 //
145 //------------------------------------------------
146
147 authority_view
148 399 url_view_base::
149 authority() const noexcept
150 {
151 399 detail::url_impl u(from::authority);
152 399 u.cs_ = encoded_authority().data();
153
1/2
✓ Branch 1 taken 399 times.
✗ Branch 2 not taken.
399 if(has_authority())
154 {
155 399 u.set_size(id_user, pi_->len(id_user) - 2);
156 399 u.set_size(id_pass, pi_->len(id_pass));
157 399 u.set_size(id_host, pi_->len(id_host));
158 399 u.set_size(id_port, pi_->len(id_port));
159 }
160 else
161 {
162 u.set_size(id_user, pi_->len(id_user));
163 BOOST_ASSERT(pi_->len(id_pass) == 0);
164 BOOST_ASSERT(pi_->len(id_host) == 0);
165 BOOST_ASSERT(pi_->len(id_port) == 0);
166 }
167 399 u.decoded_[id_user] = pi_->decoded_[id_user];
168 399 u.decoded_[id_pass] = pi_->decoded_[id_pass];
169 399 u.decoded_[id_host] = pi_->decoded_[id_host];
170
2/2
✓ Branch 0 taken 6384 times.
✓ Branch 1 taken 399 times.
6783 for (int i = 0; i < 16; ++i)
171 6384 u.ip_addr_[i] = pi_->ip_addr_[i];
172 399 u.port_number_ = pi_->port_number_;
173 399 u.host_type_ = pi_->host_type_;
174 399 return u.construct_authority();
175 }
176
177 pct_string_view
178 557 url_view_base::
179 encoded_authority() const noexcept
180 {
181 557 auto s = pi_->get(id_user, id_path);
182
2/2
✓ Branch 1 taken 517 times.
✓ Branch 2 taken 40 times.
557 if(! s.empty())
183 {
184
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 517 times.
517 BOOST_ASSERT(has_authority());
185 517 s.remove_prefix(2);
186 }
187 return make_pct_string_view_unsafe(
188 s.data(),
189 s.size(),
190 557 pi_->decoded_[id_user] +
191 557 pi_->decoded_[id_pass] +
192 557 pi_->decoded_[id_host] +
193 557 pi_->decoded_[id_port] +
194 557 has_password());
195 }
196
197 //------------------------------------------------
198 //
199 // Userinfo
200 //
201 //------------------------------------------------
202
203 bool
204 261 url_view_base::
205 has_userinfo() const noexcept
206 {
207 261 auto n = pi_->len(id_pass);
208
2/2
✓ Branch 0 taken 97 times.
✓ Branch 1 taken 164 times.
261 if(n == 0)
209 97 return false;
210
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 164 times.
164 BOOST_ASSERT(has_authority());
211
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 164 times.
164 BOOST_ASSERT(pi_->get(
212 id_pass).ends_with('@'));
213 164 return true;
214 }
215
216 bool
217 692 url_view_base::
218 has_password() const noexcept
219 {
220 692 auto const n = pi_->len(id_pass);
221
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 578 times.
692 if(n > 1)
222 {
223
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 114 times.
114 BOOST_ASSERT(pi_->get(id_pass
224 ).starts_with(':'));
225
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 114 times.
114 BOOST_ASSERT(pi_->get(id_pass
226 ).ends_with('@'));
227 114 return true;
228 }
229
3/4
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 465 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 113 times.
578 BOOST_ASSERT(n == 0 || pi_->get(
230 id_pass).ends_with('@'));
231 578 return false;
232 }
233
234 pct_string_view
235 119 url_view_base::
236 encoded_userinfo() const noexcept
237 {
238 119 auto s = pi_->get(
239 119 id_user, id_host);
240
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 111 times.
119 if(s.empty())
241 8 return s;
242
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 111 times.
111 BOOST_ASSERT(
243 has_authority());
244 111 s.remove_prefix(2);
245
2/2
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 77 times.
111 if(s.empty())
246 34 return s;
247
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 77 times.
77 BOOST_ASSERT(
248 s.ends_with('@'));
249 77 s.remove_suffix(1);
250 return make_pct_string_view_unsafe(
251 s.data(),
252 s.size(),
253 77 pi_->decoded_[id_user] +
254 77 pi_->decoded_[id_pass] +
255 77 has_password());
256 }
257
258 pct_string_view
259 131 url_view_base::
260 encoded_user() const noexcept
261 {
262 131 auto s = pi_->get(id_user);
263
2/2
✓ Branch 1 taken 130 times.
✓ Branch 2 taken 1 times.
131 if(! s.empty())
264 {
265
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 130 times.
130 BOOST_ASSERT(
266 has_authority());
267 130 s.remove_prefix(2);
268 }
269 return make_pct_string_view_unsafe(
270 s.data(),
271 s.size(),
272 131 pi_->decoded_[id_user]);
273 }
274
275 pct_string_view
276 94 url_view_base::
277 encoded_password() const noexcept
278 {
279 94 auto s = pi_->get(id_pass);
280
3/3
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 52 times.
94 switch(s.size())
281 {
282 24 case 1:
283
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
24 BOOST_ASSERT(
284 s.starts_with('@'));
285 24 s.remove_prefix(1);
286 BOOST_FALLTHROUGH;
287 42 case 0:
288 return make_pct_string_view_unsafe(
289 42 s.data(), s.size(), 0);
290 52 default:
291 52 break;
292 }
293
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
52 BOOST_ASSERT(s.ends_with('@'));
294
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
52 BOOST_ASSERT(s.starts_with(':'));
295 return make_pct_string_view_unsafe(
296 52 s.data() + 1,
297 52 s.size() - 2,
298 52 pi_->decoded_[id_pass]);
299 }
300
301 //------------------------------------------------
302 //
303 // Host
304 //
305 //------------------------------------------------
306 /*
307 host_type host_type() // ipv4, ipv6, ipvfuture, name
308
309 std::string host() // return encoded_host().decode()
310 pct_string_view encoded_host() // return host part, as-is
311 std::string host_address() // return encoded_host_address().decode()
312 pct_string_view encoded_host_address() // ipv4, ipv6, ipvfut, or encoded name, no brackets
313
314 ipv4_address host_ipv4_address() // return ipv4_address or {}
315 ipv6_address host_ipv6_address() // return ipv6_address or {}
316 core::string_view host_ipvfuture() // return ipvfuture or {}
317 std::string host_name() // return decoded name or ""
318 pct_string_view encoded_host_name() // return encoded host name or ""
319 */
320
321 pct_string_view
322 521 url_view_base::
323 encoded_host() const noexcept
324 {
325 521 return pi_->pct_get(id_host);
326 }
327
328 pct_string_view
329 117 url_view_base::
330 encoded_host_address() const noexcept
331 {
332 117 core::string_view s = pi_->get(id_host);
333 std::size_t n;
334
3/3
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 23 times.
117 switch(pi_->host_type_)
335 {
336 41 default:
337 case urls::host_type::none:
338
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
41 BOOST_ASSERT(s.empty());
339 41 n = 0;
340 41 break;
341
342 53 case urls::host_type::name:
343 case urls::host_type::ipv4:
344 53 n = pi_->decoded_[id_host];
345 53 break;
346
347 23 case urls::host_type::ipv6:
348 case urls::host_type::ipvfuture:
349 {
350
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
23 BOOST_ASSERT(
351 pi_->decoded_[id_host] ==
352 s.size());
353
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
23 BOOST_ASSERT(s.size() >= 2);
354
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
23 BOOST_ASSERT(s.front() == '[');
355
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
23 BOOST_ASSERT(s.back() == ']');
356 23 s = s.substr(1, s.size() - 2);
357 23 n = pi_->decoded_[id_host] - 2;
358 23 break;
359 }
360 }
361 return make_pct_string_view_unsafe(
362 s.data(),
363 s.size(),
364 117 n);
365 }
366
367 urls::ipv4_address
368 51 url_view_base::
369 host_ipv4_address() const noexcept
370 {
371
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 16 times.
51 if(pi_->host_type_ !=
372 urls::host_type::ipv4)
373 35 return {};
374 16 ipv4_address::bytes_type b{{}};
375 16 std::memcpy(
376 16 &b[0], &pi_->ip_addr_[0], b.size());
377 16 return urls::ipv4_address(b);
378 }
379
380 urls::ipv6_address
381 51 url_view_base::
382 host_ipv6_address() const noexcept
383 {
384
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 8 times.
51 if(pi_->host_type_ !=
385 urls::host_type::ipv6)
386 43 return {};
387 8 ipv6_address::bytes_type b{{}};
388 8 std::memcpy(
389 8 &b[0], &pi_->ip_addr_[0], b.size());
390 8 return urls::ipv6_address(b);
391 }
392
393 core::string_view
394 51 url_view_base::
395 host_ipvfuture() const noexcept
396 {
397
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 7 times.
51 if(pi_->host_type_ !=
398 urls::host_type::ipvfuture)
399 44 return {};
400 7 core::string_view s = pi_->get(id_host);
401
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 BOOST_ASSERT(s.size() >= 6);
402
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 BOOST_ASSERT(s.front() == '[');
403
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 BOOST_ASSERT(s.back() == ']');
404 7 s = s.substr(1, s.size() - 2);
405 7 return s;
406 }
407
408 pct_string_view
409 146 url_view_base::
410 encoded_host_name() const noexcept
411 {
412
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 68 times.
146 if(pi_->host_type_ !=
413 urls::host_type::name)
414 78 return {};
415 68 core::string_view s = pi_->get(id_host);
416 return make_pct_string_view_unsafe(
417 s.data(),
418 s.size(),
419 68 pi_->decoded_[id_host]);
420 }
421
422 pct_string_view
423 10 url_view_base::
424 encoded_zone_id() const noexcept
425 {
426
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
10 if(pi_->host_type_ !=
427 urls::host_type::ipv6)
428 2 return {};
429 8 core::string_view s = pi_->get(id_host);
430
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 BOOST_ASSERT(s.front() == '[');
431
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 BOOST_ASSERT(s.back() == ']');
432 8 s = s.substr(1, s.size() - 2);
433 8 auto pos = s.find("%25");
434
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if (pos == core::string_view::npos)
435 2 return {};
436 6 s.remove_prefix(pos + 3);
437 6 return *make_pct_string_view(s);
438 }
439
440 //------------------------------------------------
441
442 bool
443 364 url_view_base::
444 has_port() const noexcept
445 {
446 364 auto const n = pi_->len(id_port);
447
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 277 times.
364 if(n == 0)
448 87 return false;
449
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 277 times.
277 BOOST_ASSERT(
450 pi_->get(id_port).starts_with(':'));
451 277 return true;
452 }
453
454 core::string_view
455 179 url_view_base::
456 port() const noexcept
457 {
458 179 auto s = pi_->get(id_port);
459
2/2
✓ Branch 1 taken 58 times.
✓ Branch 2 taken 121 times.
179 if(s.empty())
460 58 return s;
461
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 121 times.
121 BOOST_ASSERT(has_port());
462 121 return s.substr(1);
463 }
464
465 std::uint16_t
466 101 url_view_base::
467 port_number() const noexcept
468 {
469
3/4
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 79 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22 times.
101 BOOST_ASSERT(
470 has_port() ||
471 pi_->port_number_ == 0);
472 101 return pi_->port_number_;
473 }
474
475 //------------------------------------------------
476 //
477 // Path
478 //
479 //------------------------------------------------
480
481 pct_string_view
482 1314 url_view_base::
483 encoded_path() const noexcept
484 {
485 1314 return pi_->pct_get(id_path);
486 }
487
488 segments_view
489 45 url_view_base::
490 segments() const noexcept
491 {
492 45 return {detail::path_ref(*pi_)};
493 }
494
495 segments_encoded_view
496 649 url_view_base::
497 encoded_segments() const noexcept
498 {
499 return segments_encoded_view(
500 649 detail::path_ref(*pi_));
501 }
502
503 //------------------------------------------------
504 //
505 // Query
506 //
507 //------------------------------------------------
508
509 bool
510 716 url_view_base::
511 has_query() const noexcept
512 {
513 716 auto const n = pi_->len(
514 id_query);
515
2/2
✓ Branch 0 taken 598 times.
✓ Branch 1 taken 118 times.
716 if(n == 0)
516 598 return false;
517
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 118 times.
118 BOOST_ASSERT(
518 pi_->get(id_query).
519 starts_with('?'));
520 118 return true;
521 }
522
523 pct_string_view
524 274 url_view_base::
525 encoded_query() const noexcept
526 {
527 274 auto s = pi_->get(id_query);
528
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 264 times.
274 if(s.empty())
529 10 return s;
530
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 264 times.
264 BOOST_ASSERT(
531 s.starts_with('?'));
532 264 return s.substr(1);
533 }
534
535 params_encoded_view
536 55 url_view_base::
537 encoded_params() const noexcept
538 {
539 55 return params_encoded_view(*pi_);
540 }
541
542 params_view
543 46 url_view_base::
544 params() const noexcept
545 {
546 return params_view(
547 46 *pi_,
548 encoding_opts{
549 46 true,false,false});
550 }
551
552 params_view
553 url_view_base::
554 params(encoding_opts opt) const noexcept
555 {
556 return params_view(*pi_, opt);
557 }
558
559 //------------------------------------------------
560 //
561 // Fragment
562 //
563 //------------------------------------------------
564
565 bool
566 624 url_view_base::
567 has_fragment() const noexcept
568 {
569 624 auto const n = pi_->len(id_frag);
570
2/2
✓ Branch 0 taken 499 times.
✓ Branch 1 taken 125 times.
624 if(n == 0)
571 499 return false;
572
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 125 times.
125 BOOST_ASSERT(
573 pi_->get(id_frag).
574 starts_with('#'));
575 125 return true;
576 }
577
578 pct_string_view
579 155 url_view_base::
580 encoded_fragment() const noexcept
581 {
582 155 auto s = pi_->get(id_frag);
583
2/2
✓ Branch 1 taken 153 times.
✓ Branch 2 taken 2 times.
155 if(! s.empty())
584 {
585
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 153 times.
153 BOOST_ASSERT(
586 s.starts_with('#'));
587 153 s.remove_prefix(1);
588 }
589 return make_pct_string_view_unsafe(
590 s.data(),
591 s.size(),
592 155 pi_->decoded_[id_frag]);
593 }
594
595 //------------------------------------------------
596 //
597 // Compound Fields
598 //
599 //------------------------------------------------
600
601 pct_string_view
602 120 url_view_base::
603 encoded_host_and_port() const noexcept
604 {
605 120 return pi_->pct_get(id_host, id_path);
606 }
607
608 pct_string_view
609 16 url_view_base::
610 encoded_origin() const noexcept
611 {
612
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
16 if(pi_->len(id_user) < 2)
613 14 return {};
614 2 return pi_->get(id_scheme, id_path);
615 }
616
617 pct_string_view
618 1 url_view_base::
619 encoded_resource() const noexcept
620 {
621 1 auto n =
622 1 pi_->decoded_[id_path] +
623 1 pi_->decoded_[id_query] +
624 1 pi_->decoded_[id_frag];
625
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if(has_query())
626 1 ++n;
627
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if(has_fragment())
628 1 ++n;
629
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 BOOST_ASSERT(pct_string_view(
630 pi_->get(id_path, id_end)
631 ).decoded_size() == n);
632 1 auto s = pi_->get(id_path, id_end);
633 return make_pct_string_view_unsafe(
634 1 s.data(), s.size(), n);
635 }
636
637 pct_string_view
638 2 url_view_base::
639 encoded_target() const noexcept
640 {
641 2 auto n =
642 2 pi_->decoded_[id_path] +
643 2 pi_->decoded_[id_query];
644
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if(has_query())
645 1 ++n;
646
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 BOOST_ASSERT(pct_string_view(
647 pi_->get(id_path, id_frag)
648 ).decoded_size() == n);
649 2 auto s = pi_->get(id_path, id_frag);
650 return make_pct_string_view_unsafe(
651 2 s.data(), s.size(), n);
652 }
653
654 //------------------------------------------------
655 //
656 // Comparisons
657 //
658 //------------------------------------------------
659
660 int
661 236 url_view_base::
662 compare(const url_view_base& other) const noexcept
663 {
664 int comp =
665 236 static_cast<int>(has_scheme()) -
666 236 static_cast<int>(other.has_scheme());
667
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
236 if ( comp != 0 )
668 return comp;
669
670
2/2
✓ Branch 1 taken 156 times.
✓ Branch 2 taken 80 times.
236 if (has_scheme())
671 {
672 156 comp = detail::ci_compare(
673 scheme(),
674 other.scheme());
675
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 142 times.
156 if ( comp != 0 )
676 14 return comp;
677 }
678
679 222 comp =
680 222 static_cast<int>(has_authority()) -
681 222 static_cast<int>(other.has_authority());
682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 222 times.
222 if ( comp != 0 )
683 return comp;
684
685
2/2
✓ Branch 1 taken 142 times.
✓ Branch 2 taken 80 times.
222 if (has_authority())
686 {
687 142 comp = authority().compare(other.authority());
688
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 88 times.
142 if ( comp != 0 )
689 54 return comp;
690 }
691
692 168 comp = detail::segments_compare(
693 encoded_segments(),
694 other.encoded_segments());
695
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 125 times.
168 if ( comp != 0 )
696 43 return comp;
697
698 125 comp =
699 125 static_cast<int>(has_query()) -
700 125 static_cast<int>(other.has_query());
701
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 125 times.
125 if ( comp != 0 )
702 return comp;
703
704
2/2
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 108 times.
125 if (has_query())
705 {
706 34 comp = detail::compare_encoded(
707 17 encoded_query(),
708 17 other.encoded_query());
709
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 3 times.
17 if ( comp != 0 )
710 14 return comp;
711 }
712
713 111 comp =
714 111 static_cast<int>(has_fragment()) -
715 111 static_cast<int>(other.has_fragment());
716
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 111 times.
111 if ( comp != 0 )
717 return comp;
718
719
2/2
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 89 times.
111 if (has_fragment())
720 {
721 44 comp = detail::compare_encoded(
722 22 encoded_fragment(),
723 22 other.encoded_fragment());
724
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 1 times.
22 if ( comp != 0 )
725 21 return comp;
726 }
727
728 90 return 0;
729 }
730
731 } // urls
732 } // boost
733
734 #endif
735