Line data Source code
1 : // 2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/ipv4_address.hpp> 13 : #include <boost/url/detail/except.hpp> 14 : #include <boost/url/grammar/parse.hpp> 15 : #include <boost/url/rfc/ipv4_address_rule.hpp> 16 : #include <cstring> 17 : 18 : namespace boost { 19 : namespace urls { 20 : 21 19 : ipv4_address:: 22 : ipv4_address( 23 19 : uint_type addr) noexcept 24 19 : : addr_(addr) 25 : { 26 19 : } 27 : 28 141 : ipv4_address:: 29 : ipv4_address( 30 141 : bytes_type const& bytes) noexcept 31 : { 32 141 : addr_ = 33 141 : (static_cast<unsigned long>(bytes[0]) << 24) | 34 141 : (static_cast<unsigned long>(bytes[1]) << 16) | 35 141 : (static_cast<unsigned long>(bytes[2]) << 8) | 36 141 : (static_cast<unsigned long>(bytes[3])); 37 141 : } 38 : 39 27 : ipv4_address:: 40 : ipv4_address( 41 27 : core::string_view s) 42 : : ipv4_address( 43 27 : parse_ipv4_address(s 44 27 : ).value(BOOST_URL_POS)) 45 : { 46 26 : } 47 : 48 : auto 49 75 : ipv4_address:: 50 : to_bytes() const noexcept -> 51 : bytes_type 52 : { 53 : bytes_type bytes; 54 75 : bytes[0] = (addr_ >> 24) & 0xff; 55 75 : bytes[1] = (addr_ >> 16) & 0xff; 56 75 : bytes[2] = (addr_ >> 8) & 0xff; 57 75 : bytes[3] = addr_ & 0xff; 58 75 : return bytes; 59 : } 60 : 61 : auto 62 54 : ipv4_address:: 63 : to_uint() const noexcept -> 64 : uint_type 65 : { 66 54 : return addr_; 67 : } 68 : 69 : core::string_view 70 19 : ipv4_address:: 71 : to_buffer( 72 : char* dest, 73 : std::size_t dest_size) const 74 : { 75 19 : if(dest_size < max_str_len) 76 1 : detail::throw_length_error(); 77 18 : auto n = print_impl(dest); 78 18 : return core::string_view(dest, n); 79 : } 80 : 81 : bool 82 4 : ipv4_address:: 83 : is_loopback() const noexcept 84 : { 85 4 : return (to_uint() & 0xFF000000) == 86 4 : 0x7F000000; 87 : } 88 : 89 : bool 90 7 : ipv4_address:: 91 : is_unspecified() const noexcept 92 : { 93 7 : return to_uint() == 0; 94 : } 95 : 96 : bool 97 4 : ipv4_address:: 98 : is_multicast() const noexcept 99 : { 100 4 : return (to_uint() & 0xF0000000) == 101 4 : 0xE0000000; 102 : } 103 : 104 : std::size_t 105 29 : ipv4_address:: 106 : print_impl( 107 : char* dest) const noexcept 108 : { 109 29 : auto const start = dest; 110 : auto const write = 111 116 : []( char*& dest, 112 : unsigned char v) 113 : { 114 116 : if(v >= 100) 115 : { 116 33 : *dest++ = '0' + 117 33 : v / 100; 118 33 : v %= 100; 119 33 : *dest++ = '0' + 120 33 : v / 10; 121 33 : v %= 10; 122 : } 123 83 : else if(v >= 10) 124 : { 125 3 : *dest++ = '0' + 126 3 : v / 10; 127 3 : v %= 10; 128 : } 129 116 : *dest++ = '0' + v; 130 116 : }; 131 29 : auto const v = to_uint(); 132 29 : write(dest, (v >> 24) & 0xff); 133 29 : *dest++ = '.'; 134 29 : write(dest, (v >> 16) & 0xff); 135 29 : *dest++ = '.'; 136 29 : write(dest, (v >> 8) & 0xff); 137 29 : *dest++ = '.'; 138 29 : write(dest, (v ) & 0xff); 139 29 : return dest - start; 140 : } 141 : 142 : void 143 2 : ipv4_address:: 144 : to_string_impl( 145 : string_token::arg& t) const 146 : { 147 : char buf[max_str_len]; 148 2 : auto const n = print_impl(buf); 149 2 : char* dest = t.prepare(n); 150 2 : std::memcpy(dest, buf, n); 151 2 : } 152 : 153 : //------------------------------------------------ 154 : 155 : auto 156 127 : parse_ipv4_address( 157 : core::string_view s) noexcept -> 158 : system::result<ipv4_address> 159 : { 160 : return grammar::parse( 161 127 : s, ipv4_address_rule); 162 : } 163 : 164 : } // urls 165 : } // boost 166 :