]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // detail/winrt_resolver_service.hpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
11fdf7f2 | 5 | // Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
7c673cae FG |
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 BOOST_ASIO_DETAIL_WINRT_RESOLVER_SERVICE_HPP | |
12 | #define BOOST_ASIO_DETAIL_WINRT_RESOLVER_SERVICE_HPP | |
13 | ||
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) | |
15 | # pragma once | |
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) | |
17 | ||
18 | #include <boost/asio/detail/config.hpp> | |
19 | ||
20 | #if defined(BOOST_ASIO_WINDOWS_RUNTIME) | |
21 | ||
7c673cae | 22 | #include <boost/asio/ip/basic_resolver_query.hpp> |
b32b8144 | 23 | #include <boost/asio/ip/basic_resolver_results.hpp> |
7c673cae | 24 | #include <boost/asio/detail/bind_handler.hpp> |
b32b8144 | 25 | #include <boost/asio/detail/memory.hpp> |
7c673cae FG |
26 | #include <boost/asio/detail/socket_ops.hpp> |
27 | #include <boost/asio/detail/winrt_async_manager.hpp> | |
28 | #include <boost/asio/detail/winrt_resolve_op.hpp> | |
29 | #include <boost/asio/detail/winrt_utils.hpp> | |
30 | ||
31 | #include <boost/asio/detail/push_options.hpp> | |
32 | ||
33 | namespace boost { | |
34 | namespace asio { | |
35 | namespace detail { | |
36 | ||
37 | template <typename Protocol> | |
b32b8144 FG |
38 | class winrt_resolver_service : |
39 | public service_base<winrt_resolver_service<Protocol> > | |
7c673cae FG |
40 | { |
41 | public: | |
42 | // The implementation type of the resolver. A cancellation token is used to | |
43 | // indicate to the asynchronous operation that the operation has been | |
44 | // cancelled. | |
45 | typedef socket_ops::shared_cancel_token_type implementation_type; | |
46 | ||
47 | // The endpoint type. | |
48 | typedef typename Protocol::endpoint endpoint_type; | |
49 | ||
50 | // The query type. | |
51 | typedef boost::asio::ip::basic_resolver_query<Protocol> query_type; | |
52 | ||
b32b8144 FG |
53 | // The results type. |
54 | typedef boost::asio::ip::basic_resolver_results<Protocol> results_type; | |
7c673cae FG |
55 | |
56 | // Constructor. | |
b32b8144 FG |
57 | winrt_resolver_service(boost::asio::io_context& io_context) |
58 | : service_base<winrt_resolver_service<Protocol> >(io_context), | |
59 | io_context_(use_service<io_context_impl>(io_context)), | |
60 | async_manager_(use_service<winrt_async_manager>(io_context)) | |
7c673cae FG |
61 | { |
62 | } | |
63 | ||
64 | // Destructor. | |
65 | ~winrt_resolver_service() | |
66 | { | |
67 | } | |
68 | ||
69 | // Destroy all user-defined handler objects owned by the service. | |
b32b8144 | 70 | void shutdown() |
7c673cae FG |
71 | { |
72 | } | |
73 | ||
74 | // Perform any fork-related housekeeping. | |
b32b8144 | 75 | void notify_fork(boost::asio::io_context::fork_event) |
7c673cae FG |
76 | { |
77 | } | |
78 | ||
79 | // Construct a new resolver implementation. | |
80 | void construct(implementation_type&) | |
81 | { | |
82 | } | |
83 | ||
b32b8144 FG |
84 | // Move-construct a new resolver implementation. |
85 | void move_construct(implementation_type&, | |
86 | implementation_type&) | |
87 | { | |
88 | } | |
89 | ||
90 | // Move-assign from another resolver implementation. | |
91 | void move_assign(implementation_type&, | |
92 | winrt_resolver_service&, implementation_type&) | |
93 | { | |
94 | } | |
95 | ||
7c673cae FG |
96 | // Destroy a resolver implementation. |
97 | void destroy(implementation_type&) | |
98 | { | |
99 | } | |
100 | ||
101 | // Cancel pending asynchronous operations. | |
102 | void cancel(implementation_type&) | |
103 | { | |
104 | } | |
105 | ||
106 | // Resolve a query to a list of entries. | |
b32b8144 | 107 | results_type resolve(implementation_type&, |
7c673cae FG |
108 | const query_type& query, boost::system::error_code& ec) |
109 | { | |
110 | try | |
111 | { | |
112 | using namespace Windows::Networking::Sockets; | |
113 | auto endpoint_pairs = async_manager_.sync( | |
114 | DatagramSocket::GetEndpointPairsAsync( | |
115 | winrt_utils::host_name(query.host_name()), | |
116 | winrt_utils::string(query.service_name())), ec); | |
117 | ||
118 | if (ec) | |
b32b8144 | 119 | return results_type(); |
7c673cae | 120 | |
b32b8144 | 121 | return results_type::create( |
7c673cae FG |
122 | endpoint_pairs, query.hints(), |
123 | query.host_name(), query.service_name()); | |
124 | } | |
125 | catch (Platform::Exception^ e) | |
126 | { | |
127 | ec = boost::system::error_code(e->HResult, | |
128 | boost::system::system_category()); | |
b32b8144 | 129 | return results_type(); |
7c673cae FG |
130 | } |
131 | } | |
132 | ||
133 | // Asynchronously resolve a query to a list of entries. | |
134 | template <typename Handler> | |
b32b8144 | 135 | void async_resolve(implementation_type& impl, |
7c673cae FG |
136 | const query_type& query, Handler& handler) |
137 | { | |
138 | bool is_continuation = | |
139 | boost_asio_handler_cont_helpers::is_continuation(handler); | |
140 | ||
141 | // Allocate and construct an operation to wrap the handler. | |
142 | typedef winrt_resolve_op<Protocol, Handler> op; | |
143 | typename op::ptr p = { boost::asio::detail::addressof(handler), | |
b32b8144 | 144 | op::ptr::allocate(handler), 0 }; |
7c673cae FG |
145 | p.p = new (p.v) op(query, handler); |
146 | ||
b32b8144 FG |
147 | BOOST_ASIO_HANDLER_CREATION((io_context_.context(), |
148 | *p.p, "resolver", &impl, 0, "async_resolve")); | |
149 | (void)impl; | |
7c673cae FG |
150 | |
151 | try | |
152 | { | |
153 | using namespace Windows::Networking::Sockets; | |
154 | async_manager_.async(DatagramSocket::GetEndpointPairsAsync( | |
155 | winrt_utils::host_name(query.host_name()), | |
156 | winrt_utils::string(query.service_name())), p.p); | |
157 | p.v = p.p = 0; | |
158 | } | |
159 | catch (Platform::Exception^ e) | |
160 | { | |
161 | p.p->ec_ = boost::system::error_code( | |
162 | e->HResult, boost::system::system_category()); | |
b32b8144 | 163 | io_context_.post_immediate_completion(p.p, is_continuation); |
7c673cae FG |
164 | p.v = p.p = 0; |
165 | } | |
166 | } | |
167 | ||
168 | // Resolve an endpoint to a list of entries. | |
b32b8144 | 169 | results_type resolve(implementation_type&, |
7c673cae FG |
170 | const endpoint_type&, boost::system::error_code& ec) |
171 | { | |
172 | ec = boost::asio::error::operation_not_supported; | |
b32b8144 | 173 | return results_type(); |
7c673cae FG |
174 | } |
175 | ||
176 | // Asynchronously resolve an endpoint to a list of entries. | |
177 | template <typename Handler> | |
178 | void async_resolve(implementation_type&, | |
179 | const endpoint_type&, Handler& handler) | |
180 | { | |
181 | boost::system::error_code ec = boost::asio::error::operation_not_supported; | |
b32b8144 FG |
182 | const results_type results; |
183 | io_context_.get_io_context().post( | |
184 | detail::bind_handler(handler, ec, results)); | |
7c673cae FG |
185 | } |
186 | ||
187 | private: | |
b32b8144 | 188 | io_context_impl& io_context_; |
7c673cae FG |
189 | winrt_async_manager& async_manager_; |
190 | }; | |
191 | ||
192 | } // namespace detail | |
193 | } // namespace asio | |
194 | } // namespace boost | |
195 | ||
196 | #include <boost/asio/detail/pop_options.hpp> | |
197 | ||
198 | #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) | |
199 | ||
200 | #endif // BOOST_ASIO_DETAIL_WINRT_RESOLVER_SERVICE_HPP |