| // |
| // ip/basic_resolver_results.hpp |
| // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| // |
| // Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
| // |
| // Distributed under the Boost Software License, Version 1.0. (See accompanying |
| // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| // |
| |
| #ifndef ASIO_IP_BASIC_RESOLVER_RESULTS_HPP |
| #define ASIO_IP_BASIC_RESOLVER_RESULTS_HPP |
| |
| #if defined(_MSC_VER) && (_MSC_VER >= 1200) |
| # pragma once |
| #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) |
| |
| #include "asio/detail/config.hpp" |
| #include <cstddef> |
| #include <cstring> |
| #include "asio/detail/socket_ops.hpp" |
| #include "asio/detail/socket_types.hpp" |
| #include "asio/ip/basic_resolver_iterator.hpp" |
| |
| #if defined(ASIO_WINDOWS_RUNTIME) |
| # include "asio/detail/winrt_utils.hpp" |
| #endif // defined(ASIO_WINDOWS_RUNTIME) |
| |
| #include "asio/detail/push_options.hpp" |
| |
| namespace asio { |
| namespace ip { |
| |
| /// A range of entries produced by a resolver. |
| /** |
| * The asio::ip::basic_resolver_results class template is used to define |
| * a range over the results returned by a resolver. |
| * |
| * The iterator's value_type, obtained when a results iterator is dereferenced, |
| * is: @code const basic_resolver_entry<InternetProtocol> @endcode |
| * |
| * @note For backward compatibility, basic_resolver_results is derived from |
| * basic_resolver_iterator. This derivation is deprecated. |
| * |
| * @par Thread Safety |
| * @e Distinct @e objects: Safe.@n |
| * @e Shared @e objects: Unsafe. |
| */ |
| template <typename InternetProtocol> |
| class basic_resolver_results |
| #if !defined(ASIO_NO_DEPRECATED) |
| : public basic_resolver_iterator<InternetProtocol> |
| #else // !defined(ASIO_NO_DEPRECATED) |
| : private basic_resolver_iterator<InternetProtocol> |
| #endif // !defined(ASIO_NO_DEPRECATED) |
| { |
| public: |
| /// The protocol type associated with the results. |
| typedef InternetProtocol protocol_type; |
| |
| /// The endpoint type associated with the results. |
| typedef typename protocol_type::endpoint endpoint_type; |
| |
| /// The type of a value in the results range. |
| typedef basic_resolver_entry<endpoint_type> value_type; |
| |
| /// The type of a const reference to a value in the range. |
| typedef const value_type& const_reference; |
| |
| /// The type of a non-const reference to a value in the range. |
| typedef value_type& reference; |
| |
| /// The type of an iterator into the range. |
| typedef basic_resolver_iterator<protocol_type> const_iterator; |
| |
| /// The type of an iterator into the range. |
| typedef const_iterator iterator; |
| |
| /// Type used to represent the distance between two iterators in the range. |
| typedef std::ptrdiff_t difference_type; |
| |
| /// Type used to represent a count of the elements in the range. |
| typedef std::size_t size_type; |
| |
| /// Default constructor creates an empty range. |
| basic_resolver_results() |
| { |
| } |
| |
| /// Copy constructor. |
| basic_resolver_results(const basic_resolver_results& other) |
| : basic_resolver_iterator<InternetProtocol>(other) |
| { |
| } |
| |
| #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) |
| /// Move constructor. |
| basic_resolver_results(basic_resolver_results&& other) |
| : basic_resolver_iterator<InternetProtocol>( |
| ASIO_MOVE_CAST(basic_resolver_results)(other)) |
| { |
| } |
| #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) |
| |
| /// Assignment operator. |
| basic_resolver_results& operator=(const basic_resolver_results& other) |
| { |
| basic_resolver_iterator<InternetProtocol>::operator=(other); |
| return *this; |
| } |
| |
| #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) |
| /// Move-assignment operator. |
| basic_resolver_results& operator=(basic_resolver_results&& other) |
| { |
| basic_resolver_iterator<InternetProtocol>::operator=( |
| ASIO_MOVE_CAST(basic_resolver_results)(other)); |
| return *this; |
| } |
| #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) |
| |
| #if !defined(GENERATING_DOCUMENTATION) |
| // Create results from an addrinfo list returned by getaddrinfo. |
| static basic_resolver_results create( |
| asio::detail::addrinfo_type* address_info, |
| const std::string& host_name, const std::string& service_name) |
| { |
| basic_resolver_results results; |
| if (!address_info) |
| return results; |
| |
| std::string actual_host_name = host_name; |
| if (address_info->ai_canonname) |
| actual_host_name = address_info->ai_canonname; |
| |
| results.values_.reset(new values_type); |
| |
| while (address_info) |
| { |
| if (address_info->ai_family == ASIO_OS_DEF(AF_INET) |
| || address_info->ai_family == ASIO_OS_DEF(AF_INET6)) |
| { |
| using namespace std; // For memcpy. |
| typename InternetProtocol::endpoint endpoint; |
| endpoint.resize(static_cast<std::size_t>(address_info->ai_addrlen)); |
| memcpy(endpoint.data(), address_info->ai_addr, |
| address_info->ai_addrlen); |
| results.values_->push_back( |
| basic_resolver_entry<InternetProtocol>(endpoint, |
| actual_host_name, service_name)); |
| } |
| address_info = address_info->ai_next; |
| } |
| |
| return results; |
| } |
| |
| // Create results from an endpoint, host name and service name. |
| static basic_resolver_results create(const endpoint_type& endpoint, |
| const std::string& host_name, const std::string& service_name) |
| { |
| basic_resolver_results results; |
| results.values_.reset(new values_type); |
| results.values_->push_back( |
| basic_resolver_entry<InternetProtocol>( |
| endpoint, host_name, service_name)); |
| return results; |
| } |
| |
| // Create results from a sequence of endpoints, host and service name. |
| template <typename EndpointIterator> |
| static basic_resolver_results create( |
| EndpointIterator begin, EndpointIterator end, |
| const std::string& host_name, const std::string& service_name) |
| { |
| basic_resolver_results results; |
| if (begin != end) |
| { |
| results.values_.reset(new values_type); |
| for (EndpointIterator ep_iter = begin; ep_iter != end; ++ep_iter) |
| { |
| results.values_->push_back( |
| basic_resolver_entry<InternetProtocol>( |
| *ep_iter, host_name, service_name)); |
| } |
| } |
| return results; |
| } |
| |
| # if defined(ASIO_WINDOWS_RUNTIME) |
| // Create results from a Windows Runtime list of EndpointPair objects. |
| static basic_resolver_results create( |
| Windows::Foundation::Collections::IVectorView< |
| Windows::Networking::EndpointPair^>^ endpoints, |
| const asio::detail::addrinfo_type& hints, |
| const std::string& host_name, const std::string& service_name) |
| { |
| basic_resolver_results results; |
| if (endpoints->Size) |
| { |
| results.values_.reset(new values_type); |
| for (unsigned int i = 0; i < endpoints->Size; ++i) |
| { |
| auto pair = endpoints->GetAt(i); |
| |
| if (hints.ai_family == ASIO_OS_DEF(AF_INET) |
| && pair->RemoteHostName->Type |
| != Windows::Networking::HostNameType::Ipv4) |
| continue; |
| |
| if (hints.ai_family == ASIO_OS_DEF(AF_INET6) |
| && pair->RemoteHostName->Type |
| != Windows::Networking::HostNameType::Ipv6) |
| continue; |
| |
| results.values_->push_back( |
| basic_resolver_entry<InternetProtocol>( |
| typename InternetProtocol::endpoint( |
| ip::make_address( |
| asio::detail::winrt_utils::string( |
| pair->RemoteHostName->CanonicalName)), |
| asio::detail::winrt_utils::integer( |
| pair->RemoteServiceName)), |
| host_name, service_name)); |
| } |
| } |
| return results; |
| } |
| # endif // defined(ASIO_WINDOWS_RUNTIME) |
| #endif // !defined(GENERATING_DOCUMENTATION) |
| |
| /// Get the number of entries in the results range. |
| size_type size() const ASIO_NOEXCEPT |
| { |
| return this->values_->size(); |
| } |
| |
| /// Get the maximum number of entries permitted in a results range. |
| size_type max_size() const ASIO_NOEXCEPT |
| { |
| return this->values_->max_size(); |
| } |
| |
| /// Determine whether the results range is empty. |
| bool empty() const ASIO_NOEXCEPT |
| { |
| return this->values_->empty(); |
| } |
| |
| /// Obtain a begin iterator for the results range. |
| const_iterator begin() const |
| { |
| basic_resolver_results tmp(*this); |
| tmp.index_ = 0; |
| return tmp; |
| } |
| |
| /// Obtain an end iterator for the results range. |
| const_iterator end() const |
| { |
| return const_iterator(); |
| } |
| |
| /// Obtain a begin iterator for the results range. |
| const_iterator cbegin() const |
| { |
| return begin(); |
| } |
| |
| /// Obtain an end iterator for the results range. |
| const_iterator cend() const |
| { |
| return end(); |
| } |
| |
| /// Swap the results range with another. |
| void swap(basic_resolver_results& that) ASIO_NOEXCEPT |
| { |
| if (this != &that) |
| { |
| this->values_.swap(that.values_); |
| std::size_t index = this->index_; |
| this->index_ = that.index_; |
| that.index_ = index; |
| } |
| } |
| |
| /// Test two iterators for equality. |
| friend bool operator==(const basic_resolver_results& a, |
| const basic_resolver_results& b) |
| { |
| return a.equal(b); |
| } |
| |
| /// Test two iterators for inequality. |
| friend bool operator!=(const basic_resolver_results& a, |
| const basic_resolver_results& b) |
| { |
| return !a.equal(b); |
| } |
| |
| private: |
| typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type; |
| }; |
| |
| } // namespace ip |
| } // namespace asio |
| |
| #include "asio/detail/pop_options.hpp" |
| |
| #endif // ASIO_IP_BASIC_RESOLVER_RESULTS_HPP |