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