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 +
host_rule_t::
 
28 +
parse(
 
29 +
    char const*& it,
 
30 +
    char const* const end
 
31 +
        ) const noexcept ->
 
32 +
    system::result<value_type>
 
33 +
{
 
34 +
    value_type t;
 
35 +

 
36 +
    if(it == end)
 
37 +
    {
 
38 +
        t.host_type =
 
39 +
            urls::host_type::name;
 
40 +
        return t;
 
41 +
    }
 
42 +

 
43 +
    auto const it0 = it;
 
44 +
    if(*it == '[')
 
45 +
    {
 
46 +
        // IP-literal
 
47 +
        auto rv = grammar::parse(
 
48 +
            it, end,
 
49 +
            detail::ip_literal_rule);
 
50 +
        if(! rv)
 
51 +
            return rv.error();
 
52 +
        auto v = *rv;
 
53 +
        if(v.is_ipv6)
 
54 +
        {
 
55 +
            auto const b =
 
56 +
                v.ipv6.to_bytes();
 
57 +
            std::memcpy(
 
58 +
                t.addr,
 
59 +
                b.data(),
 
60 +
                b.size());
 
61 +
            t.host_type =
 
62 +
                urls::host_type::ipv6;
 
63 +
            t.match = make_pct_string_view_unsafe(
 
64 +
                it0, it - it0, it - it0);
 
65 +
            return t;
 
66 +
        }
 
67 +

 
68 +
        t.host_type =
 
69 +
            urls::host_type::ipvfuture;
 
70 +
        t.match = make_pct_string_view_unsafe(
 
71 +
            it0, it - it0, it - it0);
 
72 +
        return t;
 
73 +
    }
 
74 +

 
75 +
    // IPv4address
 
76 +
    {
 
77 +
        auto rv = grammar::parse(
 
78 +
            it, end, ipv4_address_rule);
 
79 +
        if( rv )
 
80 +
        {
 
81 +
            auto it02 = it;
 
82 +
            auto rv2 = grammar::parse(
 
83 +
                it, end,
 
84 +
                detail::reg_name_rule);
 
85 +
            if (rv2.has_value() &&
 
86 +
                !rv2->empty())
 
87 +
            {
 
88 +
                auto dn = static_cast<
 
89 +
                    std::size_t>(it02 - it0) +
 
90 +
                    rv2->decoded_size();
 
91 +
                t.name = make_pct_string_view_unsafe(
 
92 +
                    it0, it - it0, dn);
 
93 +
                t.host_type =
 
94 +
                    urls::host_type::name;
 
95 +
                t.match = t.name;
 
96 +
                return t;
 
97 +
            }
 
98 +
            it = it02;
 
99 +
            auto const b =
 
100 +
                rv->to_bytes();
 
101 +
            std::memcpy(
 
102 +
                t.addr,
 
103 +
                b.data(),
 
104 +
                b.size());
 
105 +
            t.host_type =
 
106 +
                urls::host_type::ipv4;
 
107 +
            t.match = make_pct_string_view_unsafe(
 
108 +
                it0, it - it0, it - it0);
 
109 +
            return t;
 
110 +
        }
 
111 +

 
112 +
        it = it0;
 
113 +
    }
 
114 +

 
115 +
    // reg-name
 
116 +
    {
 
117 +
        auto rv = grammar::parse(
 
118 +
            it, end,
 
119 +
            detail::reg_name_rule);
 
120 +
        if(! rv)
 
121 +
            return rv.error();
 
122 +
        t.name = *rv;
 
123 +
        t.host_type =
 
124 +
            urls::host_type::name;
 
125 +
        t.match = *rv;
 
126 +
        return t;
 
127 +
    }
 
128 +
}
 
129 +

 
130 +
} // detail
 
131 +
} // urls
 
132 +
} // boost
 
133 +

 
134 +

 
135 +
#endif