Chris@16: // Chris@16: // ip/basic_resolver_iterator.hpp Chris@16: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Chris@16: // Chris@101: // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP Chris@16: #define BOOST_ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if defined(BOOST_ASIO_WINDOWS_RUNTIME) Chris@16: # include Chris@16: #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: namespace ip { Chris@16: Chris@16: /// An iterator over the entries produced by a resolver. Chris@16: /** Chris@16: * The boost::asio::ip::basic_resolver_iterator class template is used to define Chris@16: * iterators over the results returned by a resolver. Chris@16: * Chris@16: * The iterator's value_type, obtained when the iterator is dereferenced, is: Chris@16: * @code const basic_resolver_entry @endcode Chris@16: * Chris@16: * @par Thread Safety Chris@16: * @e Distinct @e objects: Safe.@n Chris@16: * @e Shared @e objects: Unsafe. Chris@16: */ Chris@16: template Chris@16: class basic_resolver_iterator Chris@16: { Chris@16: public: Chris@16: /// The type used for the distance between two iterators. Chris@16: typedef std::ptrdiff_t difference_type; Chris@16: Chris@16: /// The type of the value pointed to by the iterator. Chris@16: typedef basic_resolver_entry value_type; Chris@16: Chris@16: /// The type of the result of applying operator->() to the iterator. Chris@16: typedef const basic_resolver_entry* pointer; Chris@16: Chris@16: /// The type of the result of applying operator*() to the iterator. Chris@16: typedef const basic_resolver_entry& reference; Chris@16: Chris@16: /// The iterator category. Chris@16: typedef std::forward_iterator_tag iterator_category; Chris@16: Chris@16: /// Default constructor creates an end iterator. Chris@16: basic_resolver_iterator() Chris@16: : index_(0) Chris@16: { Chris@16: } Chris@16: Chris@16: /// Create an iterator from an addrinfo list returned by getaddrinfo. Chris@16: static basic_resolver_iterator create( Chris@16: boost::asio::detail::addrinfo_type* address_info, Chris@16: const std::string& host_name, const std::string& service_name) Chris@16: { Chris@16: basic_resolver_iterator iter; Chris@16: if (!address_info) Chris@16: return iter; Chris@16: Chris@16: std::string actual_host_name = host_name; Chris@16: if (address_info->ai_canonname) Chris@16: actual_host_name = address_info->ai_canonname; Chris@16: Chris@16: iter.values_.reset(new values_type); Chris@16: Chris@16: while (address_info) Chris@16: { Chris@16: if (address_info->ai_family == BOOST_ASIO_OS_DEF(AF_INET) Chris@16: || address_info->ai_family == BOOST_ASIO_OS_DEF(AF_INET6)) Chris@16: { Chris@16: using namespace std; // For memcpy. Chris@16: typename InternetProtocol::endpoint endpoint; Chris@16: endpoint.resize(static_cast(address_info->ai_addrlen)); Chris@16: memcpy(endpoint.data(), address_info->ai_addr, Chris@16: address_info->ai_addrlen); Chris@16: iter.values_->push_back( Chris@16: basic_resolver_entry(endpoint, Chris@16: actual_host_name, service_name)); Chris@16: } Chris@16: address_info = address_info->ai_next; Chris@16: } Chris@16: Chris@16: return iter; Chris@16: } Chris@16: Chris@16: /// Create an iterator from an endpoint, host name and service name. Chris@16: static basic_resolver_iterator create( Chris@16: const typename InternetProtocol::endpoint& endpoint, Chris@16: const std::string& host_name, const std::string& service_name) Chris@16: { Chris@16: basic_resolver_iterator iter; Chris@16: iter.values_.reset(new values_type); Chris@16: iter.values_->push_back( Chris@16: basic_resolver_entry( Chris@16: endpoint, host_name, service_name)); Chris@16: return iter; Chris@16: } Chris@16: Chris@16: /// Create an iterator from a sequence of endpoints, host and service name. Chris@16: template Chris@16: static basic_resolver_iterator create( Chris@16: EndpointIterator begin, EndpointIterator end, Chris@16: const std::string& host_name, const std::string& service_name) Chris@16: { Chris@16: basic_resolver_iterator iter; Chris@16: if (begin != end) Chris@16: { Chris@16: iter.values_.reset(new values_type); Chris@16: for (EndpointIterator ep_iter = begin; ep_iter != end; ++ep_iter) Chris@16: { Chris@16: iter.values_->push_back( Chris@16: basic_resolver_entry( Chris@16: *ep_iter, host_name, service_name)); Chris@16: } Chris@16: } Chris@16: return iter; Chris@16: } Chris@16: Chris@16: #if defined(BOOST_ASIO_WINDOWS_RUNTIME) Chris@16: /// Create an iterator from a Windows Runtime list of EndpointPair objects. Chris@16: static basic_resolver_iterator create( Chris@16: Windows::Foundation::Collections::IVectorView< Chris@16: Windows::Networking::EndpointPair^>^ endpoints, Chris@16: const boost::asio::detail::addrinfo_type& hints, Chris@16: const std::string& host_name, const std::string& service_name) Chris@16: { Chris@16: basic_resolver_iterator iter; Chris@16: if (endpoints->Size) Chris@16: { Chris@16: iter.values_.reset(new values_type); Chris@16: for (unsigned int i = 0; i < endpoints->Size; ++i) Chris@16: { Chris@16: auto pair = endpoints->GetAt(i); Chris@16: Chris@16: if (hints.ai_family == BOOST_ASIO_OS_DEF(AF_INET) Chris@16: && pair->RemoteHostName->Type Chris@16: != Windows::Networking::HostNameType::Ipv4) Chris@16: continue; Chris@16: Chris@16: if (hints.ai_family == BOOST_ASIO_OS_DEF(AF_INET6) Chris@16: && pair->RemoteHostName->Type Chris@16: != Windows::Networking::HostNameType::Ipv6) Chris@16: continue; Chris@16: Chris@16: iter.values_->push_back( Chris@16: basic_resolver_entry( Chris@16: typename InternetProtocol::endpoint( Chris@16: ip::address::from_string( Chris@16: boost::asio::detail::winrt_utils::string( Chris@16: pair->RemoteHostName->CanonicalName)), Chris@16: boost::asio::detail::winrt_utils::integer( Chris@16: pair->RemoteServiceName)), Chris@16: host_name, service_name)); Chris@16: } Chris@16: } Chris@16: return iter; Chris@16: } Chris@16: #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) Chris@16: Chris@16: /// Dereference an iterator. Chris@16: const basic_resolver_entry& operator*() const Chris@16: { Chris@16: return dereference(); Chris@16: } Chris@16: Chris@16: /// Dereference an iterator. Chris@16: const basic_resolver_entry* operator->() const Chris@16: { Chris@16: return &dereference(); Chris@16: } Chris@16: Chris@16: /// Increment operator (prefix). Chris@16: basic_resolver_iterator& operator++() Chris@16: { Chris@16: increment(); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /// Increment operator (postfix). Chris@16: basic_resolver_iterator operator++(int) Chris@16: { Chris@16: basic_resolver_iterator tmp(*this); Chris@16: ++*this; Chris@16: return tmp; Chris@16: } Chris@16: Chris@16: /// Test two iterators for equality. Chris@16: friend bool operator==(const basic_resolver_iterator& a, Chris@16: const basic_resolver_iterator& b) Chris@16: { Chris@16: return a.equal(b); Chris@16: } Chris@16: Chris@16: /// Test two iterators for inequality. Chris@16: friend bool operator!=(const basic_resolver_iterator& a, Chris@16: const basic_resolver_iterator& b) Chris@16: { Chris@16: return !a.equal(b); Chris@16: } Chris@16: Chris@16: private: Chris@16: void increment() Chris@16: { Chris@16: if (++index_ == values_->size()) Chris@16: { Chris@16: // Reset state to match a default constructed end iterator. Chris@16: values_.reset(); Chris@16: index_ = 0; Chris@16: } Chris@16: } Chris@16: Chris@16: bool equal(const basic_resolver_iterator& other) const Chris@16: { Chris@16: if (!values_ && !other.values_) Chris@16: return true; Chris@16: if (values_ != other.values_) Chris@16: return false; Chris@16: return index_ == other.index_; Chris@16: } Chris@16: Chris@16: const basic_resolver_entry& dereference() const Chris@16: { Chris@16: return (*values_)[index_]; Chris@16: } Chris@16: Chris@16: typedef std::vector > values_type; Chris@16: boost::asio::detail::shared_ptr values_; Chris@16: std::size_t index_; Chris@16: }; Chris@16: Chris@16: } // namespace ip Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP