GCC Code Coverage Report


Directory: libs/url/
File: libs/url/src/detail/url_impl.cpp
Date: 2024-01-19 15:42:54
Exec Total Coverage
Lines: 198 202 98.0%
Functions: 33 33 100.0%
Branches: 51 62 82.3%

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 1587 url_impl::
282 adjust(
283 int first,
284 int last,
285 std::size_t n) noexcept
286 {
287 1587 for(int i = first;
288
2/2
✓ Branch 0 taken 7051 times.
✓ Branch 1 taken 1587 times.
8638 i <= last; ++i)
289 7051 offset_[i] += n;
290 1587 }
291
292 // set [first, last) offset
293 void
294 1568 url_impl::
295 collapse(
296 int first,
297 int last,
298 std::size_t n) noexcept
299 {
300 1568 for(int i = first + 1;
301
2/2
✓ Branch 0 taken 545 times.
✓ Branch 1 taken 1568 times.
2113 i < last; ++i)
302 545 offset_[i] = n;
303 1568 }
304
305
306 //------------------------------------------------
307 //
308 // path_ref
309 //
310 //------------------------------------------------
311
312 2017 path_ref::
313 path_ref(
314 2017 url_impl const& impl) noexcept
315 {
316
2/2
✓ Branch 0 taken 1569 times.
✓ Branch 1 taken 448 times.
2017 if(impl.from_ == url_impl::from::url)
317 {
318 1569 impl_ = &impl;
319 }
320 else
321 {
322 448 core::string_view s = impl.get(id_path);
323 448 data_ = s.data();
324 448 size_ = s.size();
325 448 nseg_ = impl.nseg_;
326 448 dn_ = impl.decoded_[id_path];
327 }
328 2017 }
329
330 141 path_ref::
331 path_ref(
332 core::string_view s,
333 std::size_t dn,
334 141 std::size_t nseg) noexcept
335 141 : data_(s.data())
336 141 , size_(s.size())
337 , nseg_(nseg)
338 141 , dn_(dn)
339 {
340 141 }
341
342 pct_string_view
343 4475 path_ref::
344 buffer() const noexcept
345 {
346
2/2
✓ Branch 0 taken 2321 times.
✓ Branch 1 taken 2154 times.
4475 if(impl_)
347 return make_pct_string_view_unsafe(
348 2321 impl_->cs_ +
349 2321 impl_->offset(id_path),
350 2321 impl_->len(id_path),
351 4642 impl_->decoded_[id_path]);
352 return make_pct_string_view_unsafe(
353 2154 data_, size_, dn_);
354 }
355
356 std::size_t
357 3899 path_ref::
358 size() const noexcept
359 {
360
2/2
✓ Branch 0 taken 2657 times.
✓ Branch 1 taken 1242 times.
3899 if(impl_)
361 2657 return impl_->len(id_path);
362 1242 return size_;
363 }
364
365 char const*
366 12602 path_ref::
367 data() const noexcept
368 {
369
2/2
✓ Branch 0 taken 7447 times.
✓ Branch 1 taken 5155 times.
12602 if(impl_)
370 7447 return impl_->cs_ +
371 7447 impl_->offset(id_path);
372 5155 return data_;
373 }
374
375 char const*
376 4397 path_ref::
377 end() const noexcept
378 {
379
2/2
✓ Branch 0 taken 2945 times.
✓ Branch 1 taken 1452 times.
4397 if(impl_)
380 2945 return impl_->cs_ +
381 2945 impl_->offset(id_query);
382 1452 return data_ + size_;
383 }
384
385 std::size_t
386 8630 path_ref::
387 nseg() const noexcept
388 {
389
2/2
✓ Branch 0 taken 5508 times.
✓ Branch 1 taken 3122 times.
8630 if(impl_)
390 5508 return impl_->nseg_;
391 3122 return nseg_;
392 }
393
394 //------------------------------------------------
395 //
396 // query_ref
397 //
398 //------------------------------------------------
399
400 674 query_ref::
401 query_ref(
402 core::string_view s,
403 std::size_t dn,
404 674 std::size_t nparam) noexcept
405 674 : data_(s.data())
406 674 , size_(s.size())
407 , nparam_(nparam)
408 674 , dn_(dn)
409 {
410 674 }
411
412 425 query_ref::
413 query_ref(
414 425 url_impl const& impl) noexcept
415 {
416
2/2
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 81 times.
425 if(impl.from_ == url_impl::from::url)
417 {
418 344 impl_ = &impl;
419 }
420 else
421 {
422 81 core::string_view s = impl.get(id_query);
423
2/2
✓ Branch 1 taken 79 times.
✓ Branch 2 taken 2 times.
81 if (!s.empty())
424 {
425 79 s.remove_prefix(1);
426 79 question_mark_ = true;
427 }
428 81 data_ = s.data();
429 81 size_ = s.size();
430 81 nparam_ = impl.nparam_;
431 81 dn_ = impl.decoded_[id_query];
432 }
433 425 }
434
435 pct_string_view
436 454 query_ref::
437 buffer() const noexcept
438 {
439
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 452 times.
454 if(impl_)
440 {
441 2 auto pos = impl_->offset_[id_query];
442 2 auto pos1 = impl_->offset_[id_frag];
443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(pos < pos1)
444 {
445 ++pos; // no '?'
446 return make_pct_string_view_unsafe(
447 impl_->cs_ + pos,
448 pos1 - pos,
449 impl_->decoded_[id_query]);
450 }
451 // empty
452 return make_pct_string_view_unsafe(
453 2 impl_->cs_ + pos,
454 0,
455 2 0);
456 }
457 // no '?'
458 return make_pct_string_view_unsafe(
459 452 data_, size_, dn_);
460 }
461
462 // with '?'
463 std::size_t
464 5282 query_ref::
465 size() const noexcept
466 {
467
2/2
✓ Branch 0 taken 1990 times.
✓ Branch 1 taken 3292 times.
5282 if(impl_)
468 1990 return impl_->len(id_query);
469
2/2
✓ Branch 0 taken 3264 times.
✓ Branch 1 taken 28 times.
3292 if(size_ > 0)
470 3264 return size_ + 1;
471 28 return question_mark_;
472 }
473
474 // no '?'
475 char const*
476 5807 query_ref::
477 begin() const noexcept
478 {
479
2/2
✓ Branch 0 taken 2267 times.
✓ Branch 1 taken 3540 times.
5807 if(impl_)
480 {
481 // using the offset array here
482 2267 auto pos = impl_->offset_[id_query];
483 2267 auto pos1 = impl_->offset_[id_frag];
484
1/2
✓ Branch 0 taken 2267 times.
✗ Branch 1 not taken.
2267 if(pos < pos1)
485 2267 return impl_->cs_ + pos + 1; // no '?'
486 // empty
487 return impl_->cs_ + pos;
488 }
489 3540 return data_;
490
491 }
492
493 char const*
494 2282 query_ref::
495 end() const noexcept
496 {
497
2/2
✓ Branch 0 taken 902 times.
✓ Branch 1 taken 1380 times.
2282 if(impl_)
498 902 return impl_->cs_ +
499 902 impl_->offset(id_frag);
500 1380 return data_ + size_;
501 }
502
503 std::size_t
504 8886 query_ref::
505 nparam() const noexcept
506 {
507
2/2
✓ Branch 0 taken 3134 times.
✓ Branch 1 taken 5752 times.
8886 if(impl_)
508 3134 return impl_->nparam_;
509 5752 return nparam_;
510 }
511
512 #if defined(__GNUC__) && ! defined(__clang__) && defined(__MINGW32__)
513 #pragma GCC diagnostic pop
514 #endif
515
516 } // detail
517 } // urls
518 } // boost
519
520 #endif
521