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