1 // 2 // ip/basic_resolver_results.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2021 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_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. 66 typedef basic_resolver_entry<protocol_type> value_type; 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. basic_resolver_results()87 basic_resolver_results() 88 { 89 } 90 91 /// Copy constructor. basic_resolver_results(const basic_resolver_results & other)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. basic_resolver_results(basic_resolver_results && other)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. operator =(const basic_resolver_results & other)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. operator =(basic_resolver_results && other)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. create(boost::asio::detail::addrinfo_type * address_info,const std::string & host_name,const std::string & service_name)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. create(const endpoint_type & endpoint,const std::string & host_name,const std::string & 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> create(EndpointIterator begin,EndpointIterator end,const std::string & host_name,const std::string & service_name)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. size() const234 size_type size() const BOOST_ASIO_NOEXCEPT 235 { 236 return this->values_ ? this->values_->size() : 0; 237 } 238 239 /// Get the maximum number of entries permitted in a results range. max_size() const240 size_type max_size() const BOOST_ASIO_NOEXCEPT 241 { 242 return this->values_ ? this->values_->max_size() : values_type().max_size(); 243 } 244 245 /// Determine whether the results range is empty. empty() const246 bool empty() const BOOST_ASIO_NOEXCEPT 247 { 248 return this->values_ ? this->values_->empty() : true; 249 } 250 251 /// Obtain a begin iterator for the results range. begin() const252 const_iterator begin() const 253 { 254 basic_resolver_results tmp(*this); 255 tmp.index_ = 0; 256 return BOOST_ASIO_MOVE_CAST(basic_resolver_results)(tmp); 257 } 258 259 /// Obtain an end iterator for the results range. end() const260 const_iterator end() const 261 { 262 return const_iterator(); 263 } 264 265 /// Obtain a begin iterator for the results range. cbegin() const266 const_iterator cbegin() const 267 { 268 return begin(); 269 } 270 271 /// Obtain an end iterator for the results range. cend() const272 const_iterator cend() const 273 { 274 return end(); 275 } 276 277 /// Swap the results range with another. swap(basic_resolver_results & that)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. operator ==(const basic_resolver_results & a,const basic_resolver_results & b)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. operator !=(const basic_resolver_results & a,const basic_resolver_results & b)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 314