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