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