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

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