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

100.0% Lines (53/53) 100.0% Functions (1/1) 100.0% Branches (18/18)
include/boost/url/rfc/detail/impl/host_rule.hpp
Line Branch 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 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
2/2
✓ Branch 0 taken 225 times.
✓ Branch 1 taken 1884 times.
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
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 1821 times.
1884 if(*it == '[')
45 {
46 // IP-literal
47 63 auto rv = grammar::parse(
48 it, end,
49 detail::ip_literal_rule);
50
2/2
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 39 times.
63 if(! rv)
51 24 return rv.error();
52 39 auto v = *rv;
53
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 5 times.
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
2/2
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 1792 times.
1821 if( rv )
80 {
81 29 auto it02 = it;
82 29 auto rv2 = grammar::parse(
83 it, end,
84 detail::reg_name_rule);
85
4/4
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 23 times.
57 if (rv2.has_value() &&
86
2/2
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 22 times.
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
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1785 times.
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
136