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 |