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

100.0% Lines (53/53) 100.0% Functions (1/1)
include/boost/url/rfc/detail/impl/host_rule.hpp
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_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 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
139