Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) | ||
3 | // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com) | ||
4 | // | ||
5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
7 | // | ||
8 | // Official repository: https://github.com/boostorg/url | ||
9 | // | ||
10 | |||
11 | #ifndef BOOST_URL_URL_VIEW_BASE_HPP | ||
12 | #define BOOST_URL_URL_VIEW_BASE_HPP | ||
13 | |||
14 | #include <boost/url/detail/config.hpp> | ||
15 | #include <boost/url/authority_view.hpp> | ||
16 | #include <boost/url/host_type.hpp> | ||
17 | #include <boost/url/ipv4_address.hpp> | ||
18 | #include <boost/url/ipv6_address.hpp> | ||
19 | #include <boost/url/params_view.hpp> | ||
20 | #include <boost/url/params_encoded_view.hpp> | ||
21 | #include <boost/url/pct_string_view.hpp> | ||
22 | #include <boost/url/scheme.hpp> | ||
23 | #include <boost/url/segments_encoded_view.hpp> | ||
24 | #include <boost/url/segments_view.hpp> | ||
25 | #include <boost/url/detail/url_impl.hpp> | ||
26 | #include <boost/url/grammar/string_token.hpp> | ||
27 | #include <boost/assert.hpp> | ||
28 | #include <cstddef> | ||
29 | #include <cstdint> | ||
30 | #include <iosfwd> | ||
31 | #include <memory> | ||
32 | #include <string> | ||
33 | #include <utility> | ||
34 | |||
35 | namespace boost { | ||
36 | namespace urls { | ||
37 | |||
38 | #ifndef BOOST_URL_DOCS | ||
39 | namespace detail { | ||
40 | struct pattern; | ||
41 | } | ||
42 | #endif | ||
43 | |||
44 | |||
45 | /** Common functionality for containers | ||
46 | |||
47 | This base class is used by the library | ||
48 | to provide common member functions for | ||
49 | containers. This cannot be instantiated | ||
50 | directly; Instead, use one of the | ||
51 | containers or functions: | ||
52 | |||
53 | @par Containers | ||
54 | @li @ref url | ||
55 | @li @ref url_view | ||
56 | @li @ref static_url | ||
57 | |||
58 | @par Functions | ||
59 | @li @ref parse_absolute_uri | ||
60 | @li @ref parse_origin_form | ||
61 | @li @ref parse_relative_ref | ||
62 | @li @ref parse_uri | ||
63 | @li @ref parse_uri_reference | ||
64 | */ | ||
65 | class BOOST_URL_DECL | ||
66 | url_view_base | ||
67 | : private detail::parts_base | ||
68 | { | ||
69 | detail::url_impl impl_; | ||
70 | detail::url_impl const* pi_; | ||
71 | |||
72 | friend class url; | ||
73 | friend class url_base; | ||
74 | friend class url_view; | ||
75 | friend class static_url_base; | ||
76 | friend class params_base; | ||
77 | friend class params_encoded_base; | ||
78 | friend class params_encoded_ref; | ||
79 | friend class params_encoded_view; | ||
80 | friend class params_ref; | ||
81 | friend class params_view; | ||
82 | friend class segments_base; | ||
83 | friend class segments_encoded_base; | ||
84 | friend class segments_encoded_ref; | ||
85 | friend class segments_encoded_view; | ||
86 | friend class segments_ref; | ||
87 | friend class segments_view; | ||
88 | friend struct detail::pattern; | ||
89 | |||
90 | struct shared_impl; | ||
91 | |||
92 | url_view_base() noexcept; | ||
93 | |||
94 | explicit url_view_base( | ||
95 | detail::url_impl const&) noexcept; | ||
96 | |||
97 | ~url_view_base() = default; | ||
98 | |||
99 | url_view_base( | ||
100 | url_view_base const& o) noexcept | ||
101 | : impl_(o.impl_) | ||
102 | , pi_(o.pi_) | ||
103 | { | ||
104 | if (pi_ == &o.impl_) | ||
105 | pi_ = &impl_; | ||
106 | } | ||
107 | |||
108 | url_view_base& operator=( | ||
109 | url_view_base const&) = delete; | ||
110 | |||
111 | #ifndef BOOST_URL_DOCS | ||
112 | public: | ||
113 | #endif | ||
114 | std::size_t | ||
115 | digest(std::size_t = 0) const noexcept; | ||
116 | |||
117 | public: | ||
118 | //-------------------------------------------- | ||
119 | // | ||
120 | // Observers | ||
121 | // | ||
122 | //-------------------------------------------- | ||
123 | |||
124 | /** Return the maximum number of characters possible | ||
125 | |||
126 | This represents the largest number | ||
127 | of characters that are theoretically | ||
128 | possible to represent in a url, | ||
129 | not including any null terminator. | ||
130 | In practice the actual possible size | ||
131 | may be lower than this number. | ||
132 | |||
133 | @par Complexity | ||
134 | Constant. | ||
135 | |||
136 | @par Exception Safety | ||
137 | Throws nothing. | ||
138 | */ | ||
139 | static | ||
140 | constexpr | ||
141 | std::size_t | ||
142 | 8227 | max_size() noexcept | |
143 | { | ||
144 | 8227 | return BOOST_URL_MAX_SIZE; | |
145 | } | ||
146 | |||
147 | /** Return the number of characters in the url | ||
148 | |||
149 | This function returns the number of | ||
150 | characters in the url's encoded string, | ||
151 | not including any null terminator, | ||
152 | if present. | ||
153 | |||
154 | @par Example | ||
155 | @code | ||
156 | assert( url_view( "file:///Program%20Files" ).size() == 23 ); | ||
157 | @endcode | ||
158 | |||
159 | @par Complexity | ||
160 | Constant. | ||
161 | |||
162 | @par Exception Safety | ||
163 | Throws nothing. | ||
164 | */ | ||
165 | std::size_t | ||
166 | 40123 | size() const noexcept | |
167 | { | ||
168 | 40123 | return pi_->offset(id_end); | |
169 | } | ||
170 | |||
171 | /** Return true if the url is empty | ||
172 | |||
173 | The empty string matches the | ||
174 | <em>relative-ref</em> grammar. | ||
175 | |||
176 | @par Example | ||
177 | @code | ||
178 | assert( url_view( "" ).empty() ); | ||
179 | @endcode | ||
180 | |||
181 | @par Complexity | ||
182 | Constant. | ||
183 | |||
184 | @par Exception Safety | ||
185 | Throws nothing. | ||
186 | |||
187 | @par BNF | ||
188 | @code | ||
189 | relative-ref = relative-part [ "?" query ] [ "#" fragment ] | ||
190 | |||
191 | relative-part = "//" authority path-abempty | ||
192 | / path-absolute | ||
193 | / path-noscheme | ||
194 | / path-empty | ||
195 | @endcode | ||
196 | |||
197 | @par Specification | ||
198 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2" | ||
199 | >4.2. Relative Reference (rfc3986)</a> | ||
200 | */ | ||
201 | bool | ||
202 | 10 | empty() const noexcept | |
203 | { | ||
204 | 10 | return pi_->offset(id_end) == 0; | |
205 | } | ||
206 | |||
207 | /** Return a pointer to the url's character buffer | ||
208 | |||
209 | This function returns a pointer to | ||
210 | the first character of the url, which | ||
211 | is not guaranteed to be null-terminated. | ||
212 | |||
213 | @par Complexity | ||
214 | Constant. | ||
215 | |||
216 | @par Exception Safety | ||
217 | Throws nothing. | ||
218 | */ | ||
219 | char const* | ||
220 | 4774 | data() const noexcept | |
221 | { | ||
222 | 4774 | return pi_->cs_; | |
223 | } | ||
224 | |||
225 | /** Return the url string | ||
226 | |||
227 | This function returns the entire url, | ||
228 | which may contain percent escapes. | ||
229 | |||
230 | @par Example | ||
231 | @code | ||
232 | assert( url_view( "http://www.example.com" ).buffer() == "http://www.example.com" ); | ||
233 | @endcode | ||
234 | |||
235 | @par Complexity | ||
236 | Constant. | ||
237 | |||
238 | @par Exception Safety | ||
239 | Throws nothing. | ||
240 | */ | ||
241 | core::string_view | ||
242 | 1240 | buffer() const noexcept | |
243 | { | ||
244 | 1240 | return core::string_view( | |
245 | 1240 | data(), size()); | |
246 | } | ||
247 | |||
248 | /** Return the URL as a core::string_view | ||
249 | |||
250 | @par Complexity | ||
251 | Constant. | ||
252 | |||
253 | @par Exception Safety | ||
254 | Throws nothing. | ||
255 | |||
256 | */ | ||
257 | 250 | operator core::string_view() const noexcept | |
258 | { | ||
259 | 250 | return buffer(); | |
260 | } | ||
261 | |||
262 | /** Return a shared, persistent copy of the url | ||
263 | |||
264 | This function returns a read-only copy of | ||
265 | the url, with shared lifetime. The returned | ||
266 | value owns (persists) the underlying string. | ||
267 | The algorithm used to create the value | ||
268 | minimizes the number of individual memory | ||
269 | allocations, making it more efficient than | ||
270 | when using direct standard library functions. | ||
271 | |||
272 | @par Example | ||
273 | @code | ||
274 | std::shared_ptr< url_view const > sp; | ||
275 | { | ||
276 | std::string s( "http://example.com" ); | ||
277 | url_view u( s ); // u references characters in s | ||
278 | |||
279 | assert( u.data() == s.data() ); // same buffer | ||
280 | |||
281 | sp = u.persist(); | ||
282 | |||
283 | assert( sp->data() != s.data() ); // different buffer | ||
284 | assert( sp->buffer() == s); // same contents | ||
285 | |||
286 | // s is destroyed and thus u | ||
287 | // becomes invalid, but sp remains valid. | ||
288 | } | ||
289 | @endcode | ||
290 | |||
291 | @par Complexity | ||
292 | Linear in `this->size()`. | ||
293 | |||
294 | @par Exception Safety | ||
295 | Calls to allocate may throw. | ||
296 | */ | ||
297 | std::shared_ptr< | ||
298 | url_view const> persist() const; | ||
299 | |||
300 | //-------------------------------------------- | ||
301 | // | ||
302 | // Scheme | ||
303 | // | ||
304 | //-------------------------------------------- | ||
305 | |||
306 | /** Return true a scheme is present | ||
307 | |||
308 | This function returns true if this | ||
309 | contains a scheme. | ||
310 | |||
311 | @par Example | ||
312 | @code | ||
313 | assert( url_view( "http://www.example.com" ).has_scheme() ); | ||
314 | @endcode | ||
315 | |||
316 | @par Complexity | ||
317 | Constant. | ||
318 | |||
319 | @par Exception Safety | ||
320 | Throws nothing. | ||
321 | |||
322 | @par BNF | ||
323 | @code | ||
324 | URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] | ||
325 | |||
326 | absolute-URI = scheme ":" hier-part [ "?" query ] | ||
327 | |||
328 | scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) | ||
329 | @endcode | ||
330 | |||
331 | @par Specification | ||
332 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1" | ||
333 | >3.1. Scheme (rfc3986)</a> | ||
334 | |||
335 | @see | ||
336 | @ref scheme, | ||
337 | @ref scheme_id. | ||
338 | */ | ||
339 | bool | ||
340 | has_scheme() const noexcept; | ||
341 | |||
342 | /** Return the scheme | ||
343 | |||
344 | This function returns the scheme if it | ||
345 | exists, without a trailing colon (':'). | ||
346 | Otherwise it returns an empty string. | ||
347 | Note that schemes are case-insensitive, | ||
348 | and the canonical form is lowercased. | ||
349 | |||
350 | @par Example | ||
351 | @code | ||
352 | assert( url_view( "http://www.example.com" ).scheme() == "http" ); | ||
353 | @endcode | ||
354 | |||
355 | @par Exception Safety | ||
356 | Throws nothing. | ||
357 | |||
358 | @par BNF | ||
359 | @code | ||
360 | scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) | ||
361 | |||
362 | URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] | ||
363 | |||
364 | absolute-URI = scheme ":" hier-part [ "?" query ] | ||
365 | @endcode | ||
366 | |||
367 | @par Specification | ||
368 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1" | ||
369 | >3.1. Scheme (rfc3986)</a> | ||
370 | |||
371 | @see | ||
372 | @ref has_scheme, | ||
373 | @ref scheme_id. | ||
374 | */ | ||
375 | core::string_view | ||
376 | scheme() const noexcept; | ||
377 | |||
378 | /** Return the scheme | ||
379 | |||
380 | This function returns a value which | ||
381 | depends on the scheme in the url: | ||
382 | |||
383 | @li If the scheme is a well-known | ||
384 | scheme, corresponding value from | ||
385 | the enumeration @ref urls::scheme | ||
386 | is returned. | ||
387 | |||
388 | @li If a scheme is present but is not | ||
389 | a well-known scheme, the value | ||
390 | returned is @ref urls::scheme::unknown. | ||
391 | |||
392 | @li Otherwise, if the scheme is absent | ||
393 | the value returned is | ||
394 | @ref urls::scheme::none. | ||
395 | |||
396 | @par Example | ||
397 | @code | ||
398 | assert( url_view( "wss://www.example.com/crypto.cgi" ).scheme_id() == scheme::wss ); | ||
399 | @endcode | ||
400 | |||
401 | @par Complexity | ||
402 | Constant. | ||
403 | |||
404 | @par Exception Safety | ||
405 | Throws nothing. | ||
406 | |||
407 | @par BNF | ||
408 | @code | ||
409 | URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] | ||
410 | |||
411 | absolute-URI = scheme ":" hier-part [ "?" query ] | ||
412 | |||
413 | scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) | ||
414 | @endcode | ||
415 | |||
416 | @par Specification | ||
417 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.1" | ||
418 | >3.1. Scheme (rfc3986)</a> | ||
419 | |||
420 | @see | ||
421 | @ref has_scheme, | ||
422 | @ref scheme. | ||
423 | */ | ||
424 | urls::scheme | ||
425 | scheme_id() const noexcept; | ||
426 | |||
427 | //-------------------------------------------- | ||
428 | // | ||
429 | // Authority | ||
430 | // | ||
431 | //-------------------------------------------- | ||
432 | |||
433 | /** Return true if an authority is present | ||
434 | |||
435 | This function returns true if the url | ||
436 | contains an authority. The presence of | ||
437 | an authority is denoted by a double | ||
438 | slash ("//") at the beginning or after | ||
439 | the scheme. | ||
440 | |||
441 | @par Example | ||
442 | @code | ||
443 | assert( url_view( "http://www.example.com/index.htm" ).has_authority() ); | ||
444 | @endcode | ||
445 | |||
446 | @par Complexity | ||
447 | Constant. | ||
448 | |||
449 | @par Exception Safety | ||
450 | Throws nothing. | ||
451 | |||
452 | @par BNF | ||
453 | @code | ||
454 | authority = [ userinfo "@" ] host [ ":" port ] | ||
455 | |||
456 | URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] | ||
457 | |||
458 | absolute-URI = scheme ":" hier-part [ "?" query ] | ||
459 | |||
460 | URI-reference = URI / relative-ref | ||
461 | |||
462 | relative-ref = relative-part [ "?" query ] [ "#" fragment ] | ||
463 | |||
464 | hier-part = "//" authority path-abempty | ||
465 | ; (more...) | ||
466 | |||
467 | relative-part = "//" authority path-abempty | ||
468 | ; (more...) | ||
469 | |||
470 | @endcode | ||
471 | |||
472 | @par Specification | ||
473 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2" | ||
474 | >3.2. Authority (rfc3986)</a> | ||
475 | |||
476 | @see | ||
477 | @ref authority, | ||
478 | @ref encoded_authority. | ||
479 | */ | ||
480 | bool | ||
481 | 4446 | has_authority() const noexcept | |
482 | { | ||
483 | 4446 | return pi_->len(id_user) > 0; | |
484 | } | ||
485 | |||
486 | /** Return the authority | ||
487 | |||
488 | This function returns the authority as | ||
489 | an @ref authority_view. | ||
490 | |||
491 | @par Example | ||
492 | @code | ||
493 | authority_view a = url_view( "https://www.example.com:8080/index.htm" ).authority(); | ||
494 | @endcode | ||
495 | |||
496 | @par Complexity | ||
497 | Constant. | ||
498 | |||
499 | @par Exception Safety | ||
500 | Throws nothing. | ||
501 | |||
502 | @par BNF | ||
503 | @code | ||
504 | authority = [ userinfo "@" ] host [ ":" port ] | ||
505 | @endcode | ||
506 | |||
507 | @par Specification | ||
508 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2" | ||
509 | >3.2. Authority (rfc3986)</a> | ||
510 | |||
511 | @see | ||
512 | @ref encoded_authority, | ||
513 | @ref has_authority. | ||
514 | */ | ||
515 | authority_view | ||
516 | authority() const noexcept; | ||
517 | |||
518 | /** Return the authority. | ||
519 | |||
520 | If present, this function returns a | ||
521 | string representing the authority (which | ||
522 | may be empty). | ||
523 | Otherwise it returns an empty string. | ||
524 | The returned string may contain | ||
525 | percent escapes. | ||
526 | |||
527 | @par Example | ||
528 | @code | ||
529 | assert( url_view( "file://Network%20Drive/My%2DFiles" ).encoded_authority() == "Network%20Drive" ); | ||
530 | @endcode | ||
531 | |||
532 | @par Complexity | ||
533 | Constant. | ||
534 | |||
535 | @par Exception Safety | ||
536 | Throws nothing. | ||
537 | |||
538 | @par BNF | ||
539 | @code | ||
540 | authority = [ userinfo "@" ] host [ ":" port ] | ||
541 | @endcode | ||
542 | |||
543 | @par Specification | ||
544 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2" | ||
545 | >3.2. Authority (rfc3986)</a> | ||
546 | |||
547 | @see | ||
548 | @ref authority, | ||
549 | @ref has_authority. | ||
550 | */ | ||
551 | pct_string_view | ||
552 | encoded_authority() const noexcept; | ||
553 | |||
554 | //-------------------------------------------- | ||
555 | // | ||
556 | // Userinfo | ||
557 | // | ||
558 | //-------------------------------------------- | ||
559 | |||
560 | /** Return true if a userinfo is present | ||
561 | |||
562 | This function returns true if this | ||
563 | contains a userinfo. | ||
564 | |||
565 | @par Example | ||
566 | @code | ||
567 | assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_userinfo() ); | ||
568 | @endcode | ||
569 | |||
570 | @par Complexity | ||
571 | Constant. | ||
572 | |||
573 | @par Exception Safety | ||
574 | Throws nothing. | ||
575 | |||
576 | @par BNF | ||
577 | @code | ||
578 | userinfo = user [ ":" [ password ] ] | ||
579 | |||
580 | authority = [ userinfo "@" ] host [ ":" port ] | ||
581 | @endcode | ||
582 | |||
583 | @par Specification | ||
584 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1" | ||
585 | >3.2.1. User Information (rfc3986)</a> | ||
586 | |||
587 | @see | ||
588 | @ref has_password, | ||
589 | @ref encoded_password, | ||
590 | @ref encoded_user, | ||
591 | @ref encoded_userinfo, | ||
592 | @ref password, | ||
593 | @ref user, | ||
594 | @ref userinfo. | ||
595 | |||
596 | */ | ||
597 | bool | ||
598 | has_userinfo() const noexcept; | ||
599 | |||
600 | /** Return true if a password is present | ||
601 | |||
602 | This function returns true if the | ||
603 | userinfo is present and contains | ||
604 | a password. | ||
605 | |||
606 | @par Example | ||
607 | @code | ||
608 | assert( url_view( "http://jane%2Ddoe:pass@example.com" ).has_password() ); | ||
609 | @endcode | ||
610 | |||
611 | @par Complexity | ||
612 | Constant. | ||
613 | |||
614 | @par Exception Safety | ||
615 | Throws nothing. | ||
616 | |||
617 | @par BNF | ||
618 | @code | ||
619 | userinfo = user [ ":" [ password ] ] | ||
620 | |||
621 | user = *( unreserved / pct-encoded / sub-delims ) | ||
622 | password = *( unreserved / pct-encoded / sub-delims / ":" ) | ||
623 | @endcode | ||
624 | |||
625 | @par Specification | ||
626 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1" | ||
627 | >3.2.1. User Information (rfc3986)</a> | ||
628 | |||
629 | @see | ||
630 | @ref has_userinfo, | ||
631 | @ref encoded_password, | ||
632 | @ref encoded_user, | ||
633 | @ref encoded_userinfo, | ||
634 | @ref password, | ||
635 | @ref user, | ||
636 | @ref userinfo. | ||
637 | */ | ||
638 | bool | ||
639 | has_password() const noexcept; | ||
640 | |||
641 | /** Return the userinfo | ||
642 | |||
643 | If present, this function returns a | ||
644 | string representing the userinfo (which | ||
645 | may be empty). | ||
646 | Otherwise it returns an empty string. | ||
647 | Any percent-escapes in the string are | ||
648 | decoded first. | ||
649 | |||
650 | @note | ||
651 | This function uses the string token | ||
652 | return type customization. Depending on | ||
653 | the token passed, the return type and | ||
654 | behavior of the function can be different. | ||
655 | See @ref string_token::return_string | ||
656 | for more information. | ||
657 | |||
658 | @par Example | ||
659 | @code | ||
660 | assert( url_view( "http://jane%2Ddoe:pass@example.com" ).userinfo() == "jane-doe:pass" ); | ||
661 | @endcode | ||
662 | |||
663 | @par Complexity | ||
664 | Linear in `this->userinfo().size()`. | ||
665 | |||
666 | @par Exception Safety | ||
667 | Calls to allocate may throw. | ||
668 | |||
669 | @return When called with no arguments, | ||
670 | a value of type `std::string` is | ||
671 | returned. Otherwise, the return type | ||
672 | and meaning depends on the string token | ||
673 | passed to the function. | ||
674 | |||
675 | @par BNF | ||
676 | @code | ||
677 | userinfo = user [ ":" [ password ] ] | ||
678 | |||
679 | authority = [ userinfo "@" ] host [ ":" port ] | ||
680 | @endcode | ||
681 | |||
682 | @par Specification | ||
683 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1" | ||
684 | >3.2.1. User Information (rfc3986)</a> | ||
685 | |||
686 | @see | ||
687 | @ref has_password, | ||
688 | @ref has_userinfo, | ||
689 | @ref encoded_password, | ||
690 | @ref encoded_user, | ||
691 | @ref encoded_userinfo, | ||
692 | @ref password, | ||
693 | @ref user. | ||
694 | */ | ||
695 | template<BOOST_URL_STRTOK_TPARAM> | ||
696 | BOOST_URL_STRTOK_RETURN | ||
697 | 34 | userinfo( | |
698 | BOOST_URL_STRTOK_ARG(token)) const | ||
699 | { | ||
700 | 34 | encoding_opts opt; | |
701 | 34 | opt.space_as_plus = false; | |
702 | 68 | return encoded_userinfo().decode( | |
703 |
1/2✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
|
68 | opt, std::move(token)); |
704 | } | ||
705 | |||
706 | /** Return the userinfo | ||
707 | |||
708 | If present, this function returns a | ||
709 | string representing the userinfo (which | ||
710 | may be empty). | ||
711 | Otherwise it returns an empty string. | ||
712 | The returned string may contain | ||
713 | percent escapes. | ||
714 | |||
715 | @par Example | ||
716 | @code | ||
717 | assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_userinfo() == "jane%2Ddoe:pass" ); | ||
718 | @endcode | ||
719 | |||
720 | @par Complexity | ||
721 | Constant. | ||
722 | |||
723 | @par Exception Safety | ||
724 | Throws nothing | ||
725 | |||
726 | @par BNF | ||
727 | @code | ||
728 | userinfo = user [ ":" [ password ] ] | ||
729 | |||
730 | authority = [ userinfo "@" ] host [ ":" port ] | ||
731 | @endcode | ||
732 | |||
733 | @par Specification | ||
734 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1" | ||
735 | >3.2.1. User Information (rfc3986)</a> | ||
736 | |||
737 | @see | ||
738 | @ref has_password, | ||
739 | @ref has_userinfo, | ||
740 | @ref encoded_password, | ||
741 | @ref encoded_user, | ||
742 | @ref password, | ||
743 | @ref user, | ||
744 | @ref userinfo. | ||
745 | */ | ||
746 | pct_string_view | ||
747 | encoded_userinfo() const noexcept; | ||
748 | |||
749 | //-------------------------------------------- | ||
750 | |||
751 | /** Return the user | ||
752 | |||
753 | If present, this function returns a | ||
754 | string representing the user (which | ||
755 | may be empty). | ||
756 | Otherwise it returns an empty string. | ||
757 | Any percent-escapes in the string are | ||
758 | decoded first. | ||
759 | |||
760 | @par Example | ||
761 | @code | ||
762 | assert( url_view( "http://jane%2Ddoe:pass@example.com" ).user() == "jane-doe" ); | ||
763 | @endcode | ||
764 | |||
765 | @par Complexity | ||
766 | Linear in `this->user().size()`. | ||
767 | |||
768 | @par Exception Safety | ||
769 | Calls to allocate may throw. | ||
770 | |||
771 | @par BNF | ||
772 | @code | ||
773 | userinfo = user [ ":" [ password ] ] | ||
774 | |||
775 | user = *( unreserved / pct-encoded / sub-delims ) | ||
776 | password = *( unreserved / pct-encoded / sub-delims / ":" ) | ||
777 | @endcode | ||
778 | |||
779 | @par Specification | ||
780 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1" | ||
781 | >3.2.1. User Information (rfc3986)</a> | ||
782 | |||
783 | @see | ||
784 | @ref has_password, | ||
785 | @ref has_userinfo, | ||
786 | @ref encoded_password, | ||
787 | @ref encoded_user, | ||
788 | @ref encoded_userinfo, | ||
789 | @ref password, | ||
790 | @ref userinfo. | ||
791 | */ | ||
792 | template<BOOST_URL_STRTOK_TPARAM> | ||
793 | BOOST_URL_STRTOK_RETURN | ||
794 | 55 | user( | |
795 | BOOST_URL_STRTOK_ARG(token)) const | ||
796 | { | ||
797 | 55 | encoding_opts opt; | |
798 | 55 | opt.space_as_plus = false; | |
799 | 110 | return encoded_user().decode( | |
800 |
1/2✓ Branch 2 taken 55 times.
✗ Branch 3 not taken.
|
110 | opt, std::move(token)); |
801 | } | ||
802 | |||
803 | /** Return the user | ||
804 | |||
805 | If present, this function returns a | ||
806 | string representing the user (which | ||
807 | may be empty). | ||
808 | Otherwise it returns an empty string. | ||
809 | The returned string may contain | ||
810 | percent escapes. | ||
811 | |||
812 | @par Example | ||
813 | @code | ||
814 | assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_user() == "jane%2Ddoe" ); | ||
815 | @endcode | ||
816 | |||
817 | @par Complexity | ||
818 | Constant. | ||
819 | |||
820 | @par Exception Safety | ||
821 | Throws nothing. | ||
822 | |||
823 | @par BNF | ||
824 | @code | ||
825 | userinfo = user [ ":" [ password ] ] | ||
826 | |||
827 | user = *( unreserved / pct-encoded / sub-delims ) | ||
828 | password = *( unreserved / pct-encoded / sub-delims / ":" ) | ||
829 | @endcode | ||
830 | |||
831 | @par Specification | ||
832 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1" | ||
833 | >3.2.1. User Information (rfc3986)</a> | ||
834 | |||
835 | @see | ||
836 | @ref has_password, | ||
837 | @ref has_userinfo, | ||
838 | @ref encoded_password, | ||
839 | @ref encoded_userinfo, | ||
840 | @ref password, | ||
841 | @ref user, | ||
842 | @ref userinfo. | ||
843 | */ | ||
844 | pct_string_view | ||
845 | encoded_user() const noexcept; | ||
846 | |||
847 | /** Return the password | ||
848 | |||
849 | If present, this function returns a | ||
850 | string representing the password (which | ||
851 | may be an empty string). | ||
852 | Otherwise it returns an empty string. | ||
853 | Any percent-escapes in the string are | ||
854 | decoded first. | ||
855 | |||
856 | @par Example | ||
857 | @code | ||
858 | assert( url_view( "http://jane%2Ddoe:pass@example.com" ).password() == "pass" ); | ||
859 | @endcode | ||
860 | |||
861 | @par Complexity | ||
862 | Linear in `this->password().size()`. | ||
863 | |||
864 | @par Exception Safety | ||
865 | Calls to allocate may throw. | ||
866 | |||
867 | @par BNF | ||
868 | @code | ||
869 | userinfo = user [ ":" [ password ] ] | ||
870 | |||
871 | user = *( unreserved / pct-encoded / sub-delims ) | ||
872 | password = *( unreserved / pct-encoded / sub-delims / ":" ) | ||
873 | @endcode | ||
874 | |||
875 | @par Specification | ||
876 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1" | ||
877 | >3.2.1. User Information (rfc3986)</a> | ||
878 | |||
879 | @see | ||
880 | @ref has_password, | ||
881 | @ref has_userinfo, | ||
882 | @ref encoded_password, | ||
883 | @ref encoded_user, | ||
884 | @ref encoded_userinfo, | ||
885 | @ref user, | ||
886 | @ref userinfo. | ||
887 | */ | ||
888 | template<BOOST_URL_STRTOK_TPARAM> | ||
889 | BOOST_URL_STRTOK_RETURN | ||
890 | 25 | password( | |
891 | BOOST_URL_STRTOK_ARG(token)) const | ||
892 | { | ||
893 | 25 | encoding_opts opt; | |
894 | 25 | opt.space_as_plus = false; | |
895 | 50 | return encoded_password().decode( | |
896 |
1/2✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
|
50 | opt, std::move(token)); |
897 | } | ||
898 | |||
899 | /** Return the password | ||
900 | |||
901 | This function returns the password portion | ||
902 | of the userinfo as a percent-encoded string. | ||
903 | |||
904 | @par Example | ||
905 | @code | ||
906 | assert( url_view( "http://jane%2Ddoe:pass@example.com" ).encoded_password() == "pass" ); | ||
907 | @endcode | ||
908 | |||
909 | @par Complexity | ||
910 | Constant. | ||
911 | |||
912 | @par Exception Safety | ||
913 | Throws nothing. | ||
914 | |||
915 | @par BNF | ||
916 | @code | ||
917 | userinfo = user [ ":" [ password ] ] | ||
918 | |||
919 | user = *( unreserved / pct-encoded / sub-delims ) | ||
920 | password = *( unreserved / pct-encoded / sub-delims / ":" ) | ||
921 | @endcode | ||
922 | |||
923 | @par Specification | ||
924 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1" | ||
925 | >3.2.1. User Information (rfc3986)</a> | ||
926 | |||
927 | @see | ||
928 | @ref has_password, | ||
929 | @ref has_userinfo, | ||
930 | @ref encoded_user, | ||
931 | @ref encoded_userinfo, | ||
932 | @ref password, | ||
933 | @ref user, | ||
934 | @ref userinfo. | ||
935 | */ | ||
936 | pct_string_view | ||
937 | encoded_password() const noexcept; | ||
938 | |||
939 | //-------------------------------------------- | ||
940 | // | ||
941 | // Host | ||
942 | // | ||
943 | //-------------------------------------------- | ||
944 | |||
945 | /** Return the host type | ||
946 | |||
947 | This function returns one of the | ||
948 | following constants representing the | ||
949 | type of host present. | ||
950 | |||
951 | @li @ref host_type::ipv4 | ||
952 | @li @ref host_type::ipv6 | ||
953 | @li @ref host_type::ipvfuture | ||
954 | @li @ref host_type::name | ||
955 | @li @ref host_type::none | ||
956 | |||
957 | When @ref has_authority is false, the | ||
958 | host type is @ref host_type::none. | ||
959 | |||
960 | @par Example | ||
961 | @code | ||
962 | assert( url_view( "https://192.168.0.1/local.htm" ).host_type() == host_type::ipv4 ); | ||
963 | @endcode | ||
964 | |||
965 | @par Complexity | ||
966 | Constant. | ||
967 | |||
968 | @par Exception Safety | ||
969 | Throws nothing. | ||
970 | |||
971 | @par Specification | ||
972 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2" | ||
973 | >3.2.2. Host (rfc3986)</a> | ||
974 | */ | ||
975 | urls::host_type | ||
976 | 438 | host_type() const noexcept | |
977 | { | ||
978 | 438 | return pi_->host_type_; | |
979 | } | ||
980 | |||
981 | /** Return the host | ||
982 | |||
983 | This function returns the host portion | ||
984 | of the authority as a string, or the | ||
985 | empty string if there is no authority. | ||
986 | Any percent-escapes in the string are | ||
987 | decoded first. | ||
988 | |||
989 | @par Example | ||
990 | @code | ||
991 | assert( url_view( "https://www%2droot.example.com/" ).host() == "www-root.example.com" ); | ||
992 | @endcode | ||
993 | |||
994 | @par Complexity | ||
995 | Linear in `this->host().size()`. | ||
996 | |||
997 | @par Exception Safety | ||
998 | Calls to allocate may throw. | ||
999 | |||
1000 | @par BNF | ||
1001 | @code | ||
1002 | host = IP-literal / IPv4address / reg-name | ||
1003 | |||
1004 | IP-literal = "[" ( IPv6address / IPvFuture ) "]" | ||
1005 | |||
1006 | reg-name = *( unreserved / pct-encoded / "-" / ".") | ||
1007 | @endcode | ||
1008 | |||
1009 | @par Specification | ||
1010 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2" | ||
1011 | >3.2.2. Host (rfc3986)</a> | ||
1012 | */ | ||
1013 | template<BOOST_URL_STRTOK_TPARAM> | ||
1014 | BOOST_URL_STRTOK_RETURN | ||
1015 | 67 | host( | |
1016 | BOOST_URL_STRTOK_ARG(token)) const | ||
1017 | { | ||
1018 | 67 | encoding_opts opt; | |
1019 | 67 | opt.space_as_plus = false; | |
1020 | 134 | return encoded_host().decode( | |
1021 |
1/2✓ Branch 2 taken 65 times.
✗ Branch 3 not taken.
|
134 | opt, std::move(token)); |
1022 | } | ||
1023 | |||
1024 | /** Return the host | ||
1025 | |||
1026 | This function returns the host portion | ||
1027 | of the authority as a string, or the | ||
1028 | empty string if there is no authority. | ||
1029 | The returned string may contain | ||
1030 | percent escapes. | ||
1031 | |||
1032 | @par Example | ||
1033 | @code | ||
1034 | assert( url_view( "https://www%2droot.example.com/" ).encoded_host() == "www%2droot.example.com" ); | ||
1035 | @endcode | ||
1036 | |||
1037 | @par Complexity | ||
1038 | Constant. | ||
1039 | |||
1040 | @par Exception Safety | ||
1041 | Throws nothing. | ||
1042 | |||
1043 | @par BNF | ||
1044 | @code | ||
1045 | host = IP-literal / IPv4address / reg-name | ||
1046 | |||
1047 | IP-literal = "[" ( IPv6address / IPvFuture ) "]" | ||
1048 | |||
1049 | reg-name = *( unreserved / pct-encoded / "-" / ".") | ||
1050 | @endcode | ||
1051 | |||
1052 | @par Specification | ||
1053 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2" | ||
1054 | >3.2.2. Host (rfc3986)</a> | ||
1055 | */ | ||
1056 | pct_string_view | ||
1057 | encoded_host() const noexcept; | ||
1058 | |||
1059 | /** Return the host | ||
1060 | |||
1061 | The value returned by this function | ||
1062 | depends on the type of host returned | ||
1063 | from the function @ref host_type. | ||
1064 | |||
1065 | @li If the type is @ref host_type::ipv4, | ||
1066 | then the IPv4 address string is returned. | ||
1067 | |||
1068 | @li If the type is @ref host_type::ipv6, | ||
1069 | then the IPv6 address string is returned, | ||
1070 | without any enclosing brackets. | ||
1071 | |||
1072 | @li If the type is @ref host_type::ipvfuture, | ||
1073 | then the IPvFuture address string is returned, | ||
1074 | without any enclosing brackets. | ||
1075 | |||
1076 | @li If the type is @ref host_type::name, | ||
1077 | then the host name string is returned. | ||
1078 | Any percent-escapes in the string are | ||
1079 | decoded first. | ||
1080 | |||
1081 | @li If the type is @ref host_type::none, | ||
1082 | then an empty string is returned. | ||
1083 | |||
1084 | @par Example | ||
1085 | @code | ||
1086 | assert( url_view( "https://[1::6:c0a8:1]/" ).host_address() == "1::6:c0a8:1" ); | ||
1087 | @endcode | ||
1088 | |||
1089 | @par Complexity | ||
1090 | Linear in `this->host_address().size()`. | ||
1091 | |||
1092 | @par Exception Safety | ||
1093 | Calls to allocate may throw. | ||
1094 | |||
1095 | @par BNF | ||
1096 | @code | ||
1097 | host = IP-literal / IPv4address / reg-name | ||
1098 | |||
1099 | IP-literal = "[" ( IPv6address / IPvFuture ) "]" | ||
1100 | |||
1101 | reg-name = *( unreserved / pct-encoded / "-" / ".") | ||
1102 | @endcode | ||
1103 | |||
1104 | @par Specification | ||
1105 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2" | ||
1106 | >3.2.2. Host (rfc3986)</a> | ||
1107 | */ | ||
1108 | template<BOOST_URL_STRTOK_TPARAM> | ||
1109 | BOOST_URL_STRTOK_RETURN | ||
1110 | 98 | host_address( | |
1111 | BOOST_URL_STRTOK_ARG(token)) const | ||
1112 | { | ||
1113 | 98 | encoding_opts opt; | |
1114 | 98 | opt.space_as_plus = false; | |
1115 | 196 | return encoded_host_address().decode( | |
1116 |
1/2✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
|
196 | opt, std::move(token)); |
1117 | } | ||
1118 | |||
1119 | /** Return the host | ||
1120 | |||
1121 | The value returned by this function | ||
1122 | depends on the type of host returned | ||
1123 | from the function @ref host_type. | ||
1124 | |||
1125 | @li If the type is @ref host_type::ipv4, | ||
1126 | then the IPv4 address string is returned. | ||
1127 | |||
1128 | @li If the type is @ref host_type::ipv6, | ||
1129 | then the IPv6 address string is returned, | ||
1130 | without any enclosing brackets. | ||
1131 | |||
1132 | @li If the type is @ref host_type::ipvfuture, | ||
1133 | then the IPvFuture address string is returned, | ||
1134 | without any enclosing brackets. | ||
1135 | |||
1136 | @li If the type is @ref host_type::name, | ||
1137 | then the host name string is returned. | ||
1138 | Any percent-escapes in the string are | ||
1139 | decoded first. | ||
1140 | |||
1141 | @li If the type is @ref host_type::none, | ||
1142 | then an empty string is returned. | ||
1143 | The returned string may contain | ||
1144 | percent escapes. | ||
1145 | |||
1146 | @par Example | ||
1147 | @code | ||
1148 | assert( url_view( "https://www%2droot.example.com/" ).encoded_host_address() == "www%2droot.example.com" ); | ||
1149 | @endcode | ||
1150 | |||
1151 | @par Complexity | ||
1152 | Constant. | ||
1153 | |||
1154 | @par Exception Safety | ||
1155 | Throws nothing. | ||
1156 | |||
1157 | @par BNF | ||
1158 | @code | ||
1159 | host = IP-literal / IPv4address / reg-name | ||
1160 | |||
1161 | IP-literal = "[" ( IPv6address / IPvFuture ) "]" | ||
1162 | |||
1163 | reg-name = *( unreserved / pct-encoded / "-" / ".") | ||
1164 | @endcode | ||
1165 | |||
1166 | @par Specification | ||
1167 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2" | ||
1168 | >3.2.2. Host (rfc3986)</a> | ||
1169 | */ | ||
1170 | pct_string_view | ||
1171 | encoded_host_address() const noexcept; | ||
1172 | |||
1173 | /** Return the host IPv4 address | ||
1174 | |||
1175 | If the host type is @ref host_type::ipv4, | ||
1176 | this function returns the address as | ||
1177 | a value of type @ref ipv4_address. | ||
1178 | Otherwise, if the host type is not an IPv4 | ||
1179 | address, it returns a default-constructed | ||
1180 | value which is equal to the unspecified | ||
1181 | address "0.0.0.0". | ||
1182 | |||
1183 | @par Example | ||
1184 | @code | ||
1185 | assert( url_view( "http://127.0.0.1/index.htm?user=win95" ).host_ipv4_address() == ipv4_address( "127.0.0.1" ) ); | ||
1186 | @endcode | ||
1187 | |||
1188 | @par Complexity | ||
1189 | Constant. | ||
1190 | |||
1191 | @par Exception Safety | ||
1192 | Throws nothing. | ||
1193 | |||
1194 | @par BNF | ||
1195 | @code | ||
1196 | IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet | ||
1197 | |||
1198 | dec-octet = DIGIT ; 0-9 | ||
1199 | / %x31-39 DIGIT ; 10-99 | ||
1200 | / "1" 2DIGIT ; 100-199 | ||
1201 | / "2" %x30-34 DIGIT ; 200-249 | ||
1202 | / "25" %x30-35 ; 250-255 | ||
1203 | @endcode | ||
1204 | |||
1205 | @par Specification | ||
1206 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2" | ||
1207 | >3.2.2. Host (rfc3986)</a> | ||
1208 | */ | ||
1209 | ipv4_address | ||
1210 | host_ipv4_address() const noexcept; | ||
1211 | |||
1212 | /** Return the host IPv6 address | ||
1213 | |||
1214 | If the host type is @ref host_type::ipv6, | ||
1215 | this function returns the address as | ||
1216 | a value of type @ref ipv6_address. | ||
1217 | Otherwise, if the host type is not an IPv6 | ||
1218 | address, it returns a default-constructed | ||
1219 | value which is equal to the unspecified | ||
1220 | address "0:0:0:0:0:0:0:0". | ||
1221 | |||
1222 | @par Example | ||
1223 | @code | ||
1224 | assert( url_view( "ftp://[::1]/" ).host_ipv6_address() == ipv6_address( "::1" ) ); | ||
1225 | @endcode | ||
1226 | |||
1227 | @par Complexity | ||
1228 | Constant. | ||
1229 | |||
1230 | @par Exception Safety | ||
1231 | Throws nothing. | ||
1232 | |||
1233 | @par BNF | ||
1234 | @code | ||
1235 | IPv6address = 6( h16 ":" ) ls32 | ||
1236 | / "::" 5( h16 ":" ) ls32 | ||
1237 | / [ h16 ] "::" 4( h16 ":" ) ls32 | ||
1238 | / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 | ||
1239 | / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 | ||
1240 | / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 | ||
1241 | / [ *4( h16 ":" ) h16 ] "::" ls32 | ||
1242 | / [ *5( h16 ":" ) h16 ] "::" h16 | ||
1243 | / [ *6( h16 ":" ) h16 ] "::" | ||
1244 | |||
1245 | ls32 = ( h16 ":" h16 ) / IPv4address | ||
1246 | ; least-significant 32 bits of address | ||
1247 | |||
1248 | h16 = 1*4HEXDIG | ||
1249 | ; 16 bits of address represented in hexadecimal | ||
1250 | @endcode | ||
1251 | |||
1252 | @par Specification | ||
1253 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2" | ||
1254 | >3.2.2. Host (rfc3986)</a> | ||
1255 | */ | ||
1256 | ipv6_address | ||
1257 | host_ipv6_address() const noexcept; | ||
1258 | |||
1259 | /** Return the host IPvFuture address | ||
1260 | |||
1261 | If the host type is @ref host_type::ipvfuture, | ||
1262 | this function returns the address as | ||
1263 | a string. | ||
1264 | Otherwise, if the host type is not an | ||
1265 | IPvFuture address, it returns an | ||
1266 | empty string. | ||
1267 | |||
1268 | @par Example | ||
1269 | @code | ||
1270 | assert( url_view( "http://[v1fe.d:9]/index.htm" ).host_ipvfuture() == "v1fe.d:9" ); | ||
1271 | @endcode | ||
1272 | |||
1273 | @par Complexity | ||
1274 | Constant. | ||
1275 | |||
1276 | @par Exception Safety | ||
1277 | Throws nothing. | ||
1278 | |||
1279 | @par BNF | ||
1280 | @code | ||
1281 | IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) | ||
1282 | @endcode | ||
1283 | |||
1284 | @par Specification | ||
1285 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2" | ||
1286 | >3.2.2. Host (rfc3986)</a> | ||
1287 | */ | ||
1288 | core::string_view | ||
1289 | host_ipvfuture() const noexcept; | ||
1290 | |||
1291 | /** Return the host name | ||
1292 | |||
1293 | If the host type is @ref host_type::name, | ||
1294 | this function returns the name as | ||
1295 | a string. Otherwise an empty string is returned. | ||
1296 | Any percent-escapes in the string are | ||
1297 | decoded first. | ||
1298 | |||
1299 | @par Example | ||
1300 | @code | ||
1301 | assert( url_view( "https://www%2droot.example.com/" ).host_name() == "www-root.example.com" ); | ||
1302 | @endcode | ||
1303 | |||
1304 | @par Complexity | ||
1305 | Linear in `this->host_name().size()`. | ||
1306 | |||
1307 | @par Exception Safety | ||
1308 | Calls to allocate may throw. | ||
1309 | |||
1310 | @par BNF | ||
1311 | @code | ||
1312 | host = IP-literal / IPv4address / reg-name | ||
1313 | |||
1314 | IP-literal = "[" ( IPv6address / IPvFuture ) "]" | ||
1315 | |||
1316 | reg-name = *( unreserved / pct-encoded / "-" / ".") | ||
1317 | @endcode | ||
1318 | |||
1319 | @par Specification | ||
1320 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2" | ||
1321 | >3.2.2. Host (rfc3986)</a> | ||
1322 | */ | ||
1323 | template<BOOST_URL_STRTOK_TPARAM> | ||
1324 | BOOST_URL_STRTOK_RETURN | ||
1325 | 93 | host_name( | |
1326 | BOOST_URL_STRTOK_ARG(token)) const | ||
1327 | { | ||
1328 | 93 | encoding_opts opt; | |
1329 | 93 | opt.space_as_plus = false; | |
1330 | 186 | return encoded_host_name().decode( | |
1331 |
1/2✓ Branch 2 taken 93 times.
✗ Branch 3 not taken.
|
186 | opt, std::move(token)); |
1332 | } | ||
1333 | |||
1334 | /** Return the host name | ||
1335 | |||
1336 | If the host type is @ref host_type::name, | ||
1337 | this function returns the name as | ||
1338 | a string. | ||
1339 | Otherwise, if the host type is not an | ||
1340 | name, it returns an empty string. | ||
1341 | The returned string may contain | ||
1342 | percent escapes. | ||
1343 | |||
1344 | @par Example | ||
1345 | @code | ||
1346 | assert( url_view( "https://www%2droot.example.com/" ).encoded_host_name() == "www%2droot.example.com" ); | ||
1347 | @endcode | ||
1348 | |||
1349 | @par Complexity | ||
1350 | Constant. | ||
1351 | |||
1352 | @par Exception Safety | ||
1353 | Throws nothing. | ||
1354 | |||
1355 | @par BNF | ||
1356 | @code | ||
1357 | host = IP-literal / IPv4address / reg-name | ||
1358 | |||
1359 | IP-literal = "[" ( IPv6address / IPvFuture ) "]" | ||
1360 | |||
1361 | reg-name = *( unreserved / pct-encoded / "-" / ".") | ||
1362 | @endcode | ||
1363 | |||
1364 | @par Specification | ||
1365 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2" | ||
1366 | >3.2.2. Host (rfc3986)</a> | ||
1367 | */ | ||
1368 | pct_string_view | ||
1369 | encoded_host_name() const noexcept; | ||
1370 | |||
1371 | /** Return the IPv6 Zone ID | ||
1372 | |||
1373 | If the host type is @ref host_type::ipv6, | ||
1374 | this function returns the Zone ID as | ||
1375 | a string. Otherwise an empty string is returned. | ||
1376 | Any percent-escapes in the string are | ||
1377 | decoded first. | ||
1378 | |||
1379 | @par Example | ||
1380 | @code | ||
1381 | assert( url_view( "http://[fe80::1%25eth0]/" ).zone_id() == "eth0" ); | ||
1382 | @endcode | ||
1383 | |||
1384 | @par Complexity | ||
1385 | Linear in `this->encoded_zone_id().size()`. | ||
1386 | |||
1387 | @par Exception Safety | ||
1388 | Calls to allocate may throw. | ||
1389 | |||
1390 | @par BNF | ||
1391 | @code | ||
1392 | host = IP-literal / IPv4address / reg-name | ||
1393 | |||
1394 | IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture ) "]" | ||
1395 | |||
1396 | ZoneID = 1*( unreserved / pct-encoded ) | ||
1397 | |||
1398 | IPv6addrz = IPv6address "%25" ZoneID | ||
1399 | @endcode | ||
1400 | |||
1401 | @par Specification | ||
1402 | @li <a href="https://datatracker.ietf.org/doc/html/rfc6874" | ||
1403 | >Representing IPv6 Zone Identifiers in Address Literals and Uniform Resource Identifiers</a> | ||
1404 | */ | ||
1405 | template<BOOST_URL_STRTOK_TPARAM> | ||
1406 | BOOST_URL_STRTOK_RETURN | ||
1407 | 5 | zone_id( | |
1408 | BOOST_URL_STRTOK_ARG(token)) const | ||
1409 | { | ||
1410 | 5 | encoding_opts opt; | |
1411 | 5 | opt.space_as_plus = false; | |
1412 | 10 | return encoded_zone_id().decode( | |
1413 |
1/2✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
10 | opt, std::move(token)); |
1414 | } | ||
1415 | |||
1416 | /** Return the IPv6 Zone ID | ||
1417 | |||
1418 | If the host type is @ref host_type::ipv6, | ||
1419 | this function returns the Zone ID as | ||
1420 | a string. Otherwise an empty string is returned. | ||
1421 | The returned string may contain | ||
1422 | percent escapes. | ||
1423 | |||
1424 | @par Example | ||
1425 | @code | ||
1426 | assert( url_view( "http://[fe80::1%25eth0]/" ).encoded_zone_id() == "eth0" ); | ||
1427 | @endcode | ||
1428 | |||
1429 | @par Complexity | ||
1430 | Constant. | ||
1431 | |||
1432 | @par Exception Safety | ||
1433 | Throws nothing. | ||
1434 | |||
1435 | @par BNF | ||
1436 | @code | ||
1437 | host = IP-literal / IPv4address / reg-name | ||
1438 | |||
1439 | IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture ) "]" | ||
1440 | |||
1441 | ZoneID = 1*( unreserved / pct-encoded ) | ||
1442 | |||
1443 | IPv6addrz = IPv6address "%25" ZoneID | ||
1444 | @endcode | ||
1445 | |||
1446 | @par Specification | ||
1447 | @li <a href="https://datatracker.ietf.org/doc/html/rfc6874" | ||
1448 | >Representing IPv6 Zone Identifiers in Address Literals and Uniform Resource Identifiers</a> | ||
1449 | */ | ||
1450 | pct_string_view | ||
1451 | encoded_zone_id() const noexcept; | ||
1452 | |||
1453 | //-------------------------------------------- | ||
1454 | // | ||
1455 | // Port | ||
1456 | // | ||
1457 | //-------------------------------------------- | ||
1458 | |||
1459 | /** Return true if a port is present | ||
1460 | |||
1461 | This function returns true if an | ||
1462 | authority is present and contains a port. | ||
1463 | |||
1464 | @par Example | ||
1465 | @code | ||
1466 | assert( url_view( "wss://www.example.com:443" ).has_port() ); | ||
1467 | @endcode | ||
1468 | |||
1469 | @par Complexity | ||
1470 | Constant. | ||
1471 | |||
1472 | @par Exception Safety | ||
1473 | Throws nothing. | ||
1474 | |||
1475 | @par BNF | ||
1476 | @code | ||
1477 | authority = [ userinfo "@" ] host [ ":" port ] | ||
1478 | |||
1479 | port = *DIGIT | ||
1480 | @endcode | ||
1481 | |||
1482 | @par Specification | ||
1483 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3" | ||
1484 | >3.2.3. Port (rfc3986)</a> | ||
1485 | |||
1486 | @see | ||
1487 | @ref encoded_host_and_port, | ||
1488 | @ref port, | ||
1489 | @ref port_number. | ||
1490 | */ | ||
1491 | bool | ||
1492 | has_port() const noexcept; | ||
1493 | |||
1494 | /** Return the port | ||
1495 | |||
1496 | If present, this function returns a | ||
1497 | string representing the port (which | ||
1498 | may be empty). | ||
1499 | Otherwise it returns an empty string. | ||
1500 | |||
1501 | @par Example | ||
1502 | @code | ||
1503 | assert( url_view( "http://localhost.com:8080" ).port() == "8080" ); | ||
1504 | @endcode | ||
1505 | |||
1506 | @par Complexity | ||
1507 | Constant. | ||
1508 | |||
1509 | @par Exception Safety | ||
1510 | Throws nothing. | ||
1511 | |||
1512 | @par BNF | ||
1513 | @code | ||
1514 | port = *DIGIT | ||
1515 | @endcode | ||
1516 | |||
1517 | @par Specification | ||
1518 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3" | ||
1519 | >3.2.3. Port (rfc3986)</a> | ||
1520 | |||
1521 | @see | ||
1522 | @ref encoded_host_and_port, | ||
1523 | @ref has_port, | ||
1524 | @ref port_number. | ||
1525 | */ | ||
1526 | core::string_view | ||
1527 | port() const noexcept; | ||
1528 | |||
1529 | /** Return the port | ||
1530 | |||
1531 | If a port is present and the numerical | ||
1532 | value is representable, it is returned | ||
1533 | as an unsigned integer. Otherwise, the | ||
1534 | number zero is returned. | ||
1535 | |||
1536 | @par Example | ||
1537 | @code | ||
1538 | assert( url_view( "http://localhost.com:8080" ).port_number() == 8080 ); | ||
1539 | @endcode | ||
1540 | |||
1541 | @par Complexity | ||
1542 | Constant. | ||
1543 | |||
1544 | @par Exception Safety | ||
1545 | Throws nothing. | ||
1546 | |||
1547 | @par BNF | ||
1548 | @code | ||
1549 | port = *DIGIT | ||
1550 | @endcode | ||
1551 | |||
1552 | @par Specification | ||
1553 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3" | ||
1554 | >3.2.3. Port (rfc3986)</a> | ||
1555 | |||
1556 | @see | ||
1557 | @ref encoded_host_and_port, | ||
1558 | @ref has_port, | ||
1559 | @ref port. | ||
1560 | */ | ||
1561 | std::uint16_t | ||
1562 | port_number() const noexcept; | ||
1563 | |||
1564 | //-------------------------------------------- | ||
1565 | // | ||
1566 | // Path | ||
1567 | // | ||
1568 | //-------------------------------------------- | ||
1569 | |||
1570 | /** Return true if the path is absolute | ||
1571 | |||
1572 | This function returns true if the path | ||
1573 | begins with a forward slash ('/'). | ||
1574 | |||
1575 | @par Example | ||
1576 | @code | ||
1577 | assert( url_view( "/path/to/file.txt" ).is_path_absolute() ); | ||
1578 | @endcode | ||
1579 | |||
1580 | @par Complexity | ||
1581 | Constant. | ||
1582 | |||
1583 | @par Exception Safety | ||
1584 | Throws nothing. | ||
1585 | |||
1586 | @par BNF | ||
1587 | @code | ||
1588 | path = path-abempty ; begins with "/" or is empty | ||
1589 | / path-absolute ; begins with "/" but not "//" | ||
1590 | / path-noscheme ; begins with a non-colon segment | ||
1591 | / path-rootless ; begins with a segment | ||
1592 | / path-empty ; zero characters | ||
1593 | |||
1594 | path-abempty = *( "/" segment ) | ||
1595 | path-absolute = "/" [ segment-nz *( "/" segment ) ] | ||
1596 | path-noscheme = segment-nz-nc *( "/" segment ) | ||
1597 | path-rootless = segment-nz *( "/" segment ) | ||
1598 | path-empty = 0<pchar> | ||
1599 | @endcode | ||
1600 | |||
1601 | @par Specification | ||
1602 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3" | ||
1603 | >3.3. Path (rfc3986)</a> | ||
1604 | |||
1605 | @see | ||
1606 | @ref encoded_path, | ||
1607 | @ref encoded_segments. | ||
1608 | @ref path, | ||
1609 | @ref segments. | ||
1610 | */ | ||
1611 | bool | ||
1612 | 1466 | is_path_absolute() const noexcept | |
1613 | { | ||
1614 | return | ||
1615 |
2/2✓ Branch 1 taken 1077 times.
✓ Branch 2 taken 389 times.
|
2543 | pi_->len(id_path) > 0 && |
1616 |
2/2✓ Branch 1 taken 689 times.
✓ Branch 2 taken 388 times.
|
2543 | pi_->cs_[pi_->offset(id_path)] == '/'; |
1617 | } | ||
1618 | |||
1619 | /** Return the path | ||
1620 | |||
1621 | This function returns the path as a | ||
1622 | string. The path may be empty. | ||
1623 | Any percent-escapes in the string are | ||
1624 | decoded first. | ||
1625 | |||
1626 | @par Example | ||
1627 | @code | ||
1628 | assert( url_view( "file:///Program%20Files/Games/config.ini" ).path() == "/Program Files/Games/config.ini" ); | ||
1629 | @endcode | ||
1630 | |||
1631 | @par Complexity | ||
1632 | Linear in `this->path().size()`. | ||
1633 | |||
1634 | @par Exception Safety | ||
1635 | Calls to allocate may throw. | ||
1636 | |||
1637 | @par BNF | ||
1638 | @code | ||
1639 | path = path-abempty ; begins with "/" or is empty | ||
1640 | / path-absolute ; begins with "/" but not "//" | ||
1641 | / path-noscheme ; begins with a non-colon segment | ||
1642 | / path-rootless ; begins with a segment | ||
1643 | / path-empty ; zero characters | ||
1644 | |||
1645 | path-abempty = *( "/" segment ) | ||
1646 | path-absolute = "/" [ segment-nz *( "/" segment ) ] | ||
1647 | path-noscheme = segment-nz-nc *( "/" segment ) | ||
1648 | path-rootless = segment-nz *( "/" segment ) | ||
1649 | path-empty = 0<pchar> | ||
1650 | @endcode | ||
1651 | |||
1652 | @par Specification | ||
1653 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3" | ||
1654 | >3.3. Path (rfc3986)</a> | ||
1655 | |||
1656 | @see | ||
1657 | @ref is_path_absolute, | ||
1658 | @ref encoded_path, | ||
1659 | @ref encoded_segments. | ||
1660 | @ref segments. | ||
1661 | */ | ||
1662 | template<BOOST_URL_STRTOK_TPARAM> | ||
1663 | BOOST_URL_STRTOK_RETURN | ||
1664 | 15 | path( | |
1665 | BOOST_URL_STRTOK_ARG(token)) const | ||
1666 | { | ||
1667 | 15 | encoding_opts opt; | |
1668 | 15 | opt.space_as_plus = false; | |
1669 | 30 | return encoded_path().decode( | |
1670 |
1/2✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
|
30 | opt, std::move(token)); |
1671 | } | ||
1672 | |||
1673 | /** Return the path | ||
1674 | |||
1675 | This function returns the path as a | ||
1676 | string. The path may be empty. | ||
1677 | Any percent-escapes in the string are | ||
1678 | decoded first. | ||
1679 | |||
1680 | @par Example | ||
1681 | @code | ||
1682 | assert( url_view( "file:///Program%20Files/Games/config.ini" ).encoded_path() == "/Program%20Files/Games/config.ini" ); | ||
1683 | @endcode | ||
1684 | |||
1685 | @par Complexity | ||
1686 | Constant. | ||
1687 | |||
1688 | @par Exception Safety | ||
1689 | Throws nothing. | ||
1690 | |||
1691 | @par BNF | ||
1692 | @code | ||
1693 | path = path-abempty ; begins with "/" or is empty | ||
1694 | / path-absolute ; begins with "/" but not "//" | ||
1695 | / path-noscheme ; begins with a non-colon segment | ||
1696 | / path-rootless ; begins with a segment | ||
1697 | / path-empty ; zero characters | ||
1698 | |||
1699 | path-abempty = *( "/" segment ) | ||
1700 | path-absolute = "/" [ segment-nz *( "/" segment ) ] | ||
1701 | path-noscheme = segment-nz-nc *( "/" segment ) | ||
1702 | path-rootless = segment-nz *( "/" segment ) | ||
1703 | path-empty = 0<pchar> | ||
1704 | @endcode | ||
1705 | |||
1706 | @par Specification | ||
1707 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3" | ||
1708 | >3.3. Path (rfc3986)</a> | ||
1709 | |||
1710 | @see | ||
1711 | @ref is_path_absolute, | ||
1712 | @ref encoded_segments. | ||
1713 | @ref path, | ||
1714 | @ref segments. | ||
1715 | */ | ||
1716 | pct_string_view | ||
1717 | encoded_path() const noexcept; | ||
1718 | |||
1719 | /** Return the path as a container of segments | ||
1720 | |||
1721 | This function returns a bidirectional | ||
1722 | view of strings over the path. | ||
1723 | The returned view references the same | ||
1724 | underlying character buffer; ownership | ||
1725 | is not transferred. | ||
1726 | Any percent-escapes in strings returned | ||
1727 | when iterating the view are decoded first. | ||
1728 | |||
1729 | @par Example | ||
1730 | @code | ||
1731 | segments_view sv = url_view( "/path/to/file.txt" ).segments(); | ||
1732 | @endcode | ||
1733 | |||
1734 | @par Complexity | ||
1735 | Constant. | ||
1736 | |||
1737 | @par Exception Safety | ||
1738 | Throws nothing. | ||
1739 | |||
1740 | @par BNF | ||
1741 | @code | ||
1742 | path = [ "/" ] segment *( "/" segment ) | ||
1743 | @endcode | ||
1744 | |||
1745 | @par Specification | ||
1746 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3" | ||
1747 | >3.3. Path (rfc3986)</a> | ||
1748 | |||
1749 | @see | ||
1750 | @ref is_path_absolute, | ||
1751 | @ref encoded_path, | ||
1752 | @ref encoded_segments. | ||
1753 | @ref path, | ||
1754 | @ref segments_view. | ||
1755 | */ | ||
1756 | segments_view | ||
1757 | segments() const noexcept; | ||
1758 | |||
1759 | /** Return the path as a container of segments | ||
1760 | |||
1761 | This function returns a bidirectional | ||
1762 | view of strings over the path. | ||
1763 | The returned view references the same | ||
1764 | underlying character buffer; ownership | ||
1765 | is not transferred. | ||
1766 | Strings returned when iterating the | ||
1767 | range may contain percent escapes. | ||
1768 | |||
1769 | @par Example | ||
1770 | @code | ||
1771 | segments_encoded_view sv = url_view( "/path/to/file.txt" ).encoded_segments(); | ||
1772 | @endcode | ||
1773 | |||
1774 | @par Complexity | ||
1775 | Constant. | ||
1776 | |||
1777 | @par Exception Safety | ||
1778 | Throws nothing. | ||
1779 | |||
1780 | @par BNF | ||
1781 | @code | ||
1782 | path = path-abempty ; begins with "/" or is empty | ||
1783 | / path-absolute ; begins with "/" but not "//" | ||
1784 | / path-noscheme ; begins with a non-colon segment | ||
1785 | / path-rootless ; begins with a segment | ||
1786 | / path-empty ; zero characters | ||
1787 | |||
1788 | path-abempty = *( "/" segment ) | ||
1789 | path-absolute = "/" [ segment-nz *( "/" segment ) ] | ||
1790 | path-noscheme = segment-nz-nc *( "/" segment ) | ||
1791 | path-rootless = segment-nz *( "/" segment ) | ||
1792 | path-empty = 0<pchar> | ||
1793 | @endcode | ||
1794 | |||
1795 | @par Specification | ||
1796 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3" | ||
1797 | >3.3. Path (rfc3986)</a> | ||
1798 | |||
1799 | @see | ||
1800 | @ref is_path_absolute, | ||
1801 | @ref encoded_path, | ||
1802 | @ref path, | ||
1803 | @ref segments, | ||
1804 | @ref segments_encoded_view. | ||
1805 | */ | ||
1806 | segments_encoded_view | ||
1807 | encoded_segments() const noexcept; | ||
1808 | |||
1809 | //-------------------------------------------- | ||
1810 | // | ||
1811 | // Query | ||
1812 | // | ||
1813 | //-------------------------------------------- | ||
1814 | |||
1815 | /** Return true if a query is present | ||
1816 | |||
1817 | This function returns true if this | ||
1818 | contains a query. An empty query is | ||
1819 | distinct from having no query. | ||
1820 | |||
1821 | @par Example | ||
1822 | @code | ||
1823 | assert( url_view( "/sql?id=42&col=name&page-size=20" ).has_query() ); | ||
1824 | @endcode | ||
1825 | |||
1826 | @par Complexity | ||
1827 | Constant. | ||
1828 | |||
1829 | @par Exception Safety | ||
1830 | Throws nothing. | ||
1831 | |||
1832 | @par BNF | ||
1833 | @code | ||
1834 | query = *( pchar / "/" / "?" ) | ||
1835 | |||
1836 | query-param = key [ "=" value ] | ||
1837 | query-params = [ query-param ] *( "&" query-param ) | ||
1838 | @endcode | ||
1839 | |||
1840 | @par Specification | ||
1841 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4 | ||
1842 | >3.4. Query (rfc3986)</a> | ||
1843 | @li <a href="https://en.wikipedia.org/wiki/Query_string" | ||
1844 | >Query string (Wikipedia)</a> | ||
1845 | |||
1846 | @see | ||
1847 | @ref encoded_params, | ||
1848 | @ref encoded_query, | ||
1849 | @ref params, | ||
1850 | @ref query. | ||
1851 | */ | ||
1852 | bool | ||
1853 | has_query() const noexcept; | ||
1854 | |||
1855 | /** Return the query | ||
1856 | |||
1857 | If this contains a query, it is returned | ||
1858 | as a string (which may be empty). | ||
1859 | Otherwise, an empty string is returned. | ||
1860 | Any percent-escapes in the string are | ||
1861 | decoded first. | ||
1862 | <br> | ||
1863 | When plus signs appear in the query | ||
1864 | portion of the url, they are converted | ||
1865 | to spaces automatically upon decoding. | ||
1866 | This behavior can be changed by setting | ||
1867 | decode options. | ||
1868 | |||
1869 | @par Example | ||
1870 | @code | ||
1871 | assert( url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).query() == "id=42&name=jane-doe&page size=20" ); | ||
1872 | @endcode | ||
1873 | |||
1874 | @par Complexity | ||
1875 | Linear in `this->query().size()`. | ||
1876 | |||
1877 | @par Exception Safety | ||
1878 | Calls to allocate may throw. | ||
1879 | |||
1880 | @par BNF | ||
1881 | @code | ||
1882 | query = *( pchar / "/" / "?" ) | ||
1883 | |||
1884 | query-param = key [ "=" value ] | ||
1885 | query-params = [ query-param ] *( "&" query-param ) | ||
1886 | @endcode | ||
1887 | |||
1888 | @par Specification | ||
1889 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4 | ||
1890 | >3.4. Query (rfc3986)</a> | ||
1891 | @li <a href="https://en.wikipedia.org/wiki/Query_string" | ||
1892 | >Query string (Wikipedia)</a> | ||
1893 | |||
1894 | @see | ||
1895 | @ref encoded_params, | ||
1896 | @ref encoded_query, | ||
1897 | @ref has_query, | ||
1898 | @ref params. | ||
1899 | */ | ||
1900 | template<BOOST_URL_STRTOK_TPARAM> | ||
1901 | BOOST_URL_STRTOK_RETURN | ||
1902 | 29 | query( | |
1903 | BOOST_URL_STRTOK_ARG(token)) const | ||
1904 | { | ||
1905 | // When interacting with the query as | ||
1906 | // an intact string, we do not treat | ||
1907 | // the plus sign as an encoded space. | ||
1908 | 29 | encoding_opts opt; | |
1909 | 29 | opt.space_as_plus = false; | |
1910 | 58 | return encoded_query().decode( | |
1911 |
1/2✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
|
58 | opt, std::move(token)); |
1912 | } | ||
1913 | |||
1914 | /** Return the query | ||
1915 | |||
1916 | If this contains a query, it is returned | ||
1917 | as a string (which may be empty). | ||
1918 | Otherwise, an empty string is returned. | ||
1919 | The returned string may contain | ||
1920 | percent escapes. | ||
1921 | |||
1922 | @par Example | ||
1923 | @code | ||
1924 | assert( url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_query() == "id=42&name=jane%2Ddoe&page+size=20" ); | ||
1925 | @endcode | ||
1926 | |||
1927 | @par Complexity | ||
1928 | Constant. | ||
1929 | |||
1930 | @par Exception Safety | ||
1931 | Throws nothing. | ||
1932 | |||
1933 | @par BNF | ||
1934 | @code | ||
1935 | query = *( pchar / "/" / "?" ) | ||
1936 | |||
1937 | query-param = key [ "=" value ] | ||
1938 | query-params = [ query-param ] *( "&" query-param ) | ||
1939 | @endcode | ||
1940 | |||
1941 | @par Specification | ||
1942 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4 | ||
1943 | >3.4. Query (rfc3986)</a> | ||
1944 | @li <a href="https://en.wikipedia.org/wiki/Query_string" | ||
1945 | >Query string (Wikipedia)</a> | ||
1946 | |||
1947 | @see | ||
1948 | @ref encoded_params, | ||
1949 | @ref has_query, | ||
1950 | @ref params, | ||
1951 | @ref query. | ||
1952 | */ | ||
1953 | pct_string_view | ||
1954 | encoded_query() const noexcept; | ||
1955 | |||
1956 | /** Return the query as a container of parameters | ||
1957 | |||
1958 | This function returns a bidirectional | ||
1959 | view of key/value pairs over the query. | ||
1960 | The returned view references the same | ||
1961 | underlying character buffer; ownership | ||
1962 | is not transferred. | ||
1963 | Any percent-escapes in strings returned | ||
1964 | when iterating the view are decoded first. | ||
1965 | |||
1966 | @par Example | ||
1967 | @code | ||
1968 | params_view pv = url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).params(); | ||
1969 | @endcode | ||
1970 | |||
1971 | @par Complexity | ||
1972 | Constant. | ||
1973 | |||
1974 | @par Exception Safety | ||
1975 | Throws nothing. | ||
1976 | |||
1977 | @par BNF | ||
1978 | @code | ||
1979 | query = *( pchar / "/" / "?" ) | ||
1980 | |||
1981 | query-param = key [ "=" value ] | ||
1982 | query-params = [ query-param ] *( "&" query-param ) | ||
1983 | @endcode | ||
1984 | |||
1985 | @par Specification | ||
1986 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4 | ||
1987 | >3.4. Query (rfc3986)</a> | ||
1988 | @li <a href="https://en.wikipedia.org/wiki/Query_string" | ||
1989 | >Query string (Wikipedia)</a> | ||
1990 | |||
1991 | @see | ||
1992 | @ref encoded_params, | ||
1993 | @ref encoded_query, | ||
1994 | @ref has_query, | ||
1995 | @ref query. | ||
1996 | */ | ||
1997 | params_view | ||
1998 | params() const noexcept; | ||
1999 | |||
2000 | params_view | ||
2001 | params(encoding_opts opt) const noexcept; | ||
2002 | |||
2003 | /** Return the query as a container of parameters | ||
2004 | |||
2005 | This function returns a bidirectional | ||
2006 | view of key/value pairs over the query. | ||
2007 | The returned view references the same | ||
2008 | underlying character buffer; ownership | ||
2009 | is not transferred. | ||
2010 | Strings returned when iterating the | ||
2011 | range may contain percent escapes. | ||
2012 | |||
2013 | @par Example | ||
2014 | @code | ||
2015 | params_encoded_view pv = url_view( "/sql?id=42&name=jane%2Ddoe&page+size=20" ).encoded_params(); | ||
2016 | @endcode | ||
2017 | |||
2018 | @par Complexity | ||
2019 | Constant. | ||
2020 | |||
2021 | @par Exception Safety | ||
2022 | Throws nothing. | ||
2023 | |||
2024 | @par Specification | ||
2025 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4" | ||
2026 | >3.4. Query (rfc3986)</a> | ||
2027 | |||
2028 | @par BNF | ||
2029 | @code | ||
2030 | query = *( pchar / "/" / "?" ) | ||
2031 | |||
2032 | query-param = key [ "=" value ] | ||
2033 | query-params = [ query-param ] *( "&" query-param ) | ||
2034 | @endcode | ||
2035 | |||
2036 | @par Specification | ||
2037 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4 | ||
2038 | >3.4. Query (rfc3986)</a> | ||
2039 | @li <a href="https://en.wikipedia.org/wiki/Query_string" | ||
2040 | >Query string (Wikipedia)</a> | ||
2041 | |||
2042 | @see | ||
2043 | @ref encoded_query, | ||
2044 | @ref has_query, | ||
2045 | @ref params, | ||
2046 | @ref query. | ||
2047 | */ | ||
2048 | params_encoded_view | ||
2049 | encoded_params() const noexcept; | ||
2050 | |||
2051 | //-------------------------------------------- | ||
2052 | // | ||
2053 | // Fragment | ||
2054 | // | ||
2055 | //-------------------------------------------- | ||
2056 | |||
2057 | /** Return true if a fragment is present | ||
2058 | |||
2059 | This function returns true if the url | ||
2060 | contains a fragment. | ||
2061 | An empty fragment is distinct from | ||
2062 | no fragment. | ||
2063 | |||
2064 | @par Example | ||
2065 | @code | ||
2066 | assert( url_view( "http://www.example.com/index.htm#anchor" ).has_fragment() ); | ||
2067 | @endcode | ||
2068 | |||
2069 | @par Complexity | ||
2070 | Constant. | ||
2071 | |||
2072 | @par Exception Safety | ||
2073 | Throws nothing. | ||
2074 | |||
2075 | @par BNF | ||
2076 | @code | ||
2077 | URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] | ||
2078 | |||
2079 | relative-ref = relative-part [ "?" query ] [ "#" fragment ] | ||
2080 | @endcode | ||
2081 | |||
2082 | @par Specification | ||
2083 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5" | ||
2084 | >3.5. Fragment (rfc3986)</a> | ||
2085 | |||
2086 | @see | ||
2087 | @ref encoded_fragment, | ||
2088 | @ref fragment. | ||
2089 | */ | ||
2090 | bool | ||
2091 | has_fragment() const noexcept; | ||
2092 | |||
2093 | /** Return the fragment | ||
2094 | |||
2095 | This function calculates the fragment | ||
2096 | of the url, with percent escapes decoded | ||
2097 | and without the leading pound sign ('#') | ||
2098 | whose presence indicates that the url | ||
2099 | contains a fragment. | ||
2100 | |||
2101 | <br> | ||
2102 | |||
2103 | This function accepts an optional | ||
2104 | <em>StringToken</em> parameter which | ||
2105 | controls the return type and behavior | ||
2106 | of the function: | ||
2107 | |||
2108 | @li When called with no arguments, | ||
2109 | the return type of the function is | ||
2110 | `std::string`. Otherwise | ||
2111 | |||
2112 | @li When called with a string token, | ||
2113 | the behavior and return type of the | ||
2114 | function depends on the type of string | ||
2115 | token being passed. | ||
2116 | |||
2117 | @par Example | ||
2118 | @code | ||
2119 | assert( url_view( "http://www.example.com/index.htm#a%2D1" ).fragment() == "a-1" ); | ||
2120 | @endcode | ||
2121 | |||
2122 | @par Complexity | ||
2123 | Linear in `this->fragment().size()`. | ||
2124 | |||
2125 | @par Exception Safety | ||
2126 | Calls to allocate may throw. | ||
2127 | String tokens may throw exceptions. | ||
2128 | |||
2129 | @param token An optional string token to | ||
2130 | use. If this parameter is omitted, the | ||
2131 | function returns a new `std::string`. | ||
2132 | |||
2133 | @par BNF | ||
2134 | @code | ||
2135 | fragment = *( pchar / "/" / "?" ) | ||
2136 | |||
2137 | fragment-part = [ "#" fragment ] | ||
2138 | @endcode | ||
2139 | |||
2140 | @par Specification | ||
2141 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5" | ||
2142 | >3.5. Fragment (rfc3986)</a> | ||
2143 | |||
2144 | @see | ||
2145 | @ref encoded_fragment, | ||
2146 | @ref has_fragment. | ||
2147 | */ | ||
2148 | template<BOOST_URL_STRTOK_TPARAM> | ||
2149 | BOOST_URL_STRTOK_RETURN | ||
2150 | 17 | fragment( | |
2151 | BOOST_URL_STRTOK_ARG(token)) const | ||
2152 | { | ||
2153 | 17 | encoding_opts opt; | |
2154 | 17 | opt.space_as_plus = false; | |
2155 | 34 | return encoded_fragment().decode( | |
2156 |
1/2✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
|
34 | opt, std::move(token)); |
2157 | } | ||
2158 | |||
2159 | /** Return the fragment | ||
2160 | |||
2161 | This function returns the fragment as a | ||
2162 | string with percent-escapes. | ||
2163 | Ownership is not transferred; the | ||
2164 | string returned references the underlying | ||
2165 | character buffer, which must remain valid | ||
2166 | or else undefined behavior occurs. | ||
2167 | |||
2168 | @par Example | ||
2169 | @code | ||
2170 | assert( url_view( "http://www.example.com/index.htm#a%2D1" ).encoded_fragment() == "a%2D1" ); | ||
2171 | @endcode | ||
2172 | |||
2173 | @par Complexity | ||
2174 | Constant. | ||
2175 | |||
2176 | @par Exception Safety | ||
2177 | Throws nothing. | ||
2178 | |||
2179 | @par BNF | ||
2180 | @code | ||
2181 | fragment = *( pchar / "/" / "?" ) | ||
2182 | |||
2183 | pchar = unreserved / pct-encoded / sub-delims / ":" / "@" | ||
2184 | @endcode | ||
2185 | |||
2186 | @par Specification | ||
2187 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.5" | ||
2188 | >3.5. Fragment (rfc3986)</a> | ||
2189 | |||
2190 | @see | ||
2191 | @ref fragment, | ||
2192 | @ref has_fragment. | ||
2193 | */ | ||
2194 | pct_string_view | ||
2195 | encoded_fragment() const noexcept; | ||
2196 | |||
2197 | //-------------------------------------------- | ||
2198 | // | ||
2199 | // Compound Fields | ||
2200 | // | ||
2201 | //-------------------------------------------- | ||
2202 | |||
2203 | /** Return the host and port | ||
2204 | |||
2205 | If an authority is present, this | ||
2206 | function returns the host and optional | ||
2207 | port as a string, which may be empty. | ||
2208 | Otherwise it returns an empty string. | ||
2209 | The returned string may contain | ||
2210 | percent escapes. | ||
2211 | |||
2212 | @par Example | ||
2213 | @code | ||
2214 | assert( url_view( "http://www.example.com:8080/index.htm" ).encoded_host_and_port() == "www.example.com:8080" ); | ||
2215 | @endcode | ||
2216 | |||
2217 | @par Complexity | ||
2218 | Constant. | ||
2219 | |||
2220 | @par Exception Safety | ||
2221 | Throws nothing. | ||
2222 | |||
2223 | @par BNF | ||
2224 | @code | ||
2225 | authority = [ userinfo "@" ] host [ ":" port ] | ||
2226 | @endcode | ||
2227 | |||
2228 | @par Specification | ||
2229 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2" | ||
2230 | >3.2.2. Host (rfc3986)</a> | ||
2231 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.3" | ||
2232 | >3.2.3. Port (rfc3986)</a> | ||
2233 | |||
2234 | @see | ||
2235 | @ref has_port, | ||
2236 | @ref port, | ||
2237 | @ref port_number. | ||
2238 | */ | ||
2239 | pct_string_view | ||
2240 | encoded_host_and_port() const noexcept; | ||
2241 | |||
2242 | /** Return the origin | ||
2243 | |||
2244 | If an authority is present, this | ||
2245 | function returns the scheme and | ||
2246 | authority portion of the url. | ||
2247 | Otherwise, an empty string is | ||
2248 | returned. | ||
2249 | The returned string may contain | ||
2250 | percent escapes. | ||
2251 | |||
2252 | @par Example | ||
2253 | @code | ||
2254 | assert( url_view( "http://www.example.com:8080/index.htm?text=none#h1" ).encoded_origin() == "http://www.example.com:8080" ); | ||
2255 | @endcode | ||
2256 | |||
2257 | @par Complexity | ||
2258 | Constant. | ||
2259 | |||
2260 | @par Exception Safety | ||
2261 | Throws nothing. | ||
2262 | |||
2263 | @see | ||
2264 | @ref encoded_resource, | ||
2265 | @ref encoded_target. | ||
2266 | */ | ||
2267 | pct_string_view | ||
2268 | encoded_origin() const noexcept; | ||
2269 | |||
2270 | /** Return the resource | ||
2271 | |||
2272 | This function returns the resource, which | ||
2273 | is the portion of the url that includes | ||
2274 | only the path, query, and fragment. | ||
2275 | The returned string may contain | ||
2276 | percent escapes. | ||
2277 | |||
2278 | @par Example | ||
2279 | @code | ||
2280 | assert( url_view( "http://www.example.com/index.html?query#frag" ).encoded_resource() == "/index.html?query#frag" ); | ||
2281 | @endcode | ||
2282 | |||
2283 | @par Complexity | ||
2284 | Constant. | ||
2285 | |||
2286 | @par Exception Safety | ||
2287 | Throws nothing. | ||
2288 | |||
2289 | @par Specification | ||
2290 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3" | ||
2291 | >3.3. Path (rfc3986)</a> | ||
2292 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4" | ||
2293 | >3.4. Query (rfc3986)</a> | ||
2294 | |||
2295 | @see | ||
2296 | @ref encoded_origin, | ||
2297 | @ref encoded_target. | ||
2298 | */ | ||
2299 | pct_string_view | ||
2300 | encoded_resource() const noexcept; | ||
2301 | |||
2302 | /** Return the target | ||
2303 | |||
2304 | This function returns the target, which | ||
2305 | is the portion of the url that includes | ||
2306 | only the path and query. | ||
2307 | The returned string may contain | ||
2308 | percent escapes. | ||
2309 | |||
2310 | @par Example | ||
2311 | @code | ||
2312 | assert( url_view( "http://www.example.com/index.html?query#frag" ).encoded_target() == "/index.html?query" ); | ||
2313 | @endcode | ||
2314 | |||
2315 | @par Complexity | ||
2316 | Constant. | ||
2317 | |||
2318 | @par Exception Safety | ||
2319 | Throws nothing. | ||
2320 | |||
2321 | @par Specification | ||
2322 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.3" | ||
2323 | >3.3. Path (rfc3986)</a> | ||
2324 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4" | ||
2325 | >3.4. Query (rfc3986)</a> | ||
2326 | |||
2327 | @see | ||
2328 | @ref encoded_origin, | ||
2329 | @ref encoded_resource. | ||
2330 | */ | ||
2331 | pct_string_view | ||
2332 | encoded_target() const noexcept; | ||
2333 | |||
2334 | //-------------------------------------------- | ||
2335 | // | ||
2336 | // Comparison | ||
2337 | // | ||
2338 | //-------------------------------------------- | ||
2339 | |||
2340 | /** Return the result of comparing this with another url | ||
2341 | |||
2342 | This function compares two URLs | ||
2343 | according to Syntax-Based comparison | ||
2344 | algorithm. | ||
2345 | |||
2346 | @par Complexity | ||
2347 | Linear in `min( u0.size(), u1.size() )` | ||
2348 | |||
2349 | @par Exception Safety | ||
2350 | Throws nothing. | ||
2351 | |||
2352 | @par Specification | ||
2353 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" | ||
2354 | >6.2.2 Syntax-Based Normalization (rfc3986)</a> | ||
2355 | |||
2356 | @return -1 if `*this < other`, 0 if | ||
2357 | `this == other`, and 1 if `this > other`. | ||
2358 | */ | ||
2359 | int | ||
2360 | compare(url_view_base const& other) const noexcept; | ||
2361 | |||
2362 | /** Return the result of comparing two URLs | ||
2363 | |||
2364 | The URLs are compared component by | ||
2365 | component as if they were first | ||
2366 | normalized. | ||
2367 | |||
2368 | @par Example | ||
2369 | @code | ||
2370 | url_view u0( "http://www.a.com/index.htm" ); | ||
2371 | url_view u1( "http://www.a.com/index.htm" ); | ||
2372 | assert( u0 == u1 ); | ||
2373 | @endcode | ||
2374 | |||
2375 | @par Effects | ||
2376 | @code | ||
2377 | url a(u0); | ||
2378 | a.normalize(); | ||
2379 | url b(u1); | ||
2380 | b.normalize(); | ||
2381 | return std::make_tuple( | ||
2382 | a.scheme(), | ||
2383 | a.user(), | ||
2384 | a.password(), | ||
2385 | a.host(), | ||
2386 | a.port(), | ||
2387 | a.path(), | ||
2388 | a.query(), | ||
2389 | a.fragment()) == | ||
2390 | std::make_tuple( | ||
2391 | b.scheme(), | ||
2392 | b.user(), | ||
2393 | b.password(), | ||
2394 | b.host(), | ||
2395 | b.port(), | ||
2396 | b.path(), | ||
2397 | b.query(), | ||
2398 | b.fragment()); | ||
2399 | @endcode | ||
2400 | |||
2401 | @par Complexity | ||
2402 | Linear in `min( u0.size(), u1.size() )` | ||
2403 | |||
2404 | @par Exception Safety | ||
2405 | Throws nothing | ||
2406 | |||
2407 | @return `true` if `u0 == u1` | ||
2408 | |||
2409 | @par Specification | ||
2410 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" | ||
2411 | >6.2.2 Syntax-Based Normalization (rfc3986)</a> | ||
2412 | */ | ||
2413 | friend | ||
2414 | bool | ||
2415 | 66 | operator==( | |
2416 | url_view_base const& u0, | ||
2417 | url_view_base const& u1) noexcept | ||
2418 | { | ||
2419 | 66 | return u0.compare(u1) == 0; | |
2420 | } | ||
2421 | |||
2422 | /** Return the result of comparing two URLs | ||
2423 | |||
2424 | The URLs are compared component by | ||
2425 | component as if they were first | ||
2426 | normalized. | ||
2427 | |||
2428 | @par Example | ||
2429 | @code | ||
2430 | url_view u0( "http://www.a.com/index.htm" ); | ||
2431 | url_view u1( "http://www.b.com/index.htm" ); | ||
2432 | assert( u0 != u1 ); | ||
2433 | @endcode | ||
2434 | |||
2435 | @par Effects | ||
2436 | @code | ||
2437 | url a(u0); | ||
2438 | a.normalize(); | ||
2439 | url b(u1); | ||
2440 | b.normalize(); | ||
2441 | return std::make_tuple( | ||
2442 | a.scheme(), | ||
2443 | a.user(), | ||
2444 | a.password(), | ||
2445 | a.host(), | ||
2446 | a.port(), | ||
2447 | a.path(), | ||
2448 | a.query(), | ||
2449 | a.fragment()) != | ||
2450 | std::make_tuple( | ||
2451 | b.scheme(), | ||
2452 | b.user(), | ||
2453 | b.password(), | ||
2454 | b.host(), | ||
2455 | b.port(), | ||
2456 | b.path(), | ||
2457 | b.query(), | ||
2458 | b.fragment()); | ||
2459 | @endcode | ||
2460 | |||
2461 | @par Complexity | ||
2462 | Linear in `min( u0.size(), u1.size() )` | ||
2463 | |||
2464 | @par Exception Safety | ||
2465 | Throws nothing | ||
2466 | |||
2467 | @return `true` if `u0 != u1` | ||
2468 | |||
2469 | @par Specification | ||
2470 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" | ||
2471 | >6.2.2 Syntax-Based Normalization (rfc3986)</a> | ||
2472 | */ | ||
2473 | friend | ||
2474 | bool | ||
2475 | 20 | operator!=( | |
2476 | url_view_base const& u0, | ||
2477 | url_view_base const& u1) noexcept | ||
2478 | { | ||
2479 | 20 | return ! (u0 == u1); | |
2480 | } | ||
2481 | |||
2482 | /** Return the result of comparing two URLs | ||
2483 | |||
2484 | The URLs are compared component by | ||
2485 | component as if they were first | ||
2486 | normalized. | ||
2487 | |||
2488 | @par Example | ||
2489 | @code | ||
2490 | url_view u0( "http://www.a.com/index.htm" ); | ||
2491 | url_view u1( "http://www.b.com/index.htm" ); | ||
2492 | assert( u0 < u1 ); | ||
2493 | @endcode | ||
2494 | |||
2495 | @par Effects | ||
2496 | @code | ||
2497 | url a(u0); | ||
2498 | a.normalize(); | ||
2499 | url b(u1); | ||
2500 | b.normalize(); | ||
2501 | return std::make_tuple( | ||
2502 | a.scheme(), | ||
2503 | a.user(), | ||
2504 | a.password(), | ||
2505 | a.host(), | ||
2506 | a.port(), | ||
2507 | a.path(), | ||
2508 | a.query(), | ||
2509 | a.fragment()) < | ||
2510 | std::make_tuple( | ||
2511 | b.scheme(), | ||
2512 | b.user(), | ||
2513 | b.password(), | ||
2514 | b.host(), | ||
2515 | b.port(), | ||
2516 | b.path(), | ||
2517 | b.query(), | ||
2518 | b.fragment()); | ||
2519 | @endcode | ||
2520 | |||
2521 | @par Complexity | ||
2522 | Linear in `min( u0.size(), u1.size() )` | ||
2523 | |||
2524 | @par Exception Safety | ||
2525 | Throws nothing | ||
2526 | |||
2527 | @return `true` if `u0 < u1` | ||
2528 | |||
2529 | @par Specification | ||
2530 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" | ||
2531 | >6.2.2 Syntax-Based Normalization (rfc3986)</a> | ||
2532 | */ | ||
2533 | friend | ||
2534 | bool | ||
2535 | 18 | operator<( | |
2536 | url_view_base const& u0, | ||
2537 | url_view_base const& u1) noexcept | ||
2538 | { | ||
2539 | 18 | return u0.compare(u1) < 0; | |
2540 | } | ||
2541 | |||
2542 | /** Return the result of comparing two URLs | ||
2543 | |||
2544 | The URLs are compared component by | ||
2545 | component as if they were first | ||
2546 | normalized. | ||
2547 | |||
2548 | @par Example | ||
2549 | @code | ||
2550 | url_view u0( "http://www.b.com/index.htm" ); | ||
2551 | url_view u1( "http://www.b.com/index.htm" ); | ||
2552 | assert( u0 <= u1 ); | ||
2553 | @endcode | ||
2554 | |||
2555 | @par Effects | ||
2556 | @code | ||
2557 | url a(u0); | ||
2558 | a.normalize(); | ||
2559 | url b(u1); | ||
2560 | b.normalize(); | ||
2561 | return std::make_tuple( | ||
2562 | a.scheme(), | ||
2563 | a.user(), | ||
2564 | a.password(), | ||
2565 | a.host(), | ||
2566 | a.port(), | ||
2567 | a.path(), | ||
2568 | a.query(), | ||
2569 | a.fragment()) <= | ||
2570 | std::make_tuple( | ||
2571 | b.scheme(), | ||
2572 | b.user(), | ||
2573 | b.password(), | ||
2574 | b.host(), | ||
2575 | b.port(), | ||
2576 | b.path(), | ||
2577 | b.query(), | ||
2578 | b.fragment()); | ||
2579 | @endcode | ||
2580 | |||
2581 | @par Complexity | ||
2582 | Linear in `min( u0.size(), u1.size() )` | ||
2583 | |||
2584 | @par Exception Safety | ||
2585 | Throws nothing | ||
2586 | |||
2587 | @return `true` if `u0 <= u1` | ||
2588 | |||
2589 | @par Specification | ||
2590 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" | ||
2591 | >6.2.2 Syntax-Based Normalization (rfc3986)</a> | ||
2592 | */ | ||
2593 | friend | ||
2594 | bool | ||
2595 | 18 | operator<=( | |
2596 | url_view_base const& u0, | ||
2597 | url_view_base const& u1) noexcept | ||
2598 | { | ||
2599 | 18 | return u0.compare(u1) <= 0; | |
2600 | } | ||
2601 | |||
2602 | /** Return the result of comparing two URLs | ||
2603 | |||
2604 | The URLs are compared component by | ||
2605 | component as if they were first | ||
2606 | normalized. | ||
2607 | |||
2608 | @par Example | ||
2609 | @code | ||
2610 | url_view u0( "http://www.b.com/index.htm" ); | ||
2611 | url_view u1( "http://www.a.com/index.htm" ); | ||
2612 | assert( u0 > u1 ); | ||
2613 | @endcode | ||
2614 | |||
2615 | @par Effects | ||
2616 | @code | ||
2617 | url a(u0); | ||
2618 | a.normalize(); | ||
2619 | url b(u1); | ||
2620 | b.normalize(); | ||
2621 | return std::make_tuple( | ||
2622 | a.scheme(), | ||
2623 | a.user(), | ||
2624 | a.password(), | ||
2625 | a.host(), | ||
2626 | a.port(), | ||
2627 | a.path(), | ||
2628 | a.query(), | ||
2629 | a.fragment()) > | ||
2630 | std::make_tuple( | ||
2631 | b.scheme(), | ||
2632 | b.user(), | ||
2633 | b.password(), | ||
2634 | b.host(), | ||
2635 | b.port(), | ||
2636 | b.path(), | ||
2637 | b.query(), | ||
2638 | b.fragment()); | ||
2639 | @endcode | ||
2640 | |||
2641 | @par Complexity | ||
2642 | Linear in `min( u0.size(), u1.size() )` | ||
2643 | |||
2644 | @par Exception Safety | ||
2645 | Throws nothing | ||
2646 | |||
2647 | @return `true` if `u0 > u1` | ||
2648 | |||
2649 | @par Specification | ||
2650 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" | ||
2651 | >6.2.2 Syntax-Based Normalization (rfc3986)</a> | ||
2652 | */ | ||
2653 | friend | ||
2654 | bool | ||
2655 | 18 | operator>( | |
2656 | url_view_base const& u0, | ||
2657 | url_view_base const& u1) noexcept | ||
2658 | { | ||
2659 | 18 | return u0.compare(u1) > 0; | |
2660 | } | ||
2661 | |||
2662 | /** Return the result of comparing two URLs | ||
2663 | |||
2664 | The URLs are compared component by | ||
2665 | component as if they were first | ||
2666 | normalized. | ||
2667 | |||
2668 | @par Example | ||
2669 | @code | ||
2670 | url_view u0( "http://www.a.com/index.htm" ); | ||
2671 | url_view u1( "http://www.a.com/index.htm" ); | ||
2672 | assert( u0 >= u1 ); | ||
2673 | @endcode | ||
2674 | |||
2675 | @par Effects | ||
2676 | @code | ||
2677 | url a(u0); | ||
2678 | a.normalize(); | ||
2679 | url b(u1); | ||
2680 | b.normalize(); | ||
2681 | return std::make_tuple( | ||
2682 | a.scheme(), | ||
2683 | a.user(), | ||
2684 | a.password(), | ||
2685 | a.host(), | ||
2686 | a.port(), | ||
2687 | a.path(), | ||
2688 | a.query(), | ||
2689 | a.fragment()) >= | ||
2690 | std::make_tuple( | ||
2691 | b.scheme(), | ||
2692 | b.user(), | ||
2693 | b.password(), | ||
2694 | b.host(), | ||
2695 | b.port(), | ||
2696 | b.path(), | ||
2697 | b.query(), | ||
2698 | b.fragment()); | ||
2699 | @endcode | ||
2700 | |||
2701 | @par Complexity | ||
2702 | Linear in `min( u0.size(), u1.size() )` | ||
2703 | |||
2704 | @par Exception Safety | ||
2705 | Throws nothing | ||
2706 | |||
2707 | @return `true` if `u0 >= u1` | ||
2708 | |||
2709 | @par Specification | ||
2710 | @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2" | ||
2711 | >6.2.2 Syntax-Based Normalization (rfc3986)</a> | ||
2712 | */ | ||
2713 | friend | ||
2714 | bool | ||
2715 | 18 | operator>=( | |
2716 | url_view_base const& u0, | ||
2717 | url_view_base const& u1) noexcept | ||
2718 | { | ||
2719 | 18 | return u0.compare(u1) >= 0; | |
2720 | } | ||
2721 | |||
2722 | friend | ||
2723 | std::ostream& | ||
2724 | 5 | operator<<( | |
2725 | std::ostream& os, | ||
2726 | url_view_base const& u) | ||
2727 | { | ||
2728 | 5 | return os << u.buffer(); | |
2729 | } | ||
2730 | |||
2731 | private: | ||
2732 | //-------------------------------------------- | ||
2733 | // | ||
2734 | // implementation | ||
2735 | // | ||
2736 | //-------------------------------------------- | ||
2737 | static | ||
2738 | int | ||
2739 | segments_compare( | ||
2740 | segments_encoded_view seg0, | ||
2741 | segments_encoded_view seg1) noexcept; | ||
2742 | }; | ||
2743 | |||
2744 | //------------------------------------------------ | ||
2745 | |||
2746 | /** Format the url to the output stream | ||
2747 | |||
2748 | This function serializes the url to | ||
2749 | the specified output stream. Any | ||
2750 | percent-escapes are emitted as-is; | ||
2751 | no decoding is performed. | ||
2752 | |||
2753 | @par Example | ||
2754 | @code | ||
2755 | url_view u( "http://www.example.com/index.htm" ); | ||
2756 | std::stringstream ss; | ||
2757 | ss << u; | ||
2758 | assert( ss.str() == "http://www.example.com/index.htm" ); | ||
2759 | @endcode | ||
2760 | |||
2761 | @par Effects | ||
2762 | @code | ||
2763 | return os << u.buffer(); | ||
2764 | @endcode | ||
2765 | |||
2766 | @par Complexity | ||
2767 | Linear in `u.buffer().size()` | ||
2768 | |||
2769 | @par Exception Safety | ||
2770 | Basic guarantee. | ||
2771 | |||
2772 | @return A reference to the output stream, for chaining | ||
2773 | |||
2774 | @param os The output stream to write to. | ||
2775 | |||
2776 | @param u The url to write. | ||
2777 | */ | ||
2778 | std::ostream& | ||
2779 | operator<<( | ||
2780 | std::ostream& os, | ||
2781 | url_view_base const& u); | ||
2782 | |||
2783 | } // urls | ||
2784 | } // boost | ||
2785 | |||
2786 | #endif | ||
2787 |