GCC Code Coverage Report


Directory: libs/url/
File: libs/url/src/detail/url_impl.cpp
Date: 2024-02-29 20:02:56
Exec Total Coverage
Lines: 203 207 98.1%
Functions: 34 34 100.0%
Branches: 53 64 82.8%

Line Branch Exec Source
1 //
2 // Copyright (c) 2022 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_IMPL_URL_IMPL_IPP
11 #define BOOST_URL_DETAIL_IMPL_URL_IMPL_IPP
12
13 #include <boost/url/detail/config.hpp>
14 #include "path.hpp"
15 #include <boost/url/detail/url_impl.hpp>
16 #include <boost/url/authority_view.hpp>
17 #include <boost/assert.hpp>
18 #include <cstring>
19
20 namespace boost {
21 namespace urls {
22 namespace detail {
23
24 #if defined(__GNUC__) && ! defined(__clang__) && defined(__MINGW32__)
25 #pragma GCC diagnostic push
26 #pragma GCC diagnostic ignored "-Warray-bounds"
27 #endif
28
29 //------------------------------------------------
30 //
31 // url_impl
32 //
33 //------------------------------------------------
34
35 void
36 2249 url_impl::
37 apply_scheme(
38 core::string_view s) noexcept
39 {
40 2249 scheme_ = string_to_scheme(s);
41 2249 set_size(id_scheme, s.size() + 1);
42 2249 }
43
44 void
45 380 url_impl::
46 apply_userinfo(
47 pct_string_view const& user,
48 pct_string_view const* pass) noexcept
49 {
50 // this function is for
51 // authority_view_rule only
52
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 380 times.
380 BOOST_ASSERT(from_ == from::authority);
53
54 // userinfo
55 380 set_size(id_user, user.size());
56 380 decoded_[id_user] =
57 380 user.decoded_size();
58
2/2
✓ Branch 0 taken 251 times.
✓ Branch 1 taken 129 times.
380 if(pass)
59 {
60 251 set_size(id_pass,
61 251 pass->size() + 2);
62 251 decoded_[id_pass] =
63 251 pass->decoded_size();
64 }
65 else
66 {
67 // trailing '@'
68 129 set_size(id_pass, 1 );
69 }
70 380 }
71
72 void
73 1848 url_impl::
74 apply_host(
75 host_type ht,
76 pct_string_view s,
77 unsigned char const* addr) noexcept
78 {
79 // this function is for
80 // authority_view_rule only
81
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1848 times.
1848 BOOST_ASSERT(from_ == from::authority);
82
83 // host, port
84 1848 host_type_ = ht;
85 1848 set_size(id_host, s.size());
86 1848 decoded_[id_host] =
87 1848 s.decoded_size();
88 1848 std::memcpy(
89 1848 ip_addr_,
90 addr,
91 sizeof(ip_addr_));
92 1848 }
93
94 void
95 247 url_impl::
96 apply_port(
97 core::string_view s,
98 unsigned short pn) noexcept
99 {
100 // this function is for
101 // authority_view_rule only
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 247 times.
247 BOOST_ASSERT(from_ == from::authority);
103
104 247 port_number_ = pn;
105 247 set_size(id_port, 1 + s.size());
106 247 }
107
108 void
109 1792 url_impl::
110 apply_authority(
111 authority_view const& a) noexcept
112 {
113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1792 times.
1792 BOOST_ASSERT(from_ != from::authority);
114
115 // userinfo
116 1792 set_size(id_user,
117 1792 a.u_.len(id_user) +
118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1792 times.
1792 (from_ == from::authority ? 0 : 2));
119 1792 set_size(id_pass, a.u_.len(id_pass));
120 1792 decoded_[id_user] = a.u_.decoded_[id_user];
121 1792 decoded_[id_pass] = a.u_.decoded_[id_pass];
122
123 // host, port
124 1792 host_type_ = a.u_.host_type_;
125 1792 port_number_ = a.u_.port_number_;
126 1792 set_size(id_host, a.u_.len(id_host));
127 1792 set_size(id_port, a.u_.len(id_port));
128 1792 std::memcpy(
129 1792 ip_addr_,
130 1792 a.u_.ip_addr_,
131 sizeof(ip_addr_));
132 1792 decoded_[id_host] = a.u_.decoded_[id_host];
133 1792 }
134
135 void
136 3523 url_impl::
137 apply_path(
138 pct_string_view s,
139 std::size_t nseg) noexcept
140 {
141 3523 set_size(id_path, s.size());
142 3523 decoded_[id_path] = s.decoded_size();
143 3523 nseg_ = detail::path_segments(s, nseg);
144 3523 }
145
146 void
147 430 url_impl::
148 apply_query(
149 pct_string_view s,
150 std::size_t n) noexcept
151 {
152 430 nparam_ = n;
153 430 set_size(id_query, 1 + s.size());
154 430 decoded_[id_query] = s.decoded_size();
155 430 }
156
157 void
158 210 url_impl::
159 apply_frag(
160 pct_string_view s) noexcept
161 {
162 210 set_size(id_frag, s.size() + 1);
163 210 decoded_[id_frag] = s.decoded_size();
164 210 }
165
166 // return length of [first, last)
167 auto
168 20187 url_impl::
169 len(
170 int first,
171 int last) const noexcept ->
172 std::size_t
173 {
174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20187 times.
20187 BOOST_ASSERT(first <= last);
175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20187 times.
20187 BOOST_ASSERT(last <= id_end);
176 20187 return offset(last) - offset(first);
177 }
178
179 // return length of part
180 auto
181 262748 url_impl::
182 len(int id) const noexcept ->
183 std::size_t
184 {
185 return id == id_end
186
1/2
✓ Branch 0 taken 262748 times.
✗ Branch 1 not taken.
525496 ? zero_
187 262748 : ( offset(id + 1) -
188 525496 offset(id) );
189 }
190
191 // return offset of id
192 auto
193 688690 url_impl::
194 offset(int id) const noexcept ->
195 std::size_t
196 {
197 return
198 id == id_scheme
199
2/2
✓ Branch 0 taken 637008 times.
✓ Branch 1 taken 51682 times.
688690 ? zero_
200 688690 : offset_[id];
201 }
202
203 // return id as string
204 core::string_view
205 46519 url_impl::
206 get(int id) const noexcept
207 {
208 return {
209 46519 cs_ + offset(id), len(id) };
210 }
211
212 // return [first, last) as string
213 core::string_view
214 791 url_impl::
215 get(int first,
216 int last) const noexcept
217 {
218 791 return { cs_ + offset(first),
219 791 offset(last) - offset(first) };
220 }
221
222 // return id as pct-string
223 pct_string_view
224 2085 url_impl::
225 pct_get(
226 int id) const noexcept
227 {
228 return make_pct_string_view_unsafe(
229 2085 cs_ + offset(id),
230 len(id),
231 4170 decoded_[id]);
232 }
233
234 // return [first, last) as pct-string
235 pct_string_view
236 120 url_impl::
237 pct_get(
238 int first,
239 int last) const noexcept
240 {
241 120 auto const pos = offset(first);
242 120 std::size_t n = 0;
243
2/2
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 120 times.
360 for(auto i = first; i < last;)
244 240 n += decoded_[i++];
245 return make_pct_string_view_unsafe(
246 120 cs_ + pos,
247 120 offset(last) - pos,
248 120 n);
249 }
250
251 //------------------------------------------------
252
253 // change id to size n
254 void
255 18762 url_impl::
256 set_size(
257 int id,
258 std::size_t n) noexcept
259 {
260 18762 auto d = n - len(id);
261 18762 for(auto i = id + 1;
262
2/2
✓ Branch 0 taken 95061 times.
✓ Branch 1 taken 18762 times.
113823 i <= id_end; ++i)
263 95061 offset_[i] += d;
264 18762 }
265
266 // trim id to size n,
267 // moving excess into id+1
268 void
269 811 url_impl::
270 split(
271 int id,
272 std::size_t n) noexcept
273 {
274
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 811 times.
811 BOOST_ASSERT(id < id_end - 1);
275 //BOOST_ASSERT(n <= len(id));
276 811 offset_[id + 1] = offset(id) + n;
277 811 }
278
279 // add n to [first, last]
280 void
281 911 url_impl::
282 adjust_right(
283 int first,
284 int last,
285 std::size_t n) noexcept
286 {
287 911 for(int i = first;
288
2/2
✓ Branch 0 taken 4394 times.
✓ Branch 1 taken 911 times.
5305 i <= last; ++i)
289 4394 offset_[i] += n;
290 911 }
291
292 // remove n from [first, last]
293 void
294 676 url_impl::
295 adjust_left(
296 int first,
297 int last,
298 std::size_t n) noexcept
299 {
300 676 for(int i = first;
301
2/2
✓ Branch 0 taken 2657 times.
✓ Branch 1 taken 676 times.
3333 i <= last; ++i)
302 2657 offset_[i] -= n;
303 676 }
304
305 // set [first, last) offset
306 void
307 1568 url_impl::
308 collapse(
309 int first,
310 int last,
311 std::size_t n) noexcept
312 {
313 1568 for(int i = first + 1;
314
2/2
✓ Branch 0 taken 545 times.
✓ Branch 1 taken 1568 times.
2113 i < last; ++i)
315 545 offset_[i] = n;
316 1568 }
317
318
319 //------------------------------------------------
320 //
321 // path_ref
322 //
323 //------------------------------------------------
324
325 2017 path_ref::
326 path_ref(
327 2017 url_impl const& impl) noexcept
328 {
329
2/2
✓ Branch 0 taken 1569 times.
✓ Branch 1 taken 448 times.
2017 if(impl.from_ == url_impl::from::url)
330 {
331 1569 impl_ = &impl;
332 }
333 else
334 {
335 448 core::string_view s = impl.get(id_path);
336 448 data_ = s.data();
337 448 size_ = s.size();
338 448 nseg_ = impl.nseg_;
339 448 dn_ = impl.decoded_[id_path];
340 }
341 2017 }
342
343 141 path_ref::
344 path_ref(
345 core::string_view s,
346 std::size_t dn,
347 141 std::size_t nseg) noexcept
348 141 : data_(s.data())
349 141 , size_(s.size())
350 , nseg_(nseg)
351 141 , dn_(dn)
352 {
353 141 }
354
355 pct_string_view
356 4475 path_ref::
357 buffer() const noexcept
358 {
359
2/2
✓ Branch 0 taken 2321 times.
✓ Branch 1 taken 2154 times.
4475 if(impl_)
360 return make_pct_string_view_unsafe(
361 2321 impl_->cs_ +
362 2321 impl_->offset(id_path),
363 2321 impl_->len(id_path),
364 4642 impl_->decoded_[id_path]);
365 return make_pct_string_view_unsafe(
366 2154 data_, size_, dn_);
367 }
368
369 std::size_t
370 3899 path_ref::
371 size() const noexcept
372 {
373
2/2
✓ Branch 0 taken 2657 times.
✓ Branch 1 taken 1242 times.
3899 if(impl_)
374 2657 return impl_->len(id_path);
375 1242 return size_;
376 }
377
378 char const*
379 12602 path_ref::
380 data() const noexcept
381 {
382
2/2
✓ Branch 0 taken 7447 times.
✓ Branch 1 taken 5155 times.
12602 if(impl_)
383 7447 return impl_->cs_ +
384 7447 impl_->offset(id_path);
385 5155 return data_;
386 }
387
388 char const*
389 4397 path_ref::
390 end() const noexcept
391 {
392
2/2
✓ Branch 0 taken 2945 times.
✓ Branch 1 taken 1452 times.
4397 if(impl_)
393 2945 return impl_->cs_ +
394 2945 impl_->offset(id_query);
395 1452 return data_ + size_;
396 }
397
398 std::size_t
399 8630 path_ref::
400 nseg() const noexcept
401 {
402
2/2
✓ Branch 0 taken 5508 times.
✓ Branch 1 taken 3122 times.
8630 if(impl_)
403 5508 return impl_->nseg_;
404 3122 return nseg_;
405 }
406
407 //------------------------------------------------
408 //
409 // query_ref
410 //
411 //------------------------------------------------
412
413 674 query_ref::
414 query_ref(
415 core::string_view s,
416 std::size_t dn,
417 674 std::size_t nparam) noexcept
418 674 : data_(s.data())
419 674 , size_(s.size())
420 , nparam_(nparam)
421 674 , dn_(dn)
422 {
423 674 }
424
425 425 query_ref::
426 query_ref(
427 425 url_impl const& impl) noexcept
428 {
429
2/2
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 81 times.
425 if(impl.from_ == url_impl::from::url)
430 {
431 344 impl_ = &impl;
432 }
433 else
434 {
435 81 core::string_view s = impl.get(id_query);
436
2/2
✓ Branch 1 taken 79 times.
✓ Branch 2 taken 2 times.
81 if (!s.empty())
437 {
438 79 s.remove_prefix(1);
439 79 question_mark_ = true;
440 }
441 81 data_ = s.data();
442 81 size_ = s.size();
443 81 nparam_ = impl.nparam_;
444 81 dn_ = impl.decoded_[id_query];
445 }
446 425 }
447
448 pct_string_view
449 454 query_ref::
450 buffer() const noexcept
451 {
452
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 452 times.
454 if(impl_)
453 {
454 2 auto pos = impl_->offset_[id_query];
455 2 auto pos1 = impl_->offset_[id_frag];
456
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(pos < pos1)
457 {
458 ++pos; // no '?'
459 return make_pct_string_view_unsafe(
460 impl_->cs_ + pos,
461 pos1 - pos,
462 impl_->decoded_[id_query]);
463 }
464 // empty
465 return make_pct_string_view_unsafe(
466 2 impl_->cs_ + pos,
467 0,
468 2 0);
469 }
470 // no '?'
471 return make_pct_string_view_unsafe(
472 452 data_, size_, dn_);
473 }
474
475 // with '?'
476 std::size_t
477 5282 query_ref::
478 size() const noexcept
479 {
480
2/2
✓ Branch 0 taken 1990 times.
✓ Branch 1 taken 3292 times.
5282 if(impl_)
481 1990 return impl_->len(id_query);
482
2/2
✓ Branch 0 taken 3264 times.
✓ Branch 1 taken 28 times.
3292 if(size_ > 0)
483 3264 return size_ + 1;
484 28 return question_mark_;
485 }
486
487 // no '?'
488 char const*
489 5807 query_ref::
490 begin() const noexcept
491 {
492
2/2
✓ Branch 0 taken 2267 times.
✓ Branch 1 taken 3540 times.
5807 if(impl_)
493 {
494 // using the offset array here
495 2267 auto pos = impl_->offset_[id_query];
496 2267 auto pos1 = impl_->offset_[id_frag];
497
1/2
✓ Branch 0 taken 2267 times.
✗ Branch 1 not taken.
2267 if(pos < pos1)
498 2267 return impl_->cs_ + pos + 1; // no '?'
499 // empty
500 return impl_->cs_ + pos;
501 }
502 3540 return data_;
503
504 }
505
506 char const*
507 2282 query_ref::
508 end() const noexcept
509 {
510
2/2
✓ Branch 0 taken 902 times.
✓ Branch 1 taken 1380 times.
2282 if(impl_)
511 902 return impl_->cs_ +
512 902 impl_->offset(id_frag);
513 1380 return data_ + size_;
514 }
515
516 std::size_t
517 8886 query_ref::
518 nparam() const noexcept
519 {
520
2/2
✓ Branch 0 taken 3134 times.
✓ Branch 1 taken 5752 times.
8886 if(impl_)
521 3134 return impl_->nparam_;
522 5752 return nparam_;
523 }
524
525 #if defined(__GNUC__) && ! defined(__clang__) && defined(__MINGW32__)
526 #pragma GCC diagnostic pop
527 #endif
528
529 } // detail
530 } // urls
531 } // boost
532
533 #endif
534