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

96.7% Lines (58/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 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 return rv.error();
61 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 return rv.error();
79 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
135