1 //
2 // detail/winrt_resolver_service.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 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 
22 #include <boost/asio/ip/basic_resolver_iterator.hpp>
23 #include <boost/asio/ip/basic_resolver_query.hpp>
24 #include <boost/asio/detail/addressof.hpp>
25 #include <boost/asio/detail/bind_handler.hpp>
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>
38 class winrt_resolver_service
39 {
40 public:
41   // The implementation type of the resolver. A cancellation token is used to
42   // indicate to the asynchronous operation that the operation has been
43   // cancelled.
44   typedef socket_ops::shared_cancel_token_type implementation_type;
45 
46   // The endpoint type.
47   typedef typename Protocol::endpoint endpoint_type;
48 
49   // The query type.
50   typedef boost::asio::ip::basic_resolver_query<Protocol> query_type;
51 
52   // The iterator type.
53   typedef boost::asio::ip::basic_resolver_iterator<Protocol> iterator_type;
54 
55   // Constructor.
winrt_resolver_service(boost::asio::io_service & io_service)56   winrt_resolver_service(boost::asio::io_service& io_service)
57     : io_service_(use_service<io_service_impl>(io_service)),
58       async_manager_(use_service<winrt_async_manager>(io_service))
59   {
60   }
61 
62   // Destructor.
~winrt_resolver_service()63   ~winrt_resolver_service()
64   {
65   }
66 
67   // Destroy all user-defined handler objects owned by the service.
shutdown_service()68   void shutdown_service()
69   {
70   }
71 
72   // Perform any fork-related housekeeping.
fork_service(boost::asio::io_service::fork_event)73   void fork_service(boost::asio::io_service::fork_event)
74   {
75   }
76 
77   // Construct a new resolver implementation.
construct(implementation_type &)78   void construct(implementation_type&)
79   {
80   }
81 
82   // Destroy a resolver implementation.
destroy(implementation_type &)83   void destroy(implementation_type&)
84   {
85   }
86 
87   // Cancel pending asynchronous operations.
cancel(implementation_type &)88   void cancel(implementation_type&)
89   {
90   }
91 
92   // Resolve a query to a list of entries.
resolve(implementation_type &,const query_type & query,boost::system::error_code & ec)93   iterator_type resolve(implementation_type&,
94       const query_type& query, boost::system::error_code& ec)
95   {
96     try
97     {
98       using namespace Windows::Networking::Sockets;
99       auto endpoint_pairs = async_manager_.sync(
100           DatagramSocket::GetEndpointPairsAsync(
101             winrt_utils::host_name(query.host_name()),
102             winrt_utils::string(query.service_name())), ec);
103 
104       if (ec)
105         return iterator_type();
106 
107       return iterator_type::create(
108           endpoint_pairs, query.hints(),
109           query.host_name(), query.service_name());
110     }
111     catch (Platform::Exception^ e)
112     {
113       ec = boost::system::error_code(e->HResult,
114           boost::system::system_category());
115       return iterator_type();
116     }
117   }
118 
119   // Asynchronously resolve a query to a list of entries.
120   template <typename Handler>
async_resolve(implementation_type &,const query_type & query,Handler & handler)121   void async_resolve(implementation_type&,
122       const query_type& query, Handler& handler)
123   {
124     bool is_continuation =
125       boost_asio_handler_cont_helpers::is_continuation(handler);
126 
127     // Allocate and construct an operation to wrap the handler.
128     typedef winrt_resolve_op<Protocol, Handler> op;
129     typename op::ptr p = { boost::asio::detail::addressof(handler),
130       boost_asio_handler_alloc_helpers::allocate(
131         sizeof(op), handler), 0 };
132     p.p = new (p.v) op(query, handler);
133 
134     BOOST_ASIO_HANDLER_CREATION((p.p, "resolver", &impl, "async_resolve"));
135 
136     try
137     {
138       using namespace Windows::Networking::Sockets;
139       async_manager_.async(DatagramSocket::GetEndpointPairsAsync(
140             winrt_utils::host_name(query.host_name()),
141             winrt_utils::string(query.service_name())), p.p);
142       p.v = p.p = 0;
143     }
144     catch (Platform::Exception^ e)
145     {
146       p.p->ec_ = boost::system::error_code(
147           e->HResult, boost::system::system_category());
148       io_service_.post_immediate_completion(p.p, is_continuation);
149       p.v = p.p = 0;
150     }
151   }
152 
153   // Resolve an endpoint to a list of entries.
resolve(implementation_type &,const endpoint_type &,boost::system::error_code & ec)154   iterator_type resolve(implementation_type&,
155       const endpoint_type&, boost::system::error_code& ec)
156   {
157     ec = boost::asio::error::operation_not_supported;
158     return iterator_type();
159   }
160 
161   // Asynchronously resolve an endpoint to a list of entries.
162   template <typename Handler>
async_resolve(implementation_type &,const endpoint_type &,Handler & handler)163   void async_resolve(implementation_type&,
164       const endpoint_type&, Handler& handler)
165   {
166     boost::system::error_code ec = boost::asio::error::operation_not_supported;
167     const iterator_type iterator;
168     io_service_.get_io_service().post(
169         detail::bind_handler(handler, ec, iterator));
170   }
171 
172 private:
173   io_service_impl& io_service_;
174   winrt_async_manager& async_manager_;
175 };
176 
177 } // namespace detail
178 } // namespace asio
179 } // namespace boost
180 
181 #include <boost/asio/detail/pop_options.hpp>
182 
183 #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
184 
185 #endif // BOOST_ASIO_DETAIL_WINRT_RESOLVER_SERVICE_HPP
186