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 25namespace asio { 26namespace ip { 27 28address::address() 29 : type_(ipv4), 30 ipv4_address_(), 31 ipv6_address_() 32{ 33} 34 35address::address(const asio::ip::address_v4& ipv4_address) 36 : type_(ipv4), 37 ipv4_address_(ipv4_address), 38 ipv6_address_() 39{ 40} 41 42address::address(const asio::ip::address_v6& ipv6_address) 43 : type_(ipv6), 44 ipv4_address_(), 45 ipv6_address_(ipv6_address) 46{ 47} 48 49address::address(const address& other) 50 : type_(other.type_), 51 ipv4_address_(other.ipv4_address_), 52 ipv6_address_(other.ipv6_address_) 53{ 54} 55 56address::address(address&& other) 57 : type_(other.type_), 58 ipv4_address_(other.ipv4_address_), 59 ipv6_address_(other.ipv6_address_) 60{ 61} 62 63address& 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 71address& 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 79address& 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 87address& 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 95asio::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 105asio::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 115std::string address::to_string() const 116{ 117 if (type_ == ipv6) 118 return ipv6_address_.to_string(); 119 return ipv4_address_.to_string(); 120} 121 122std::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 129address 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 137address 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 162address address::from_string(const std::string& str) 163{ 164 return from_string(str.c_str()); 165} 166 167address address::from_string(const std::string& str, 168 asio::error_code& ec) 169{ 170 return from_string(str.c_str(), ec); 171} 172 173bool address::is_loopback() const 174{ 175 return (type_ == ipv4) 176 ? ipv4_address_.is_loopback() 177 : ipv6_address_.is_loopback(); 178} 179 180bool address::is_unspecified() const 181{ 182 return (type_ == ipv4) 183 ? ipv4_address_.is_unspecified() 184 : ipv6_address_.is_unspecified(); 185} 186 187bool address::is_multicast() const 188{ 189 return (type_ == ipv4) 190 ? ipv4_address_.is_multicast() 191 : ipv6_address_.is_multicast(); 192} 193 194bool 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 203bool 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