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

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