Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP
00012 #define ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP
00013
00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00015 # pragma once
00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
00017
00018 #include "asio/detail/push_options.hpp"
00019
00020 #include "asio/detail/push_options.hpp"
00021 #include <boost/iterator/iterator_facade.hpp>
00022 #include <boost/optional.hpp>
00023 #include <boost/shared_ptr.hpp>
00024 #include <cstring>
00025 #include <string>
00026 #include <vector>
00027 #include "asio/detail/pop_options.hpp"
00028
00029 #include "asio/detail/socket_ops.hpp"
00030 #include "asio/detail/socket_types.hpp"
00031 #include "asio/ip/basic_resolver_entry.hpp"
00032
00033 namespace asio {
00034 namespace ip {
00035
00037
00048 template <typename InternetProtocol>
00049 class basic_resolver_iterator
00050 : public boost::iterator_facade<
00051 basic_resolver_iterator<InternetProtocol>,
00052 const basic_resolver_entry<InternetProtocol>,
00053 boost::forward_traversal_tag>
00054 {
00055 public:
00057 basic_resolver_iterator()
00058 {
00059 }
00060
00062 static basic_resolver_iterator create(
00063 asio::detail::addrinfo_type* address_info,
00064 const std::string& host_name, const std::string& service_name)
00065 {
00066 basic_resolver_iterator iter;
00067 if (!address_info)
00068 return iter;
00069
00070 std::string actual_host_name = host_name;
00071 if (address_info->ai_canonname)
00072 actual_host_name = address_info->ai_canonname;
00073
00074 iter.values_.reset(new values_type);
00075
00076 while (address_info)
00077 {
00078 if (address_info->ai_family == PF_INET
00079 || address_info->ai_family == PF_INET6)
00080 {
00081 using namespace std;
00082 typename InternetProtocol::endpoint endpoint;
00083 endpoint.resize(static_cast<std::size_t>(address_info->ai_addrlen));
00084 memcpy(endpoint.data(), address_info->ai_addr,
00085 address_info->ai_addrlen);
00086 iter.values_->push_back(
00087 basic_resolver_entry<InternetProtocol>(endpoint,
00088 actual_host_name, service_name));
00089 }
00090 address_info = address_info->ai_next;
00091 }
00092
00093 if (iter.values_->size())
00094 iter.iter_ = iter.values_->begin();
00095 else
00096 iter.values_.reset();
00097
00098 return iter;
00099 }
00100
00102 static basic_resolver_iterator create(
00103 const typename InternetProtocol::endpoint& endpoint,
00104 const std::string& host_name, const std::string& service_name)
00105 {
00106 basic_resolver_iterator iter;
00107 iter.values_.reset(new values_type);
00108 iter.values_->push_back(
00109 basic_resolver_entry<InternetProtocol>(
00110 endpoint, host_name, service_name));
00111 iter.iter_ = iter.values_->begin();
00112 return iter;
00113 }
00114
00115 private:
00116 friend class boost::iterator_core_access;
00117
00118 void increment()
00119 {
00120 if (++*iter_ == values_->end())
00121 {
00122
00123 values_.reset();
00124 typedef typename values_type::const_iterator values_iterator_type;
00125 iter_.reset();
00126 }
00127 }
00128
00129 bool equal(const basic_resolver_iterator& other) const
00130 {
00131 if (!values_ && !other.values_)
00132 return true;
00133 if (values_ != other.values_)
00134 return false;
00135 return *iter_ == *other.iter_;
00136 }
00137
00138 const basic_resolver_entry<InternetProtocol>& dereference() const
00139 {
00140 return **iter_;
00141 }
00142
00143 typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type;
00144 typedef typename values_type::const_iterator values_iter_type;
00145 boost::shared_ptr<values_type> values_;
00146 boost::optional<values_iter_type> iter_;
00147 };
00148
00149 }
00150 }
00151
00152 #include "asio/detail/pop_options.hpp"
00153
00154 #endif // ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP