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 |