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