1 -
//
 
2 -
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
 
3 -
//
 
4 -
// Distributed under the Boost Software License, Version 1.0. (See accompanying
 
5 -
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
6 -
//
 
7 -
// Official repository: https://github.com/boostorg/url
 
8 -
//
 
9 -

 
10 -

 
11 -
#include <boost/url/detail/config.hpp>
 
12 -
#include <boost/url/rfc/ipv4_address_rule.hpp>
 
13 -
#include "host_rule.hpp"
 
14 -
#include "ip_literal_rule.hpp"
 
15 -
#include "reg_name_rule.hpp"
 
16 -
#include <boost/url/grammar/parse.hpp>
 
17 -

 
18 -
namespace boost {
 
19 -
namespace urls {
 
20 -
namespace detail {
 
21 -

 
22 -
auto
 
23 -
host_rule_t::
 
24 -
parse(
 
25 -
    char const*& it,
 
26 -
    char const* const end
 
27 -
        ) const noexcept ->
 
28 -
    system::result<value_type>
 
29 -
{
 
30 -
    value_type t;
 
31 -

 
32 -
    if(it == end)
 
33 -
    {
 
34 -
        // empty host
 
35 -
        t.host_type =
 
36 -
            urls::host_type::name;
 
37 -
        return t;
 
38 -
    }
 
39 -

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

 
66 -
        // IPvFuture
 
67 -
        t.host_type =
 
68 -
            urls::host_type::ipvfuture;
 
69 -
        t.match = core::string_view(
 
70 -
            it0, it - it0);
 
71 -
        return t;
 
72 -
    }
 
73 -

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

 
109 -
        it = it0; // rewind
 
110 -
    }
 
111 -

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

 
128 -
} // detail
 
129 -
} // urls
 
130 -
} // boost
 
131 -