1//
2// ip/basic_resolver.hpp
3// ~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2015 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 ASIO_IP_BASIC_RESOLVER_HPP
12#define ASIO_IP_BASIC_RESOLVER_HPP
13
14
15#include "asio/detail/config.hpp"
16#include "asio/basic_io_object.hpp"
17#include "asio/detail/handler_type_requirements.hpp"
18#include "asio/detail/throw_error.hpp"
19#include "asio/error.hpp"
20#include "asio/ip/basic_resolver_iterator.hpp"
21#include "asio/ip/basic_resolver_query.hpp"
22#include "asio/ip/resolver_service.hpp"
23
24#include "asio/detail/push_options.hpp"
25
26namespace asio {
27namespace ip {
28
29/// Provides endpoint resolution functionality.
30/**
31 * The basic_resolver class template provides the ability to resolve a query
32 * to a list of endpoints.
33 *
34 * @par Thread Safety
35 * @e Distinct @e objects: Safe.@n
36 * @e Shared @e objects: Unsafe.
37 */
38template <typename InternetProtocol,
39    typename ResolverService = resolver_service<InternetProtocol> >
40class basic_resolver
41  : public basic_io_object<ResolverService>
42{
43public:
44  /// The protocol type.
45  typedef InternetProtocol protocol_type;
46
47  /// The endpoint type.
48  typedef typename InternetProtocol::endpoint endpoint_type;
49
50  /// The query type.
51  typedef basic_resolver_query<InternetProtocol> query;
52
53  /// The iterator type.
54  typedef basic_resolver_iterator<InternetProtocol> iterator;
55
56  /// Constructor.
57  /**
58   * This constructor creates a basic_resolver.
59   *
60   * @param io_service The io_service object that the resolver will use to
61   * dispatch handlers for any asynchronous operations performed on the timer.
62   */
63  explicit basic_resolver(asio::io_service& io_service)
64    : basic_io_object<ResolverService>(io_service)
65  {
66  }
67
68  /// Cancel any asynchronous operations that are waiting on the resolver.
69  /**
70   * This function forces the completion of any pending asynchronous
71   * operations on the host resolver. The handler for each cancelled operation
72   * will be invoked with the asio::error::operation_aborted error code.
73   */
74  void cancel()
75  {
76    return this->service.cancel(this->implementation);
77  }
78
79  /// Perform forward resolution of a query to a list of entries.
80  /**
81   * This function is used to resolve a query into a list of endpoint entries.
82   *
83   * @param q A query object that determines what endpoints will be returned.
84   *
85   * @returns A forward-only iterator that can be used to traverse the list
86   * of endpoint entries.
87   *
88   * @throws asio::system_error Thrown on failure.
89   *
90   * @note A default constructed iterator represents the end of the list.
91   *
92   * A successful call to this function is guaranteed to return at least one
93   * entry.
94   */
95  iterator resolve(const query& q)
96  {
97    asio::error_code ec;
98    iterator i = this->service.resolve(this->implementation, q, ec);
99    asio::detail::throw_error(ec, "resolve");
100    return i;
101  }
102
103  /// Perform forward resolution of a query to a list of entries.
104  /**
105   * This function is used to resolve a query into a list of endpoint entries.
106   *
107   * @param q A query object that determines what endpoints will be returned.
108   *
109   * @param ec Set to indicate what error occurred, if any.
110   *
111   * @returns A forward-only iterator that can be used to traverse the list
112   * of endpoint entries. Returns a default constructed iterator if an error
113   * occurs.
114   *
115   * @note A default constructed iterator represents the end of the list.
116   *
117   * A successful call to this function is guaranteed to return at least one
118   * entry.
119   */
120  iterator resolve(const query& q, asio::error_code& ec)
121  {
122    return this->service.resolve(this->implementation, q, ec);
123  }
124
125  /// Asynchronously perform forward resolution of a query to a list of entries.
126  /**
127   * This function is used to asynchronously resolve a query into a list of
128   * endpoint entries.
129   *
130   * @param q A query object that determines what endpoints will be returned.
131   *
132   * @param handler The handler to be called when the resolve operation
133   * completes. Copies will be made of the handler as required. The function
134   * signature of the handler must be:
135   * @code void handler(
136   *   const asio::error_code& error, // Result of operation.
137   *   resolver::iterator iterator             // Forward-only iterator that can
138   *                                           // be used to traverse the list
139   *                                           // of endpoint entries.
140   * ); @endcode
141   * Regardless of whether the asynchronous operation completes immediately or
142   * not, the handler will not be invoked from within this function. Invocation
143   * of the handler will be performed in a manner equivalent to using
144   * asio::io_service::post().
145   *
146   * @note A default constructed iterator represents the end of the list.
147   *
148   * A successful resolve operation is guaranteed to pass at least one entry to
149   * the handler.
150   */
151  template <typename ResolveHandler>
152  ASIO_INITFN_RESULT_TYPE(ResolveHandler,
153      void (asio::error_code, iterator))
154  async_resolve(const query& q,
155      ASIO_MOVE_ARG(ResolveHandler) handler)
156  {
157    // If you get an error on the following line it means that your handler does
158    // not meet the documented type requirements for a ResolveHandler.
159    ASIO_RESOLVE_HANDLER_CHECK(
160        ResolveHandler, handler, iterator) type_check;
161
162    return this->service.async_resolve(this->implementation, q,
163        ASIO_MOVE_CAST(ResolveHandler)(handler));
164  }
165
166  /// Perform reverse resolution of an endpoint to a list of entries.
167  /**
168   * This function is used to resolve an endpoint into a list of endpoint
169   * entries.
170   *
171   * @param e An endpoint object that determines what endpoints will be
172   * returned.
173   *
174   * @returns A forward-only iterator that can be used to traverse the list
175   * of endpoint entries.
176   *
177   * @throws asio::system_error Thrown on failure.
178   *
179   * @note A default constructed iterator represents the end of the list.
180   *
181   * A successful call to this function is guaranteed to return at least one
182   * entry.
183   */
184  iterator resolve(const endpoint_type& e)
185  {
186    asio::error_code ec;
187    iterator i = this->service.resolve(this->implementation, e, ec);
188    asio::detail::throw_error(ec, "resolve");
189    return i;
190  }
191
192  /// Perform reverse resolution of an endpoint to a list of entries.
193  /**
194   * This function is used to resolve an endpoint into a list of endpoint
195   * entries.
196   *
197   * @param e An endpoint object that determines what endpoints will be
198   * returned.
199   *
200   * @param ec Set to indicate what error occurred, if any.
201   *
202   * @returns A forward-only iterator that can be used to traverse the list
203   * of endpoint entries. Returns a default constructed iterator if an error
204   * occurs.
205   *
206   * @note A default constructed iterator represents the end of the list.
207   *
208   * A successful call to this function is guaranteed to return at least one
209   * entry.
210   */
211  iterator resolve(const endpoint_type& e, asio::error_code& ec)
212  {
213    return this->service.resolve(this->implementation, e, ec);
214  }
215
216  /// Asynchronously perform reverse resolution of an endpoint to a list of
217  /// entries.
218  /**
219   * This function is used to asynchronously resolve an endpoint into a list of
220   * endpoint entries.
221   *
222   * @param e An endpoint object that determines what endpoints will be
223   * returned.
224   *
225   * @param handler The handler to be called when the resolve operation
226   * completes. Copies will be made of the handler as required. The function
227   * signature of the handler must be:
228   * @code void handler(
229   *   const asio::error_code& error, // Result of operation.
230   *   resolver::iterator iterator             // Forward-only iterator that can
231   *                                           // be used to traverse the list
232   *                                           // of endpoint entries.
233   * ); @endcode
234   * Regardless of whether the asynchronous operation completes immediately or
235   * not, the handler will not be invoked from within this function. Invocation
236   * of the handler will be performed in a manner equivalent to using
237   * asio::io_service::post().
238   *
239   * @note A default constructed iterator represents the end of the list.
240   *
241   * A successful resolve operation is guaranteed to pass at least one entry to
242   * the handler.
243   */
244  template <typename ResolveHandler>
245  ASIO_INITFN_RESULT_TYPE(ResolveHandler,
246      void (asio::error_code, iterator))
247  async_resolve(const endpoint_type& e,
248      ASIO_MOVE_ARG(ResolveHandler) handler)
249  {
250    // If you get an error on the following line it means that your handler does
251    // not meet the documented type requirements for a ResolveHandler.
252    ASIO_RESOLVE_HANDLER_CHECK(
253        ResolveHandler, handler, iterator) type_check;
254
255    return this->service.async_resolve(this->implementation, e,
256        ASIO_MOVE_CAST(ResolveHandler)(handler));
257  }
258};
259
260} // namespace ip
261} // namespace asio
262
263#include "asio/detail/pop_options.hpp"
264
265#endif // ASIO_IP_BASIC_RESOLVER_HPP
266