]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | // |
2 | // ip/basic_resolver_results.hpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
f67539c2 | 5 | // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
b32b8144 FG |
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_BASIC_RESOLVER_RESULTS_HPP | |
12 | #define BOOST_ASIO_IP_BASIC_RESOLVER_RESULTS_HPP | |
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 <cstddef> | |
20 | #include <cstring> | |
21 | #include <boost/asio/detail/socket_ops.hpp> | |
22 | #include <boost/asio/detail/socket_types.hpp> | |
23 | #include <boost/asio/ip/basic_resolver_iterator.hpp> | |
24 | ||
25 | #if defined(BOOST_ASIO_WINDOWS_RUNTIME) | |
26 | # include <boost/asio/detail/winrt_utils.hpp> | |
27 | #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) | |
28 | ||
29 | #include <boost/asio/detail/push_options.hpp> | |
30 | ||
31 | namespace boost { | |
32 | namespace asio { | |
33 | namespace ip { | |
34 | ||
35 | /// A range of entries produced by a resolver. | |
36 | /** | |
37 | * The boost::asio::ip::basic_resolver_results class template is used to define | |
38 | * a range over the results returned by a resolver. | |
39 | * | |
40 | * The iterator's value_type, obtained when a results iterator is dereferenced, | |
41 | * is: @code const basic_resolver_entry<InternetProtocol> @endcode | |
42 | * | |
43 | * @note For backward compatibility, basic_resolver_results is derived from | |
44 | * basic_resolver_iterator. This derivation is deprecated. | |
45 | * | |
46 | * @par Thread Safety | |
47 | * @e Distinct @e objects: Safe.@n | |
48 | * @e Shared @e objects: Unsafe. | |
49 | */ | |
50 | template <typename InternetProtocol> | |
51 | class basic_resolver_results | |
52 | #if !defined(BOOST_ASIO_NO_DEPRECATED) | |
53 | : public basic_resolver_iterator<InternetProtocol> | |
54 | #else // !defined(BOOST_ASIO_NO_DEPRECATED) | |
55 | : private basic_resolver_iterator<InternetProtocol> | |
56 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) | |
57 | { | |
58 | public: | |
59 | /// The protocol type associated with the results. | |
60 | typedef InternetProtocol protocol_type; | |
61 | ||
62 | /// The endpoint type associated with the results. | |
63 | typedef typename protocol_type::endpoint endpoint_type; | |
64 | ||
65 | /// The type of a value in the results range. | |
11fdf7f2 | 66 | typedef basic_resolver_entry<protocol_type> value_type; |
b32b8144 FG |
67 | |
68 | /// The type of a const reference to a value in the range. | |
69 | typedef const value_type& const_reference; | |
70 | ||
71 | /// The type of a non-const reference to a value in the range. | |
72 | typedef value_type& reference; | |
73 | ||
74 | /// The type of an iterator into the range. | |
75 | typedef basic_resolver_iterator<protocol_type> const_iterator; | |
76 | ||
77 | /// The type of an iterator into the range. | |
78 | typedef const_iterator iterator; | |
79 | ||
80 | /// Type used to represent the distance between two iterators in the range. | |
81 | typedef std::ptrdiff_t difference_type; | |
82 | ||
83 | /// Type used to represent a count of the elements in the range. | |
84 | typedef std::size_t size_type; | |
85 | ||
86 | /// Default constructor creates an empty range. | |
87 | basic_resolver_results() | |
88 | { | |
89 | } | |
90 | ||
91 | /// Copy constructor. | |
92 | basic_resolver_results(const basic_resolver_results& other) | |
93 | : basic_resolver_iterator<InternetProtocol>(other) | |
94 | { | |
95 | } | |
96 | ||
97 | #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
98 | /// Move constructor. | |
99 | basic_resolver_results(basic_resolver_results&& other) | |
100 | : basic_resolver_iterator<InternetProtocol>( | |
101 | BOOST_ASIO_MOVE_CAST(basic_resolver_results)(other)) | |
102 | { | |
103 | } | |
104 | #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
105 | ||
106 | /// Assignment operator. | |
107 | basic_resolver_results& operator=(const basic_resolver_results& other) | |
108 | { | |
109 | basic_resolver_iterator<InternetProtocol>::operator=(other); | |
110 | return *this; | |
111 | } | |
112 | ||
113 | #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
114 | /// Move-assignment operator. | |
115 | basic_resolver_results& operator=(basic_resolver_results&& other) | |
116 | { | |
117 | basic_resolver_iterator<InternetProtocol>::operator=( | |
118 | BOOST_ASIO_MOVE_CAST(basic_resolver_results)(other)); | |
119 | return *this; | |
120 | } | |
121 | #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
122 | ||
123 | #if !defined(GENERATING_DOCUMENTATION) | |
124 | // Create results from an addrinfo list returned by getaddrinfo. | |
125 | static basic_resolver_results create( | |
126 | boost::asio::detail::addrinfo_type* address_info, | |
127 | const std::string& host_name, const std::string& service_name) | |
128 | { | |
129 | basic_resolver_results results; | |
130 | if (!address_info) | |
131 | return results; | |
132 | ||
133 | std::string actual_host_name = host_name; | |
134 | if (address_info->ai_canonname) | |
135 | actual_host_name = address_info->ai_canonname; | |
136 | ||
137 | results.values_.reset(new values_type); | |
138 | ||
139 | while (address_info) | |
140 | { | |
141 | if (address_info->ai_family == BOOST_ASIO_OS_DEF(AF_INET) | |
142 | || address_info->ai_family == BOOST_ASIO_OS_DEF(AF_INET6)) | |
143 | { | |
144 | using namespace std; // For memcpy. | |
145 | typename InternetProtocol::endpoint endpoint; | |
146 | endpoint.resize(static_cast<std::size_t>(address_info->ai_addrlen)); | |
147 | memcpy(endpoint.data(), address_info->ai_addr, | |
148 | address_info->ai_addrlen); | |
149 | results.values_->push_back( | |
150 | basic_resolver_entry<InternetProtocol>(endpoint, | |
151 | actual_host_name, service_name)); | |
152 | } | |
153 | address_info = address_info->ai_next; | |
154 | } | |
155 | ||
156 | return results; | |
157 | } | |
158 | ||
159 | // Create results from an endpoint, host name and service name. | |
160 | static basic_resolver_results create(const endpoint_type& endpoint, | |
161 | const std::string& host_name, const std::string& service_name) | |
162 | { | |
163 | basic_resolver_results results; | |
164 | results.values_.reset(new values_type); | |
165 | results.values_->push_back( | |
166 | basic_resolver_entry<InternetProtocol>( | |
167 | endpoint, host_name, service_name)); | |
168 | return results; | |
169 | } | |
170 | ||
171 | // Create results from a sequence of endpoints, host and service name. | |
172 | template <typename EndpointIterator> | |
173 | static basic_resolver_results create( | |
174 | EndpointIterator begin, EndpointIterator end, | |
175 | const std::string& host_name, const std::string& service_name) | |
176 | { | |
177 | basic_resolver_results results; | |
178 | if (begin != end) | |
179 | { | |
180 | results.values_.reset(new values_type); | |
181 | for (EndpointIterator ep_iter = begin; ep_iter != end; ++ep_iter) | |
182 | { | |
183 | results.values_->push_back( | |
184 | basic_resolver_entry<InternetProtocol>( | |
185 | *ep_iter, host_name, service_name)); | |
186 | } | |
187 | } | |
188 | return results; | |
189 | } | |
190 | ||
191 | # if defined(BOOST_ASIO_WINDOWS_RUNTIME) | |
192 | // Create results from a Windows Runtime list of EndpointPair objects. | |
193 | static basic_resolver_results create( | |
194 | Windows::Foundation::Collections::IVectorView< | |
195 | Windows::Networking::EndpointPair^>^ endpoints, | |
196 | const boost::asio::detail::addrinfo_type& hints, | |
197 | const std::string& host_name, const std::string& service_name) | |
198 | { | |
199 | basic_resolver_results results; | |
200 | if (endpoints->Size) | |
201 | { | |
202 | results.values_.reset(new values_type); | |
203 | for (unsigned int i = 0; i < endpoints->Size; ++i) | |
204 | { | |
205 | auto pair = endpoints->GetAt(i); | |
206 | ||
207 | if (hints.ai_family == BOOST_ASIO_OS_DEF(AF_INET) | |
208 | && pair->RemoteHostName->Type | |
209 | != Windows::Networking::HostNameType::Ipv4) | |
210 | continue; | |
211 | ||
212 | if (hints.ai_family == BOOST_ASIO_OS_DEF(AF_INET6) | |
213 | && pair->RemoteHostName->Type | |
214 | != Windows::Networking::HostNameType::Ipv6) | |
215 | continue; | |
216 | ||
217 | results.values_->push_back( | |
218 | basic_resolver_entry<InternetProtocol>( | |
219 | typename InternetProtocol::endpoint( | |
220 | ip::make_address( | |
221 | boost::asio::detail::winrt_utils::string( | |
222 | pair->RemoteHostName->CanonicalName)), | |
223 | boost::asio::detail::winrt_utils::integer( | |
224 | pair->RemoteServiceName)), | |
225 | host_name, service_name)); | |
226 | } | |
227 | } | |
228 | return results; | |
229 | } | |
230 | # endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) | |
231 | #endif // !defined(GENERATING_DOCUMENTATION) | |
232 | ||
233 | /// Get the number of entries in the results range. | |
234 | size_type size() const BOOST_ASIO_NOEXCEPT | |
235 | { | |
92f5a8d4 | 236 | return this->values_ ? this->values_->size() : 0; |
b32b8144 FG |
237 | } |
238 | ||
239 | /// Get the maximum number of entries permitted in a results range. | |
240 | size_type max_size() const BOOST_ASIO_NOEXCEPT | |
241 | { | |
92f5a8d4 | 242 | return this->values_ ? this->values_->max_size() : values_type().max_size(); |
b32b8144 FG |
243 | } |
244 | ||
245 | /// Determine whether the results range is empty. | |
246 | bool empty() const BOOST_ASIO_NOEXCEPT | |
247 | { | |
92f5a8d4 | 248 | return this->values_ ? this->values_->empty() : true; |
b32b8144 FG |
249 | } |
250 | ||
251 | /// Obtain a begin iterator for the results range. | |
252 | const_iterator begin() const | |
253 | { | |
254 | basic_resolver_results tmp(*this); | |
255 | tmp.index_ = 0; | |
92f5a8d4 | 256 | return BOOST_ASIO_MOVE_CAST(basic_resolver_results)(tmp); |
b32b8144 FG |
257 | } |
258 | ||
259 | /// Obtain an end iterator for the results range. | |
260 | const_iterator end() const | |
261 | { | |
262 | return const_iterator(); | |
263 | } | |
264 | ||
265 | /// Obtain a begin iterator for the results range. | |
266 | const_iterator cbegin() const | |
267 | { | |
268 | return begin(); | |
269 | } | |
270 | ||
271 | /// Obtain an end iterator for the results range. | |
272 | const_iterator cend() const | |
273 | { | |
274 | return end(); | |
275 | } | |
276 | ||
277 | /// Swap the results range with another. | |
278 | void swap(basic_resolver_results& that) BOOST_ASIO_NOEXCEPT | |
279 | { | |
280 | if (this != &that) | |
281 | { | |
282 | this->values_.swap(that.values_); | |
283 | std::size_t index = this->index_; | |
284 | this->index_ = that.index_; | |
285 | that.index_ = index; | |
286 | } | |
287 | } | |
288 | ||
289 | /// Test two iterators for equality. | |
290 | friend bool operator==(const basic_resolver_results& a, | |
291 | const basic_resolver_results& b) | |
292 | { | |
293 | return a.equal(b); | |
294 | } | |
295 | ||
296 | /// Test two iterators for inequality. | |
297 | friend bool operator!=(const basic_resolver_results& a, | |
298 | const basic_resolver_results& b) | |
299 | { | |
300 | return !a.equal(b); | |
301 | } | |
302 | ||
303 | private: | |
304 | typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type; | |
305 | }; | |
306 | ||
307 | } // namespace ip | |
308 | } // namespace asio | |
309 | } // namespace boost | |
310 | ||
311 | #include <boost/asio/detail/pop_options.hpp> | |
312 | ||
313 | #endif // BOOST_ASIO_IP_BASIC_RESOLVER_RESULTS_HPP |