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 13091 : 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 13091 : constexpr auto pchars_nc = pchars - ':';
35 :
36 13091 : value_type t;
37 13091 : if(it == end)
38 : {
39 : // path-empty
40 153 : return t;
41 : }
42 12938 : if(end - it == 1)
43 : {
44 184 : if(*it == '/')
45 : {
46 : // path-absolute
47 81 : t.path = make_pct_string_view_unsafe(
48 : it, 1, 1);
49 81 : t.segment_count = 1;
50 81 : ++it;
51 81 : return t;
52 : }
53 103 : if(*it != ':')
54 : {
55 : // path-noscheme or
56 : // path-empty
57 102 : auto rv = grammar::parse(
58 : it, end, segment_rule);
59 102 : if(! rv)
60 MIS 0 : return rv.error();
61 HIT 102 : if(! rv->empty())
62 : {
63 50 : t.path = *rv;
64 50 : t.segment_count = 1;
65 : }
66 : }
67 : // path-empty
68 103 : return t;
69 : }
70 12754 : if( it[0] == '/' &&
71 668 : 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 12754 : if(it == end)
83 : {
84 : // path-empty
85 129 : return t;
86 : }
87 12625 : auto const it0 = it;
88 12625 : std::size_t dn = 0;
89 12625 : if(*it != '/')
90 : {
91 : // segment_nc
92 12089 : auto rv = grammar::parse(it, end,
93 12089 : pct_encoded_rule(pchars_nc));
94 12089 : if(! rv)
95 121 : return rv.error();
96 11968 : if(rv->empty())
97 2325 : return t;
98 9643 : dn += rv->decoded_size();
99 9643 : ++t.segment_count;
100 9643 : if( it != end &&
101 9503 : *it == ':')
102 : {
103 415 : BOOST_URL_CONSTEXPR_RETURN_EC(
104 : grammar::error::mismatch);
105 : }
106 : }
107 13479 : while(it != end)
108 : {
109 12740 : if(*it == '/')
110 : {
111 2029 : ++dn;
112 2029 : ++it;
113 2029 : ++t.segment_count;
114 2029 : continue;
115 : }
116 10711 : auto rv = grammar::parse(
117 : it, end, segment_rule);
118 10711 : if(! rv)
119 4 : return rv.error();
120 10707 : if(rv->empty())
121 9021 : break;
122 1686 : dn += rv->decoded_size();
123 : }
124 9760 : t.path = make_pct_string_view_unsafe(
125 9760 : it0, it - it0, dn);
126 9760 : return t;
127 13091 : }
128 :
129 : } // detail
130 : } // urls
131 : } // boost
132 :
133 :
134 : #endif
|