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

98.2% Lines (56 / 57) 100.0% Functions (1 / 1)
hier_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_HIER_PART_RULE_HPP
12 #define BOOST_URL_RFC_DETAIL_IMPL_HIER_PART_RULE_HPP
13
14 #include <boost/url/detail/config.hpp>
15 #include <boost/url/rfc/detail/path_rules.hpp>
16 #include <boost/url/grammar/parse.hpp>
17
18 namespace boost {
19 namespace urls {
20 namespace detail {
21
22 BOOST_URL_CXX20_CONSTEXPR_OR_INLINE
23 auto
24 7280x hier_part_rule_t::
25 parse(
26 char const*& it,
27 char const* const end
28 ) const noexcept ->
29 system::result<value_type>
30 {
31 7280x value_type t;
32 7280x if(it == end)
33 {
34 // path-empty
35 47x return t;
36 }
37 7233x if(end - it == 1)
38 {
39 39x if(*it == '/')
40 {
41 // path-absolute
42 26x t.path = make_pct_string_view_unsafe(
43 it, 1, 1);
44 26x t.segment_count = 1;
45 26x ++it;
46 26x return t;
47 }
48 // path-rootless
49 13x auto rv = grammar::parse(
50 it, end, segment_rule);
51 13x if(! rv)
52 ✗ return rv.error();
53 13x t.path = *rv;
54 13x t.segment_count = !t.path.empty();
55 13x return t;
56 }
57 7194x if( it[0] == '/' &&
58 6351x it[1] == '/')
59 {
60 // "//" authority
61 6239x it += 2;
62 auto rv = grammar::parse(
63 6239x it, end, authority_rule);
64 6239x if(! rv)
65 32x return rv.error();
66 6207x t.authority = *rv;
67 6207x t.has_authority = true;
68 6239x }
69 // the authority requires an absolute path
70 // or an empty path
71 7162x if(it == end || (
72 6705x t.has_authority && (
73 5750x *it != '/' &&
74 151x *it != '?' &&
75 106x *it != '#')))
76 {
77 // path-empty
78 547x return t;
79 }
80 6615x auto const it0 = it;
81 6615x std::size_t dn = 0;
82 6615x if(*it != '/')
83 {
84 904x auto rv = grammar::parse(
85 it, end, segment_rule);
86 904x if(! rv)
87 2x return rv.error();
88 902x if(rv->empty())
89 122x return t;
90 780x dn += rv->decoded_size();
91 780x ++t.segment_count;
92 }
93 25901x while(it != end)
94 {
95 23156x if(*it == '/')
96 {
97 10519x ++dn;
98 10519x ++it;
99 10519x ++t.segment_count;
100 10519x continue;
101 }
102 12637x auto rv = grammar::parse(
103 it, end, segment_rule);
104 12637x if(! rv)
105 11x return rv.error();
106 12626x if(rv->empty())
107 3735x break;
108 8891x dn += rv->decoded_size();
109 }
110 6480x t.path = make_pct_string_view_unsafe(
111 6480x it0, it - it0, dn);
112 6480x return t;
113 7280x }
114
115 } // detail
116 } // urls
117 } // boost
118
119
120 #endif
121