1 // 2 // ip/impl/address.ipp 3 // ~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 // 10 11 #ifndef ASIO_IP_IMPL_ADDRESS_IPP 12 #define ASIO_IP_IMPL_ADDRESS_IPP 13 14 15 #include "asio/detail/config.hpp" 16 #include <typeinfo> 17 #include "asio/detail/throw_error.hpp" 18 #include "asio/detail/throw_exception.hpp" 19 #include "asio/error.hpp" 20 #include "asio/ip/address.hpp" 21 #include "asio/system_error.hpp" 22 23 #include "asio/detail/push_options.hpp" 24 25 namespace asio { 26 namespace ip { 27 28 address::address() 29 : type_(ipv4), 30 ipv4_address_(), 31 ipv6_address_() 32 { 33 } 34 35 address::address(const asio::ip::address_v4& ipv4_address) 36 : type_(ipv4), 37 ipv4_address_(ipv4_address), 38 ipv6_address_() 39 { 40 } 41 42 address::address(const asio::ip::address_v6& ipv6_address) 43 : type_(ipv6), 44 ipv4_address_(), 45 ipv6_address_(ipv6_address) 46 { 47 } 48 49 address::address(const address& other) 50 : type_(other.type_), 51 ipv4_address_(other.ipv4_address_), 52 ipv6_address_(other.ipv6_address_) 53 { 54 } 55 56 address::address(address&& other) 57 : type_(other.type_), 58 ipv4_address_(other.ipv4_address_), 59 ipv6_address_(other.ipv6_address_) 60 { 61 } 62 63 address& address::operator=(const address& other) 64 { 65 type_ = other.type_; 66 ipv4_address_ = other.ipv4_address_; 67 ipv6_address_ = other.ipv6_address_; 68 return *this; 69 } 70 71 address& address::operator=(address&& other) 72 { 73 type_ = other.type_; 74 ipv4_address_ = other.ipv4_address_; 75 ipv6_address_ = other.ipv6_address_; 76 return *this; 77 } 78 79 address& address::operator=(const asio::ip::address_v4& ipv4_address) 80 { 81 type_ = ipv4; 82 ipv4_address_ = ipv4_address; 83 ipv6_address_ = asio::ip::address_v6(); 84 return *this; 85 } 86 87 address& address::operator=(const asio::ip::address_v6& ipv6_address) 88 { 89 type_ = ipv6; 90 ipv4_address_ = asio::ip::address_v4(); 91 ipv6_address_ = ipv6_address; 92 return *this; 93 } 94 95 asio::ip::address_v4 address::to_v4() const 96 { 97 if (type_ != ipv4) 98 { 99 std::bad_cast ex; 100 asio::detail::throw_exception(ex); 101 } 102 return ipv4_address_; 103 } 104 105 asio::ip::address_v6 address::to_v6() const 106 { 107 if (type_ != ipv6) 108 { 109 std::bad_cast ex; 110 asio::detail::throw_exception(ex); 111 } 112 return ipv6_address_; 113 } 114 115 std::string address::to_string() const 116 { 117 if (type_ == ipv6) 118 return ipv6_address_.to_string(); 119 return ipv4_address_.to_string(); 120 } 121 122 std::string address::to_string(asio::error_code& ec) const 123 { 124 if (type_ == ipv6) 125 return ipv6_address_.to_string(ec); 126 return ipv4_address_.to_string(ec); 127 } 128 129 address address::from_string(const char* str) 130 { 131 asio::error_code ec; 132 address addr = from_string(str, ec); 133 asio::detail::throw_error(ec); 134 return addr; 135 } 136 137 address address::from_string(const char* str, asio::error_code& ec) 138 { 139 asio::ip::address_v6 ipv6_address = 140 asio::ip::address_v6::from_string(str, ec); 141 if (!ec) 142 { 143 address tmp; 144 tmp.type_ = ipv6; 145 tmp.ipv6_address_ = ipv6_address; 146 return tmp; 147 } 148 149 asio::ip::address_v4 ipv4_address = 150 asio::ip::address_v4::from_string(str, ec); 151 if (!ec) 152 { 153 address tmp; 154 tmp.type_ = ipv4; 155 tmp.ipv4_address_ = ipv4_address; 156 return tmp; 157 } 158 159 return address(); 160 } 161 162 address address::from_string(const std::string& str) 163 { 164 return from_string(str.c_str()); 165 } 166 167 address address::from_string(const std::string& str, 168 asio::error_code& ec) 169 { 170 return from_string(str.c_str(), ec); 171 } 172 173 bool address::is_loopback() const 174 { 175 return (type_ == ipv4) 176 ? ipv4_address_.is_loopback() 177 : ipv6_address_.is_loopback(); 178 } 179 180 bool address::is_unspecified() const 181 { 182 return (type_ == ipv4) 183 ? ipv4_address_.is_unspecified() 184 : ipv6_address_.is_unspecified(); 185 } 186 187 bool address::is_multicast() const 188 { 189 return (type_ == ipv4) 190 ? ipv4_address_.is_multicast() 191 : ipv6_address_.is_multicast(); 192 } 193 194 bool operator==(const address& a1, const address& a2) 195 { 196 if (a1.type_ != a2.type_) 197 return false; 198 if (a1.type_ == address::ipv6) 199 return a1.ipv6_address_ == a2.ipv6_address_; 200 return a1.ipv4_address_ == a2.ipv4_address_; 201 } 202 203 bool operator<(const address& a1, const address& a2) 204 { 205 if (a1.type_ < a2.type_) 206 return true; 207 if (a1.type_ > a2.type_) 208 return false; 209 if (a1.type_ == address::ipv6) 210 return a1.ipv6_address_ < a2.ipv6_address_; 211 return a1.ipv4_address_ < a2.ipv4_address_; 212 } 213 214 } // namespace ip 215 } // namespace asio 216 217 #include "asio/detail/pop_options.hpp" 218 219 #endif // ASIO_IP_IMPL_ADDRESS_IPP 220