Chris@16
|
1 //
|
Chris@16
|
2 // ip/detail/impl/endpoint.ipp
|
Chris@16
|
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
Chris@16
|
4 //
|
Chris@101
|
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
Chris@16
|
6 //
|
Chris@16
|
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 //
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP
|
Chris@16
|
12 #define BOOST_ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP
|
Chris@16
|
13
|
Chris@16
|
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
15 # pragma once
|
Chris@16
|
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/asio/detail/config.hpp>
|
Chris@16
|
19 #include <cstring>
|
Chris@16
|
20 #if !defined(BOOST_ASIO_NO_IOSTREAM)
|
Chris@16
|
21 # include <sstream>
|
Chris@16
|
22 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
|
Chris@16
|
23 #include <boost/asio/detail/socket_ops.hpp>
|
Chris@16
|
24 #include <boost/asio/detail/throw_error.hpp>
|
Chris@16
|
25 #include <boost/asio/error.hpp>
|
Chris@16
|
26 #include <boost/asio/ip/detail/endpoint.hpp>
|
Chris@16
|
27
|
Chris@16
|
28 #include <boost/asio/detail/push_options.hpp>
|
Chris@16
|
29
|
Chris@16
|
30 namespace boost {
|
Chris@16
|
31 namespace asio {
|
Chris@16
|
32 namespace ip {
|
Chris@16
|
33 namespace detail {
|
Chris@16
|
34
|
Chris@16
|
35 endpoint::endpoint()
|
Chris@16
|
36 : data_()
|
Chris@16
|
37 {
|
Chris@16
|
38 data_.v4.sin_family = BOOST_ASIO_OS_DEF(AF_INET);
|
Chris@16
|
39 data_.v4.sin_port = 0;
|
Chris@16
|
40 data_.v4.sin_addr.s_addr = BOOST_ASIO_OS_DEF(INADDR_ANY);
|
Chris@16
|
41 }
|
Chris@16
|
42
|
Chris@16
|
43 endpoint::endpoint(int family, unsigned short port_num)
|
Chris@16
|
44 : data_()
|
Chris@16
|
45 {
|
Chris@16
|
46 using namespace std; // For memcpy.
|
Chris@16
|
47 if (family == BOOST_ASIO_OS_DEF(AF_INET))
|
Chris@16
|
48 {
|
Chris@16
|
49 data_.v4.sin_family = BOOST_ASIO_OS_DEF(AF_INET);
|
Chris@16
|
50 data_.v4.sin_port =
|
Chris@16
|
51 boost::asio::detail::socket_ops::host_to_network_short(port_num);
|
Chris@16
|
52 data_.v4.sin_addr.s_addr = BOOST_ASIO_OS_DEF(INADDR_ANY);
|
Chris@16
|
53 }
|
Chris@16
|
54 else
|
Chris@16
|
55 {
|
Chris@16
|
56 data_.v6.sin6_family = BOOST_ASIO_OS_DEF(AF_INET6);
|
Chris@16
|
57 data_.v6.sin6_port =
|
Chris@16
|
58 boost::asio::detail::socket_ops::host_to_network_short(port_num);
|
Chris@16
|
59 data_.v6.sin6_flowinfo = 0;
|
Chris@16
|
60 data_.v6.sin6_addr.s6_addr[0] = 0; data_.v6.sin6_addr.s6_addr[1] = 0;
|
Chris@16
|
61 data_.v6.sin6_addr.s6_addr[2] = 0, data_.v6.sin6_addr.s6_addr[3] = 0;
|
Chris@16
|
62 data_.v6.sin6_addr.s6_addr[4] = 0, data_.v6.sin6_addr.s6_addr[5] = 0;
|
Chris@16
|
63 data_.v6.sin6_addr.s6_addr[6] = 0, data_.v6.sin6_addr.s6_addr[7] = 0;
|
Chris@16
|
64 data_.v6.sin6_addr.s6_addr[8] = 0, data_.v6.sin6_addr.s6_addr[9] = 0;
|
Chris@16
|
65 data_.v6.sin6_addr.s6_addr[10] = 0, data_.v6.sin6_addr.s6_addr[11] = 0;
|
Chris@16
|
66 data_.v6.sin6_addr.s6_addr[12] = 0, data_.v6.sin6_addr.s6_addr[13] = 0;
|
Chris@16
|
67 data_.v6.sin6_addr.s6_addr[14] = 0, data_.v6.sin6_addr.s6_addr[15] = 0;
|
Chris@16
|
68 data_.v6.sin6_scope_id = 0;
|
Chris@16
|
69 }
|
Chris@16
|
70 }
|
Chris@16
|
71
|
Chris@16
|
72 endpoint::endpoint(const boost::asio::ip::address& addr,
|
Chris@16
|
73 unsigned short port_num)
|
Chris@16
|
74 : data_()
|
Chris@16
|
75 {
|
Chris@16
|
76 using namespace std; // For memcpy.
|
Chris@16
|
77 if (addr.is_v4())
|
Chris@16
|
78 {
|
Chris@16
|
79 data_.v4.sin_family = BOOST_ASIO_OS_DEF(AF_INET);
|
Chris@16
|
80 data_.v4.sin_port =
|
Chris@16
|
81 boost::asio::detail::socket_ops::host_to_network_short(port_num);
|
Chris@16
|
82 data_.v4.sin_addr.s_addr =
|
Chris@16
|
83 boost::asio::detail::socket_ops::host_to_network_long(
|
Chris@16
|
84 static_cast<boost::asio::detail::u_long_type>(
|
Chris@16
|
85 addr.to_v4().to_ulong()));
|
Chris@16
|
86 }
|
Chris@16
|
87 else
|
Chris@16
|
88 {
|
Chris@16
|
89 data_.v6.sin6_family = BOOST_ASIO_OS_DEF(AF_INET6);
|
Chris@16
|
90 data_.v6.sin6_port =
|
Chris@16
|
91 boost::asio::detail::socket_ops::host_to_network_short(port_num);
|
Chris@16
|
92 data_.v6.sin6_flowinfo = 0;
|
Chris@16
|
93 boost::asio::ip::address_v6 v6_addr = addr.to_v6();
|
Chris@16
|
94 boost::asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes();
|
Chris@16
|
95 memcpy(data_.v6.sin6_addr.s6_addr, bytes.data(), 16);
|
Chris@16
|
96 data_.v6.sin6_scope_id =
|
Chris@16
|
97 static_cast<boost::asio::detail::u_long_type>(
|
Chris@16
|
98 v6_addr.scope_id());
|
Chris@16
|
99 }
|
Chris@16
|
100 }
|
Chris@16
|
101
|
Chris@16
|
102 void endpoint::resize(std::size_t new_size)
|
Chris@16
|
103 {
|
Chris@16
|
104 if (new_size > sizeof(boost::asio::detail::sockaddr_storage_type))
|
Chris@16
|
105 {
|
Chris@16
|
106 boost::system::error_code ec(boost::asio::error::invalid_argument);
|
Chris@16
|
107 boost::asio::detail::throw_error(ec);
|
Chris@16
|
108 }
|
Chris@16
|
109 }
|
Chris@16
|
110
|
Chris@16
|
111 unsigned short endpoint::port() const
|
Chris@16
|
112 {
|
Chris@16
|
113 if (is_v4())
|
Chris@16
|
114 {
|
Chris@16
|
115 return boost::asio::detail::socket_ops::network_to_host_short(
|
Chris@16
|
116 data_.v4.sin_port);
|
Chris@16
|
117 }
|
Chris@16
|
118 else
|
Chris@16
|
119 {
|
Chris@16
|
120 return boost::asio::detail::socket_ops::network_to_host_short(
|
Chris@16
|
121 data_.v6.sin6_port);
|
Chris@16
|
122 }
|
Chris@16
|
123 }
|
Chris@16
|
124
|
Chris@16
|
125 void endpoint::port(unsigned short port_num)
|
Chris@16
|
126 {
|
Chris@16
|
127 if (is_v4())
|
Chris@16
|
128 {
|
Chris@16
|
129 data_.v4.sin_port
|
Chris@16
|
130 = boost::asio::detail::socket_ops::host_to_network_short(port_num);
|
Chris@16
|
131 }
|
Chris@16
|
132 else
|
Chris@16
|
133 {
|
Chris@16
|
134 data_.v6.sin6_port
|
Chris@16
|
135 = boost::asio::detail::socket_ops::host_to_network_short(port_num);
|
Chris@16
|
136 }
|
Chris@16
|
137 }
|
Chris@16
|
138
|
Chris@16
|
139 boost::asio::ip::address endpoint::address() const
|
Chris@16
|
140 {
|
Chris@16
|
141 using namespace std; // For memcpy.
|
Chris@16
|
142 if (is_v4())
|
Chris@16
|
143 {
|
Chris@16
|
144 return boost::asio::ip::address_v4(
|
Chris@16
|
145 boost::asio::detail::socket_ops::network_to_host_long(
|
Chris@16
|
146 data_.v4.sin_addr.s_addr));
|
Chris@16
|
147 }
|
Chris@16
|
148 else
|
Chris@16
|
149 {
|
Chris@16
|
150 boost::asio::ip::address_v6::bytes_type bytes;
|
Chris@16
|
151 #if defined(BOOST_ASIO_HAS_STD_ARRAY)
|
Chris@16
|
152 memcpy(bytes.data(), data_.v6.sin6_addr.s6_addr, 16);
|
Chris@16
|
153 #else // defined(BOOST_ASIO_HAS_STD_ARRAY)
|
Chris@16
|
154 memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16);
|
Chris@16
|
155 #endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
|
Chris@16
|
156 return boost::asio::ip::address_v6(bytes, data_.v6.sin6_scope_id);
|
Chris@16
|
157 }
|
Chris@16
|
158 }
|
Chris@16
|
159
|
Chris@16
|
160 void endpoint::address(const boost::asio::ip::address& addr)
|
Chris@16
|
161 {
|
Chris@16
|
162 endpoint tmp_endpoint(addr, port());
|
Chris@16
|
163 data_ = tmp_endpoint.data_;
|
Chris@16
|
164 }
|
Chris@16
|
165
|
Chris@16
|
166 bool operator==(const endpoint& e1, const endpoint& e2)
|
Chris@16
|
167 {
|
Chris@16
|
168 return e1.address() == e2.address() && e1.port() == e2.port();
|
Chris@16
|
169 }
|
Chris@16
|
170
|
Chris@16
|
171 bool operator<(const endpoint& e1, const endpoint& e2)
|
Chris@16
|
172 {
|
Chris@16
|
173 if (e1.address() < e2.address())
|
Chris@16
|
174 return true;
|
Chris@16
|
175 if (e1.address() != e2.address())
|
Chris@16
|
176 return false;
|
Chris@16
|
177 return e1.port() < e2.port();
|
Chris@16
|
178 }
|
Chris@16
|
179
|
Chris@16
|
180 #if !defined(BOOST_ASIO_NO_IOSTREAM)
|
Chris@16
|
181 std::string endpoint::to_string(boost::system::error_code& ec) const
|
Chris@16
|
182 {
|
Chris@16
|
183 std::string a = address().to_string(ec);
|
Chris@16
|
184 if (ec)
|
Chris@16
|
185 return std::string();
|
Chris@16
|
186
|
Chris@16
|
187 std::ostringstream tmp_os;
|
Chris@16
|
188 tmp_os.imbue(std::locale::classic());
|
Chris@16
|
189 if (is_v4())
|
Chris@16
|
190 tmp_os << a;
|
Chris@16
|
191 else
|
Chris@16
|
192 tmp_os << '[' << a << ']';
|
Chris@16
|
193 tmp_os << ':' << port();
|
Chris@16
|
194
|
Chris@16
|
195 return tmp_os.str();
|
Chris@16
|
196 }
|
Chris@16
|
197 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
|
Chris@16
|
198
|
Chris@16
|
199 } // namespace detail
|
Chris@16
|
200 } // namespace ip
|
Chris@16
|
201 } // namespace asio
|
Chris@16
|
202 } // namespace boost
|
Chris@16
|
203
|
Chris@16
|
204 #include <boost/asio/detail/pop_options.hpp>
|
Chris@16
|
205
|
Chris@16
|
206 #endif // BOOST_ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP
|