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

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