]>
Commit | Line | Data |
---|---|---|
b71fa693 | 1 | // |
2 | // ip/detail/impl/endpoint.ipp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
5 | // Copyright (c) 2003-2011 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_DETAIL_IMPL_ENDPOINT_IPP | |
12 | #define ASIO_IP_DETAIL_IMPL_ENDPOINT_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 <cstring> | |
20 | #if !defined(BOOST_NO_IOSTREAM) | |
21 | # include <sstream> | |
22 | #endif // !defined(BOOST_NO_IOSTREAM) | |
23 | #include "asio/detail/socket_ops.hpp" | |
24 | #include "asio/detail/throw_error.hpp" | |
25 | #include "asio/error.hpp" | |
26 | #include "asio/ip/detail/endpoint.hpp" | |
27 | ||
28 | #include "asio/detail/push_options.hpp" | |
29 | ||
30 | namespace asio { | |
31 | namespace ip { | |
32 | namespace detail { | |
33 | ||
34 | endpoint::endpoint() | |
35 | : data_() | |
36 | { | |
37 | data_.v4.sin_family = AF_INET; | |
38 | data_.v4.sin_port = 0; | |
39 | data_.v4.sin_addr.s_addr = INADDR_ANY; | |
40 | } | |
41 | ||
42 | endpoint::endpoint(int family, unsigned short port_num) | |
43 | : data_() | |
44 | { | |
45 | using namespace std; // For memcpy. | |
46 | if (family == PF_INET) | |
47 | { | |
48 | data_.v4.sin_family = AF_INET; | |
49 | data_.v4.sin_port = | |
50 | asio::detail::socket_ops::host_to_network_short(port_num); | |
51 | data_.v4.sin_addr.s_addr = INADDR_ANY; | |
52 | } | |
53 | else | |
54 | { | |
55 | data_.v6.sin6_family = AF_INET6; | |
56 | data_.v6.sin6_port = | |
57 | asio::detail::socket_ops::host_to_network_short(port_num); | |
58 | data_.v6.sin6_flowinfo = 0; | |
59 | asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT; | |
60 | data_.v6.sin6_addr = tmp_addr; | |
61 | data_.v6.sin6_scope_id = 0; | |
62 | } | |
63 | } | |
64 | ||
65 | endpoint::endpoint(const asio::ip::address& addr, | |
66 | unsigned short port_num) | |
67 | : data_() | |
68 | { | |
69 | using namespace std; // For memcpy. | |
70 | if (addr.is_v4()) | |
71 | { | |
72 | data_.v4.sin_family = AF_INET; | |
73 | data_.v4.sin_port = | |
74 | asio::detail::socket_ops::host_to_network_short(port_num); | |
75 | data_.v4.sin_addr.s_addr = | |
76 | asio::detail::socket_ops::host_to_network_long( | |
77 | addr.to_v4().to_ulong()); | |
78 | } | |
79 | else | |
80 | { | |
81 | data_.v6.sin6_family = AF_INET6; | |
82 | data_.v6.sin6_port = | |
83 | asio::detail::socket_ops::host_to_network_short(port_num); | |
84 | data_.v6.sin6_flowinfo = 0; | |
85 | asio::ip::address_v6 v6_addr = addr.to_v6(); | |
86 | asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes(); | |
87 | memcpy(data_.v6.sin6_addr.s6_addr, bytes.elems, 16); | |
88 | data_.v6.sin6_scope_id = v6_addr.scope_id(); | |
89 | } | |
90 | } | |
91 | ||
92 | void endpoint::resize(std::size_t size) | |
93 | { | |
94 | if (size > sizeof(asio::detail::sockaddr_storage_type)) | |
95 | { | |
96 | asio::error_code ec(asio::error::invalid_argument); | |
97 | asio::detail::throw_error(ec); | |
98 | } | |
99 | } | |
100 | ||
101 | unsigned short endpoint::port() const | |
102 | { | |
103 | if (is_v4()) | |
104 | { | |
105 | return asio::detail::socket_ops::network_to_host_short( | |
106 | data_.v4.sin_port); | |
107 | } | |
108 | else | |
109 | { | |
110 | return asio::detail::socket_ops::network_to_host_short( | |
111 | data_.v6.sin6_port); | |
112 | } | |
113 | } | |
114 | ||
115 | void endpoint::port(unsigned short port_num) | |
116 | { | |
117 | if (is_v4()) | |
118 | { | |
119 | data_.v4.sin_port | |
120 | = asio::detail::socket_ops::host_to_network_short(port_num); | |
121 | } | |
122 | else | |
123 | { | |
124 | data_.v6.sin6_port | |
125 | = asio::detail::socket_ops::host_to_network_short(port_num); | |
126 | } | |
127 | } | |
128 | ||
129 | asio::ip::address endpoint::address() const | |
130 | { | |
131 | using namespace std; // For memcpy. | |
132 | if (is_v4()) | |
133 | { | |
134 | return asio::ip::address_v4( | |
135 | asio::detail::socket_ops::network_to_host_long( | |
136 | data_.v4.sin_addr.s_addr)); | |
137 | } | |
138 | else | |
139 | { | |
140 | asio::ip::address_v6::bytes_type bytes; | |
141 | memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16); | |
142 | return asio::ip::address_v6(bytes, data_.v6.sin6_scope_id); | |
143 | } | |
144 | } | |
145 | ||
146 | void endpoint::address(const asio::ip::address& addr) | |
147 | { | |
148 | endpoint tmp_endpoint(addr, port()); | |
149 | data_ = tmp_endpoint.data_; | |
150 | } | |
151 | ||
152 | bool operator==(const endpoint& e1, const endpoint& e2) | |
153 | { | |
154 | return e1.address() == e2.address() && e1.port() == e2.port(); | |
155 | } | |
156 | ||
157 | bool operator<(const endpoint& e1, const endpoint& e2) | |
158 | { | |
159 | if (e1.address() < e2.address()) | |
160 | return true; | |
161 | if (e1.address() != e2.address()) | |
162 | return false; | |
163 | return e1.port() < e2.port(); | |
164 | } | |
165 | ||
166 | #if !defined(BOOST_NO_IOSTREAM) | |
167 | std::string endpoint::to_string(asio::error_code& ec) const | |
168 | { | |
169 | std::string a = address().to_string(ec); | |
170 | if (ec) | |
171 | return std::string(); | |
172 | ||
173 | std::ostringstream tmp_os; | |
174 | tmp_os.imbue(std::locale::classic()); | |
175 | if (is_v4()) | |
176 | tmp_os << a; | |
177 | else | |
178 | tmp_os << '[' << a << ']'; | |
179 | tmp_os << ':' << port(); | |
180 | ||
181 | return tmp_os.str(); | |
182 | } | |
183 | #endif // !defined(BOOST_NO_IOSTREAM) | |
184 | ||
185 | } // namespace detail | |
186 | } // namespace ip | |
187 | } // namespace asio | |
188 | ||
189 | #include "asio/detail/pop_options.hpp" | |
190 | ||
191 | #endif // ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP |