GCC Code Coverage Report


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