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