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