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 13282 : 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 13282 : constexpr auto pchars_nc = pchars - ':';
35 :
36 13282 : value_type t;
37 13282 : if(it == end)
38 : {
39 : // path-empty
40 159 : return t;
41 : }
42 13123 : if(end - it == 1)
43 : {
44 203 : if(*it == '/')
45 : {
46 : // path-absolute
47 94 : t.path = make_pct_string_view_unsafe(
48 : it, 1, 1);
49 94 : t.segment_count = 1;
50 94 : ++it;
51 94 : return t;
52 : }
53 109 : if(*it != ':')
54 : {
55 : // path-noscheme or
56 : // path-empty
57 108 : auto rv = grammar::parse(
58 : it, end, segment_rule);
59 108 : if(! rv)
60 MIS 0 : return rv.error();
61 HIT 108 : if(! rv->empty())
62 : {
63 56 : t.path = *rv;
64 56 : t.segment_count = 1;
65 : }
66 : }
67 : // path-empty
68 109 : return t;
69 : }
70 12920 : if( it[0] == '/' &&
71 733 : it[1] == '/')
72 : {
73 : // "//" authority
74 258 : it += 2;
75 : auto rv = grammar::parse(
76 258 : it, end, authority_rule);
77 258 : if(! rv)
78 MIS 0 : return rv.error();
79 HIT 258 : t.authority = *rv;
80 258 : t.has_authority = true;
81 258 : }
82 12920 : if(it == end)
83 : {
84 : // path-empty
85 129 : return t;
86 : }
87 12791 : auto const it0 = it;
88 12791 : std::size_t dn = 0;
89 12791 : if(*it != '/')
90 : {
91 : // segment_nc
92 12190 : auto rv = grammar::parse(it, end,
93 12190 : pct_encoded_rule(pchars_nc));
94 12190 : if(! rv)
95 121 : return rv.error();
96 12069 : if(rv->empty())
97 2329 : return t;
98 9740 : dn += rv->decoded_size();
99 9740 : ++t.segment_count;
100 9740 : if( it != end &&
101 9585 : *it == ':')
102 : {
103 415 : BOOST_URL_CONSTEXPR_RETURN_EC(
104 : grammar::error::mismatch);
105 : }
106 : }
107 14171 : while(it != end)
108 : {
109 13271 : if(*it == '/')
110 : {
111 2345 : ++dn;
112 2345 : ++it;
113 2345 : ++t.segment_count;
114 2345 : continue;
115 : }
116 10926 : auto rv = grammar::parse(
117 : it, end, segment_rule);
118 10926 : if(! rv)
119 4 : return rv.error();
120 10922 : if(rv->empty())
121 9022 : break;
122 1900 : dn += rv->decoded_size();
123 : }
124 9922 : t.path = make_pct_string_view_unsafe(
125 9922 : it0, it - it0, dn);
126 9922 : return t;
127 13282 : }
128 :
129 : } // detail
130 : } // urls
131 : } // boost
132 :
133 :
134 : #endif
|