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