GCC Code Coverage Report


Directory: libs/url/
File: libs/url/src/detail/url_impl.cpp
Date: 2023-12-15 15:31:49
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 <boost/url/detail/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 2233 url_impl::
37 apply_scheme(
38 core::string_view s) noexcept
39 {
40 2233 scheme_ = string_to_scheme(s);
41 2233 set_size(id_scheme, s.size() + 1);
42 2233 }
43
44 void
45 372 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 372 times.
372 BOOST_ASSERT(from_ == from::authority);
53
54 // userinfo
55 372 set_size(id_user, user.size());
56 372 decoded_[id_user] =
57 372 user.decoded_size();
58
2/2
✓ Branch 0 taken 243 times.
✓ Branch 1 taken 129 times.
372 if(pass)
59 {
60 243 set_size(id_pass,
61 243 pass->size() + 2);
62 243 decoded_[id_pass] =
63 243 pass->decoded_size();
64 }
65 else
66 {
67 // trailing '@'
68 129 set_size(id_pass, 1 );
69 }
70 372 }
71
72 void
73 1840 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 1840 times.
1840 BOOST_ASSERT(from_ == from::authority);
82
83 // host, port
84 1840 host_type_ = ht;
85 1840 set_size(id_host, s.size());
86 1840 decoded_[id_host] =
87 1840 s.decoded_size();
88 1840 std::memcpy(
89 1840 ip_addr_,
90 addr,
91 sizeof(ip_addr_));
92 1840 }
93
94 void
95 239 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 239 times.
239 BOOST_ASSERT(from_ == from::authority);
103
104 239 port_number_ = pn;
105 239 set_size(id_port, 1 + s.size());
106 239 }
107
108 void
109 1784 url_impl::
110 apply_authority(
111 authority_view const& a) noexcept
112 {
113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1784 times.
1784 BOOST_ASSERT(from_ != from::authority);
114
115 // userinfo
116 1784 set_size(id_user,
117 1784 a.u_.len(id_user) +
118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1784 times.
1784 (from_ == from::authority ? 0 : 2));
119 1784 set_size(id_pass, a.u_.len(id_pass));
120 1784 decoded_[id_user] = a.u_.decoded_[id_user];
121 1784 decoded_[id_pass] = a.u_.decoded_[id_pass];
122
123 // host, port
124 1784 host_type_ = a.u_.host_type_;
125 1784 port_number_ = a.u_.port_number_;
126 1784 set_size(id_host, a.u_.len(id_host));
127 1784 set_size(id_port, a.u_.len(id_port));
128 1784 std::memcpy(
129 1784 ip_addr_,
130 1784 a.u_.ip_addr_,
131 sizeof(ip_addr_));
132 1784 decoded_[id_host] = a.u_.decoded_[id_host];
133 1784 }
134
135 void
136 3499 url_impl::
137 apply_path(
138 pct_string_view s,
139 std::size_t nseg) noexcept
140 {
141 3499 set_size(id_path, s.size());
142 3499 decoded_[id_path] = s.decoded_size();
143 3499 nseg_ = detail::path_segments(s, nseg);
144 3499 }
145
146 void
147 422 url_impl::
148 apply_query(
149 pct_string_view s,
150 std::size_t n) noexcept
151 {
152 422 nparam_ = n;
153 422 set_size(id_query, 1 + s.size());
154 422 decoded_[id_query] = s.decoded_size();
155 422 }
156
157 void
158 202 url_impl::
159 apply_frag(
160 pct_string_view s) noexcept
161 {
162 202 set_size(id_frag, s.size() + 1);
163 202 decoded_[id_frag] = s.decoded_size();
164 202 }
165
166 // return length of [first, last)
167 auto
168 19899 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 19899 times.
19899 BOOST_ASSERT(first <= last);
175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19899 times.
19899 BOOST_ASSERT(last <= id_end);
176 19899 return offset(last) - offset(first);
177 }
178
179 // return length of part
180 auto
181 259476 url_impl::
182 len(int id) const noexcept ->
183 std::size_t
184 {
185 return id == id_end
186
1/2
✓ Branch 0 taken 259476 times.
✗ Branch 1 not taken.
518952 ? zero_
187 259476 : ( offset(id + 1) -
188 518952 offset(id) );
189 }
190
191 // return offset of id
192 auto
193 680082 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 629216 times.
✓ Branch 1 taken 50866 times.
680082 ? zero_
200 680082 : offset_[id];
201 }
202
203 // return id as string
204 core::string_view
205 46071 url_impl::
206 get(int id) const noexcept
207 {
208 return {
209 46071 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 2053 url_impl::
225 pct_get(
226 int id) const noexcept
227 {
228 return make_pct_string_view_unsafe(
229 2053 cs_ + offset(id),
230 len(id),
231 4106 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 18610 url_impl::
256 set_size(
257 int id,
258 std::size_t n) noexcept
259 {
260 18610 auto d = n - len(id);
261 18610 for(auto i = id + 1;
262
2/2
✓ Branch 0 taken 94389 times.
✓ Branch 1 taken 18610 times.
112999 i <= id_end; ++i)
263 94389 offset_[i] += d;
264 18610 }
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 1571 url_impl::
282 adjust(
283 int first,
284 int last,
285 std::size_t n) noexcept
286 {
287 1571 for(int i = first;
288
2/2
✓ Branch 0 taken 7003 times.
✓ Branch 1 taken 1571 times.
8574 i <= last; ++i)
289 7003 offset_[i] += n;
290 1571 }
291
292 // set [first, last) offset
293 void
294 1552 url_impl::
295 collapse(
296 int first,
297 int last,
298 std::size_t n) noexcept
299 {
300 1552 for(int i = first + 1;
301
2/2
✓ Branch 0 taken 545 times.
✓ Branch 1 taken 1552 times.
2097 i < last; ++i)
302 545 offset_[i] = n;
303 1552 }
304
305
306 //------------------------------------------------
307 //
308 // path_ref
309 //
310 //------------------------------------------------
311
312 1937 path_ref::
313 path_ref(
314 1937 url_impl const& impl) noexcept
315 {
316
2/2
✓ Branch 0 taken 1521 times.
✓ Branch 1 taken 416 times.
1937 if(impl.from_ == url_impl::from::url)
317 {
318 1521 impl_ = &impl;
319 }
320 else
321 {
322 416 core::string_view s = impl.get(id_path);
323 416 data_ = s.data();
324 416 size_ = s.size();
325 416 nseg_ = impl.nseg_;
326 416 dn_ = impl.decoded_[id_path];
327 }
328 1937 }
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 4443 path_ref::
344 buffer() const noexcept
345 {
346
2/2
✓ Branch 0 taken 2305 times.
✓ Branch 1 taken 2138 times.
4443 if(impl_)
347 return make_pct_string_view_unsafe(
348 2305 impl_->cs_ +
349 2305 impl_->offset(id_path),
350 2305 impl_->len(id_path),
351 4610 impl_->decoded_[id_path]);
352 return make_pct_string_view_unsafe(
353 2138 data_, size_, dn_);
354 }
355
356 std::size_t
357 3771 path_ref::
358 size() const noexcept
359 {
360
2/2
✓ Branch 0 taken 2561 times.
✓ Branch 1 taken 1210 times.
3771 if(impl_)
361 2561 return impl_->len(id_path);
362 1210 return size_;
363 }
364
365 char const*
366 12186 path_ref::
367 data() const noexcept
368 {
369
2/2
✓ Branch 0 taken 7319 times.
✓ Branch 1 taken 4867 times.
12186 if(impl_)
370 7319 return impl_->cs_ +
371 7319 impl_->offset(id_path);
372 4867 return data_;
373 }
374
375 char const*
376 4221 path_ref::
377 end() const noexcept
378 {
379
2/2
✓ Branch 0 taken 2913 times.
✓ Branch 1 taken 1308 times.
4221 if(impl_)
380 2913 return impl_->cs_ +
381 2913 impl_->offset(id_query);
382 1308 return data_ + size_;
383 }
384
385 std::size_t
386 8214 path_ref::
387 nseg() const noexcept
388 {
389
2/2
✓ Branch 0 taken 5428 times.
✓ Branch 1 taken 2786 times.
8214 if(impl_)
390 5428 return impl_->nseg_;
391 2786 return nseg_;
392 }
393
394 //------------------------------------------------
395 //
396 // query_ref
397 //
398 //------------------------------------------------
399
400 666 query_ref::
401 query_ref(
402 core::string_view s,
403 std::size_t dn,
404 666 std::size_t nparam) noexcept
405 666 : data_(s.data())
406 666 , size_(s.size())
407 , nparam_(nparam)
408 666 , dn_(dn)
409 {
410 666 }
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 446 query_ref::
437 buffer() const noexcept
438 {
439
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 444 times.
446 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 444 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 8878 query_ref::
505 nparam() const noexcept
506 {
507
2/2
✓ Branch 0 taken 3134 times.
✓ Branch 1 taken 5744 times.
8878 if(impl_)
508 3134 return impl_->nparam_;
509 5744 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