TLA Line data Source code
1 : //
2 : // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 : // Copyright (c) 2023 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_RFC_DETAIL_IMPL_RELATIVE_PART_RULE_HPP
12 : #define BOOST_URL_RFC_DETAIL_IMPL_RELATIVE_PART_RULE_HPP
13 :
14 : #include <boost/url/detail/config.hpp>
15 : #include <boost/url/rfc/detail/path_rules.hpp>
16 : #include <boost/url/rfc/pct_encoded_rule.hpp>
17 : #include <boost/url/rfc/pchars.hpp>
18 : #include <boost/url/grammar/error.hpp>
19 : #include <boost/url/grammar/parse.hpp>
20 :
21 : namespace boost {
22 : namespace urls {
23 : namespace detail {
24 :
25 : BOOST_URL_CXX20_CONSTEXPR_OR_INLINE
26 : auto
27 HIT 13131 : relative_part_rule_t::
28 : parse(
29 : char const*& it,
30 : char const* const end
31 : ) const noexcept ->
32 : system::result<value_type>
33 : {
34 13131 : constexpr auto pchars_nc = pchars - ':';
35 :
36 13131 : value_type t;
37 13131 : if(it == end)
38 : {
39 : // path-empty
40 153 : return t;
41 : }
42 12978 : if(end - it == 1)
43 : {
44 188 : if(*it == '/')
45 : {
46 : // path-absolute
47 83 : t.path = make_pct_string_view_unsafe(
48 : it, 1, 1);
49 83 : t.segment_count = 1;
50 83 : ++it;
51 83 : return t;
52 : }
53 105 : if(*it != ':')
54 : {
55 : // path-noscheme or
56 : // path-empty
57 104 : auto rv = grammar::parse(
58 : it, end, segment_rule);
59 104 : if(! rv)
60 MIS 0 : return rv.error();
61 HIT 104 : if(! rv->empty())
62 : {
63 52 : t.path = *rv;
64 52 : t.segment_count = 1;
65 : }
66 : }
67 : // path-empty
68 105 : return t;
69 : }
70 12790 : if( it[0] == '/' &&
71 675 : it[1] == '/')
72 : {
73 : // "//" authority
74 255 : it += 2;
75 : auto rv = grammar::parse(
76 255 : it, end, authority_rule);
77 255 : if(! rv)
78 MIS 0 : return rv.error();
79 HIT 255 : t.authority = *rv;
80 255 : t.has_authority = true;
81 255 : }
82 12790 : if(it == end)
83 : {
84 : // path-empty
85 129 : return t;
86 : }
87 12661 : auto const it0 = it;
88 12661 : std::size_t dn = 0;
89 12661 : if(*it != '/')
90 : {
91 : // segment_nc
92 12118 : auto rv = grammar::parse(it, end,
93 12118 : pct_encoded_rule(pchars_nc));
94 12118 : if(! rv)
95 121 : return rv.error();
96 11997 : if(rv->empty())
97 2325 : return t;
98 9672 : dn += rv->decoded_size();
99 9672 : ++t.segment_count;
100 9672 : if( it != end &&
101 9524 : *it == ':')
102 : {
103 415 : BOOST_URL_CONSTEXPR_RETURN_EC(
104 : grammar::error::mismatch);
105 : }
106 : }
107 13639 : while(it != end)
108 : {
109 12864 : if(*it == '/')
110 : {
111 2097 : ++dn;
112 2097 : ++it;
113 2097 : ++t.segment_count;
114 2097 : continue;
115 : }
116 10767 : auto rv = grammar::parse(
117 : it, end, segment_rule);
118 10767 : if(! rv)
119 4 : return rv.error();
120 10763 : if(rv->empty())
121 9021 : break;
122 1742 : dn += rv->decoded_size();
123 : }
124 9796 : t.path = make_pct_string_view_unsafe(
125 9796 : it0, it - it0, dn);
126 9796 : return t;
127 13131 : }
128 :
129 : } // detail
130 : } // urls
131 : } // boost
132 :
133 :
134 : #endif
|