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