GCC Code Coverage Report


Directory: libs/url/
File: boost/url/url_view_base.hpp
Date: 2024-04-08 19:38:36
Exec Total Coverage
Lines: 84 84 100.0%
Functions: 26 27 96.3%
Branches: 14 24 58.3%

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