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/shared_ptr.hpp>
00023 #include <cstring>
00024 #include <string>
00025 #include <vector>
00026 #include "asio/detail/pop_options.hpp"
00027
00028 #include "asio/detail/socket_ops.hpp"
00029 #include "asio/detail/socket_types.hpp"
00030 #include "asio/ip/basic_resolver_entry.hpp"
00031
00032 namespace asio {
00033 namespace ip {
00034
00036
00047 template <typename InternetProtocol>
00048 class basic_resolver_iterator
00049 : public boost::iterator_facade<
00050 basic_resolver_iterator<InternetProtocol>,
00051 const basic_resolver_entry<InternetProtocol>,
00052 boost::forward_traversal_tag>
00053 {
00054 public:
00056 basic_resolver_iterator()
00057 {
00058 }
00059
00061 static basic_resolver_iterator create(
00062 asio::detail::addrinfo_type* address_info,
00063 const std::string& host_name, const std::string& service_name)
00064 {
00065 basic_resolver_iterator iter;
00066 if (!address_info)
00067 return iter;
00068
00069 std::string actual_host_name = host_name;
00070 if (address_info->ai_canonname)
00071 actual_host_name = address_info->ai_canonname;
00072
00073 iter.values_.reset(new values_type);
00074
00075 while (address_info)
00076 {
00077 if (address_info->ai_family == PF_INET
00078 || address_info->ai_family == PF_INET6)
00079 {
00080 using namespace std;
00081 typename InternetProtocol::endpoint endpoint;
00082 endpoint.resize(
00083 static_cast<asio::detail::socket_addr_len_type>(
00084 address_info->ai_addrlen));
00085 memcpy(endpoint.data(), address_info->ai_addr,
00086 address_info->ai_addrlen);
00087 iter.values_->push_back(
00088 basic_resolver_entry<InternetProtocol>(endpoint,
00089 actual_host_name, service_name));
00090 }
00091 address_info = address_info->ai_next;
00092 }
00093
00094 if (iter.values_->size())
00095 iter.iter_ = iter.values_->begin();
00096 else
00097 iter.values_.reset();
00098
00099 return iter;
00100 }
00101
00103 static basic_resolver_iterator create(
00104 const typename InternetProtocol::endpoint& endpoint,
00105 const std::string& host_name, const std::string& service_name)
00106 {
00107 basic_resolver_iterator iter;
00108 iter.values_.reset(new values_type);
00109 iter.values_->push_back(
00110 basic_resolver_entry<InternetProtocol>(
00111 endpoint, host_name, service_name));
00112 iter.iter_ = iter.values_->begin();
00113 return iter;
00114 }
00115
00116 private:
00117 friend class boost::iterator_core_access;
00118
00119 void increment()
00120 {
00121 if (++iter_ == values_->end())
00122 {
00123
00124 values_.reset();
00125 typedef typename values_type::const_iterator values_iterator_type;
00126 iter_ = values_iterator_type();
00127 }
00128 }
00129
00130 bool equal(const basic_resolver_iterator& other) const
00131 {
00132 if (!values_ && !other.values_)
00133 return true;
00134 if (values_ != other.values_)
00135 return false;
00136 return iter_ == other.iter_;
00137 }
00138
00139 const basic_resolver_entry<InternetProtocol>& dereference() const
00140 {
00141 return *iter_;
00142 }
00143
00144 typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type;
00145 boost::shared_ptr<values_type> values_;
00146 typename values_type::const_iterator iter_;
00147 };
00148
00149 }
00150 }
00151
00152 #include "asio/detail/pop_options.hpp"
00153
00154 #endif // ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP