TLA 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_HOST_RULE_HPP
12 : #define BOOST_URL_RFC_DETAIL_IMPL_HOST_RULE_HPP
13 :
14 : #include <boost/url/detail/config.hpp>
15 : #include <boost/url/rfc/ipv4_address_rule.hpp>
16 : #include <boost/url/rfc/detail/ip_literal_rule.hpp>
17 : #include <boost/url/rfc/detail/reg_name_rule.hpp>
18 : #include <boost/url/grammar/parse.hpp>
19 : #include <cstring>
20 :
21 : namespace boost {
22 : namespace urls {
23 : namespace detail {
24 :
25 : BOOST_URL_CXX20_CONSTEXPR_OR_INLINE
26 : auto
27 HIT 6703 : host_rule_t::
28 : parse(
29 : char const*& it,
30 : char const* const end
31 : ) const noexcept ->
32 : system::result<value_type>
33 : {
34 6703 : value_type t;
35 :
36 6703 : if(it == end)
37 : {
38 : // empty host
39 228 : t.host_type =
40 : urls::host_type::name;
41 228 : return t;
42 : }
43 :
44 6475 : auto const it0 = it;
45 6475 : if(*it == '[')
46 : {
47 : // IP-literal
48 73 : auto rv = grammar::parse(
49 : it, end,
50 : detail::ip_literal_rule);
51 73 : if(! rv)
52 26 : return rv.error();
53 47 : auto v = *rv;
54 47 : if(v.is_ipv6)
55 : {
56 : // IPv6address
57 : auto const b =
58 42 : v.ipv6.to_bytes();
59 84 : std::memcpy(
60 : t.addr,
61 42 : b.data(),
62 : b.size());
63 42 : t.host_type =
64 : urls::host_type::ipv6;
65 42 : auto dn = static_cast<
66 42 : std::size_t>(it - it0);
67 42 : if( !v.zone_id.empty())
68 : // Account for '%25' -> '%' and recalculate the decoded zone_id size.
69 10 : dn -= 2 + v.zone_id.size() -
70 5 : v.zone_id.decoded_size();
71 42 : t.match = make_pct_string_view_unsafe(
72 42 : it0, it - it0, dn);
73 42 : return t;
74 : }
75 :
76 : // IPvFuture
77 5 : t.host_type =
78 : urls::host_type::ipvfuture;
79 5 : t.match = make_pct_string_view_unsafe(
80 5 : it0, it - it0, it - it0);
81 5 : return t;
82 : }
83 :
84 : // IPv4address
85 : {
86 6402 : auto rv = grammar::parse(
87 : it, end, ipv4_address_rule);
88 6402 : if( rv )
89 : {
90 108 : auto it02 = it;
91 108 : auto rv2 = grammar::parse(
92 : it, end,
93 : detail::reg_name_rule);
94 215 : if (rv2.has_value() &&
95 107 : !rv2->empty())
96 : {
97 6 : auto dn = static_cast<
98 6 : std::size_t>(it02 - it0) +
99 6 : rv2->decoded_size();
100 6 : t.name = make_pct_string_view_unsafe(
101 6 : it0, it - it0, dn);
102 6 : t.host_type =
103 : urls::host_type::name;
104 6 : t.match = t.name;
105 6 : return t;
106 : }
107 102 : it = it02;
108 : auto const b =
109 102 : rv->to_bytes();
110 204 : std::memcpy(
111 : t.addr,
112 102 : b.data(),
113 : b.size());
114 102 : t.host_type =
115 : urls::host_type::ipv4;
116 102 : t.match = make_pct_string_view_unsafe(
117 102 : it0, it - it0, it - it0);
118 102 : return t;
119 : }
120 :
121 6294 : it = it0; // rewind
122 : }
123 :
124 : // reg-name
125 : {
126 6294 : auto rv = grammar::parse(
127 : it, end,
128 : detail::reg_name_rule);
129 6294 : if(! rv)
130 7 : return rv.error();
131 6287 : t.name = *rv;
132 6287 : t.host_type =
133 : urls::host_type::name;
134 6287 : t.match = *rv;
135 6287 : return t;
136 : }
137 : }
138 :
139 : } // detail
140 : } // urls
141 : } // boost
142 :
143 :
144 : #endif
|