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 6755 : host_rule_t::
28 : parse(
29 : char const*& it,
30 : char const* const end
31 : ) const noexcept ->
32 : system::result<value_type>
33 : {
34 6755 : value_type t;
35 :
36 6755 : if(it == end)
37 : {
38 : // empty host
39 230 : t.host_type =
40 : urls::host_type::name;
41 230 : return t;
42 : }
43 :
44 6525 : auto const it0 = it;
45 6525 : if(*it == '[')
46 : {
47 : // IP-literal
48 92 : auto rv = grammar::parse(
49 : it, end,
50 : detail::ip_literal_rule);
51 92 : if(! rv)
52 26 : return rv.error();
53 66 : auto v = *rv;
54 66 : if(v.is_ipv6)
55 : {
56 : // IPv6address
57 : auto const b =
58 61 : v.ipv6.to_bytes();
59 122 : std::memcpy(
60 : t.addr,
61 61 : b.data(),
62 : b.size());
63 61 : t.host_type =
64 : urls::host_type::ipv6;
65 : // "[" IPv6address [ "%25" ZoneID ] "]"
66 : // decodes to
67 : // "[" IPv6address [ "%" zone_id ] "]"
68 61 : auto dn = static_cast<
69 61 : std::size_t>(it - it0);
70 61 : if(! v.zone_id.empty())
71 21 : dn = dn
72 21 : - (3 + v.zone_id.size())
73 21 : + (1 + v.zone_id.decoded_size());
74 61 : t.match = make_pct_string_view_unsafe(
75 61 : it0, it - it0, dn);
76 61 : return t;
77 : }
78 :
79 : // IPvFuture
80 5 : t.host_type =
81 : urls::host_type::ipvfuture;
82 5 : t.match = make_pct_string_view_unsafe(
83 5 : it0, it - it0, it - it0);
84 5 : return t;
85 : }
86 :
87 : // IPv4address
88 : {
89 6433 : auto rv = grammar::parse(
90 : it, end, ipv4_address_rule);
91 6433 : if( rv )
92 : {
93 108 : auto it02 = it;
94 108 : auto rv2 = grammar::parse(
95 : it, end,
96 : detail::reg_name_rule);
97 215 : if (rv2.has_value() &&
98 107 : !rv2->empty())
99 : {
100 6 : auto dn = static_cast<
101 6 : std::size_t>(it02 - it0) +
102 6 : rv2->decoded_size();
103 6 : t.name = make_pct_string_view_unsafe(
104 6 : it0, it - it0, dn);
105 6 : t.host_type =
106 : urls::host_type::name;
107 6 : t.match = t.name;
108 6 : return t;
109 : }
110 102 : it = it02;
111 : auto const b =
112 102 : rv->to_bytes();
113 204 : std::memcpy(
114 : t.addr,
115 102 : b.data(),
116 : b.size());
117 102 : t.host_type =
118 : urls::host_type::ipv4;
119 102 : t.match = make_pct_string_view_unsafe(
120 102 : it0, it - it0, it - it0);
121 102 : return t;
122 : }
123 :
124 6325 : it = it0; // rewind
125 : }
126 :
127 : // reg-name
128 : {
129 6325 : auto rv = grammar::parse(
130 : it, end,
131 : detail::reg_name_rule);
132 6325 : if(! rv)
133 7 : return rv.error();
134 6318 : t.name = *rv;
135 6318 : t.host_type =
136 : urls::host_type::name;
137 6318 : t.match = *rv;
138 6318 : return t;
139 : }
140 : }
141 :
142 : } // detail
143 : } // urls
144 : } // boost
145 :
146 :
147 : #endif
|