Line data Source code
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 : #ifndef BOOST_URL_RFC_DETAIL_IMPL_HOST_RULE_IPP 11 : #define BOOST_URL_RFC_DETAIL_IMPL_HOST_RULE_IPP 12 : 13 : #include <boost/url/detail/config.hpp> 14 : #include <boost/url/rfc/ipv4_address_rule.hpp> 15 : #include "host_rule.hpp" 16 : #include "ip_literal_rule.hpp" 17 : #include "reg_name_rule.hpp" 18 : #include <boost/url/grammar/parse.hpp> 19 : 20 : namespace boost { 21 : namespace urls { 22 : namespace detail { 23 : 24 : auto 25 1924 : host_rule_t:: 26 : parse( 27 : char const*& it, 28 : char const* const end 29 : ) const noexcept -> 30 : system::result<value_type> 31 : { 32 1924 : value_type t; 33 : 34 1924 : if(it == end) 35 : { 36 : // empty host 37 224 : t.host_type = 38 : urls::host_type::name; 39 224 : return t; 40 : } 41 : 42 1700 : auto const it0 = it; 43 1700 : if(*it == '[') 44 : { 45 : // IP-literal 46 : auto rv = grammar::parse( 47 : it, end, 48 61 : detail::ip_literal_rule); 49 61 : if(! rv) 50 24 : return rv.error(); 51 37 : auto v = *rv; 52 37 : if(v.is_ipv6) 53 : { 54 : // IPv6address 55 : auto const b = 56 32 : v.ipv6.to_bytes(); 57 32 : std::memcpy( 58 : t.addr, 59 32 : b.data(), 60 : b.size()); 61 32 : t.host_type = 62 : urls::host_type::ipv6; 63 64 : t.match = core::string_view( 64 32 : it0, it - it0); 65 32 : return t; 66 : } 67 : 68 : // IPvFuture 69 5 : t.host_type = 70 : urls::host_type::ipvfuture; 71 10 : t.match = core::string_view( 72 5 : it0, it - it0); 73 5 : return t; 74 : } 75 : 76 : // IPv4address 77 : { 78 : auto rv = grammar::parse( 79 1639 : it, end, ipv4_address_rule); 80 1639 : if( rv ) 81 : { 82 27 : auto it02 = it; 83 : auto rv2 = grammar::parse( 84 : it, end, 85 27 : detail::reg_name_rule); 86 53 : if (rv2.has_value() && 87 26 : !rv2->empty()) 88 : { 89 6 : t.name = core::string_view( 90 6 : it0, it - it0); 91 6 : t.host_type = 92 : urls::host_type::name; 93 12 : t.match = core::string_view( 94 6 : it0, it - it0); 95 6 : return t; 96 : } 97 21 : it = it02; 98 : auto const b = 99 21 : rv->to_bytes(); 100 21 : std::memcpy( 101 : t.addr, 102 21 : b.data(), 103 : b.size()); 104 21 : t.host_type = 105 : urls::host_type::ipv4; 106 42 : t.match = core::string_view( 107 21 : it0, it - it0); 108 21 : return t; 109 : } 110 : 111 1612 : it = it0; // rewind 112 : } 113 : 114 : // reg-name 115 : { 116 : auto rv = grammar::parse( 117 : it, end, 118 1612 : detail::reg_name_rule); 119 1612 : if(! rv) 120 7 : return rv.error(); 121 1605 : t.name = *rv; 122 1605 : t.host_type = 123 : urls::host_type::name; 124 3210 : t.match = core::string_view( 125 1605 : it0, it - it0); 126 1605 : return t; 127 : } 128 : } 129 : 130 : } // detail 131 : } // urls 132 : } // boost 133 : 134 : #endif