include/boost/url/rfc/detail/impl/relative_part_rule.hpp

95.0% Lines (57/60) 100.0% Functions (1/1)
include/boost/url/rfc/detail/impl/relative_part_rule.hpp
Line TLA Hits 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 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 return rv.error();
61 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 return rv.error();
79 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 return rv.error();
120 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
135