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

96.7% Lines (58/60) 100.0% List of functions (1/1)
relative_part_rule.hpp
f(x) Functions (1)
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 13117x 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 13117x constexpr auto pchars_nc = pchars - ':';
35
36 13117x value_type t;
37 13117x if(it == end)
38 {
39 // path-empty
40 153x return t;
41 }
42 12964x if(end - it == 1)
43 {
44 184x if(*it == '/')
45 {
46 // path-absolute
47 81x t.path = make_pct_string_view_unsafe(
48 it, 1, 1);
49 81x t.segment_count = 1;
50 81x ++it;
51 81x return t;
52 }
53 103x if(*it != ':')
54 {
55 // path-noscheme or
56 // path-empty
57 102x auto rv = grammar::parse(
58 it, end, segment_rule);
59 102x if(! rv)
60 return rv.error();
61 102x if(! rv->empty())
62 {
63 50x t.path = *rv;
64 50x t.segment_count = 1;
65 }
66 }
67 // path-empty
68 103x return t;
69 }
70 12780x if( it[0] == '/' &&
71 668x it[1] == '/')
72 {
73 // "//" authority
74 255x it += 2;
75 auto rv = grammar::parse(
76 255x it, end, authority_rule);
77 255x if(! rv)
78 return rv.error();
79 255x t.authority = *rv;
80 255x t.has_authority = true;
81 255x }
82 12780x if(it == end)
83 {
84 // path-empty
85 129x return t;
86 }
87 12651x auto const it0 = it;
88 12651x std::size_t dn = 0;
89 12651x if(*it != '/')
90 {
91 // segment_nc
92 12115x auto rv = grammar::parse(it, end,
93 12115x pct_encoded_rule(pchars_nc));
94 12115x if(! rv)
95 121x return rv.error();
96 11994x if(rv->empty())
97 2325x return t;
98 9669x dn += rv->decoded_size();
99 9669x ++t.segment_count;
100 9669x if( it != end &&
101 9522x *it == ':')
102 {
103 415x BOOST_URL_CONSTEXPR_RETURN_EC(
104 grammar::error::mismatch);
105 }
106 }
107 13595x while(it != end)
108 {
109 12830x if(*it == '/')
110 {
111 2080x ++dn;
112 2080x ++it;
113 2080x ++t.segment_count;
114 2080x continue;
115 }
116 10750x auto rv = grammar::parse(
117 it, end, segment_rule);
118 10750x if(! rv)
119 4x return rv.error();
120 10746x if(rv->empty())
121 9021x break;
122 1725x dn += rv->decoded_size();
123 }
124 9786x t.path = make_pct_string_view_unsafe(
125 9786x it0, it - it0, dn);
126 9786x return t;
127 13117x }
128
129 } // detail
130 } // urls
131 } // boost
132
133
134 #endif
135