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