winrt_ssocket_service.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. //
  2. // detail/winrt_ssocket_service.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2013 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. #ifndef BOOST_ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP
  11. #define BOOST_ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
  17. #include <boost/asio/error.hpp>
  18. #include <boost/asio/io_service.hpp>
  19. #include <boost/asio/detail/addressof.hpp>
  20. #include <boost/asio/detail/winrt_socket_connect_op.hpp>
  21. #include <boost/asio/detail/winrt_ssocket_service_base.hpp>
  22. #include <boost/asio/detail/winrt_utils.hpp>
  23. #include <boost/asio/detail/push_options.hpp>
  24. namespace boost {
  25. namespace asio {
  26. namespace detail {
  27. template <typename Protocol>
  28. class winrt_ssocket_service :
  29. public winrt_ssocket_service_base
  30. {
  31. public:
  32. // The protocol type.
  33. typedef Protocol protocol_type;
  34. // The endpoint type.
  35. typedef typename Protocol::endpoint endpoint_type;
  36. // The native type of a socket.
  37. typedef Windows::Networking::Sockets::StreamSocket^ native_handle_type;
  38. // The implementation type of the socket.
  39. struct implementation_type : base_implementation_type
  40. {
  41. // Default constructor.
  42. implementation_type()
  43. : base_implementation_type(),
  44. protocol_(endpoint_type().protocol())
  45. {
  46. }
  47. // The protocol associated with the socket.
  48. protocol_type protocol_;
  49. };
  50. // Constructor.
  51. winrt_ssocket_service(boost::asio::io_service& io_service)
  52. : winrt_ssocket_service_base(io_service)
  53. {
  54. }
  55. // Move-construct a new socket implementation.
  56. void move_construct(implementation_type& impl,
  57. implementation_type& other_impl)
  58. {
  59. this->base_move_construct(impl, other_impl);
  60. impl.protocol_ = other_impl.protocol_;
  61. other_impl.protocol_ = endpoint_type().protocol();
  62. }
  63. // Move-assign from another socket implementation.
  64. void move_assign(implementation_type& impl,
  65. winrt_ssocket_service& other_service,
  66. implementation_type& other_impl)
  67. {
  68. this->base_move_assign(impl, other_service, other_impl);
  69. impl.protocol_ = other_impl.protocol_;
  70. other_impl.protocol_ = endpoint_type().protocol();
  71. }
  72. // Move-construct a new socket implementation from another protocol type.
  73. template <typename Protocol1>
  74. void converting_move_construct(implementation_type& impl,
  75. typename winrt_ssocket_service<
  76. Protocol1>::implementation_type& other_impl)
  77. {
  78. this->base_move_construct(impl, other_impl);
  79. impl.protocol_ = protocol_type(other_impl.protocol_);
  80. other_impl.protocol_ = typename Protocol1::endpoint().protocol();
  81. }
  82. // Open a new socket implementation.
  83. boost::system::error_code open(implementation_type& impl,
  84. const protocol_type& protocol, boost::system::error_code& ec)
  85. {
  86. if (is_open(impl))
  87. {
  88. ec = boost::asio::error::already_open;
  89. return ec;
  90. }
  91. try
  92. {
  93. impl.socket_ = ref new Windows::Networking::Sockets::StreamSocket;
  94. impl.protocol_ = protocol;
  95. ec = boost::system::error_code();
  96. }
  97. catch (Platform::Exception^ e)
  98. {
  99. ec = boost::system::error_code(e->HResult,
  100. boost::system::system_category());
  101. }
  102. return ec;
  103. }
  104. // Assign a native socket to a socket implementation.
  105. boost::system::error_code assign(implementation_type& impl,
  106. const protocol_type& protocol, const native_handle_type& native_socket,
  107. boost::system::error_code& ec)
  108. {
  109. if (is_open(impl))
  110. {
  111. ec = boost::asio::error::already_open;
  112. return ec;
  113. }
  114. impl.socket_ = native_socket;
  115. impl.protocol_ = protocol;
  116. ec = boost::system::error_code();
  117. return ec;
  118. }
  119. // Bind the socket to the specified local endpoint.
  120. boost::system::error_code bind(implementation_type&,
  121. const endpoint_type&, boost::system::error_code& ec)
  122. {
  123. ec = boost::asio::error::operation_not_supported;
  124. return ec;
  125. }
  126. // Get the local endpoint.
  127. endpoint_type local_endpoint(const implementation_type& impl,
  128. boost::system::error_code& ec) const
  129. {
  130. endpoint_type endpoint;
  131. endpoint.resize(do_get_endpoint(impl, true,
  132. endpoint.data(), endpoint.size(), ec));
  133. return endpoint;
  134. }
  135. // Get the remote endpoint.
  136. endpoint_type remote_endpoint(const implementation_type& impl,
  137. boost::system::error_code& ec) const
  138. {
  139. endpoint_type endpoint;
  140. endpoint.resize(do_get_endpoint(impl, false,
  141. endpoint.data(), endpoint.size(), ec));
  142. return endpoint;
  143. }
  144. // Set a socket option.
  145. template <typename Option>
  146. boost::system::error_code set_option(implementation_type& impl,
  147. const Option& option, boost::system::error_code& ec)
  148. {
  149. return do_set_option(impl, option.level(impl.protocol_),
  150. option.name(impl.protocol_), option.data(impl.protocol_),
  151. option.size(impl.protocol_), ec);
  152. }
  153. // Get a socket option.
  154. template <typename Option>
  155. boost::system::error_code get_option(const implementation_type& impl,
  156. Option& option, boost::system::error_code& ec) const
  157. {
  158. std::size_t size = option.size(impl.protocol_);
  159. do_get_option(impl, option.level(impl.protocol_),
  160. option.name(impl.protocol_),
  161. option.data(impl.protocol_), &size, ec);
  162. if (!ec)
  163. option.resize(impl.protocol_, size);
  164. return ec;
  165. }
  166. // Connect the socket to the specified endpoint.
  167. boost::system::error_code connect(implementation_type& impl,
  168. const endpoint_type& peer_endpoint, boost::system::error_code& ec)
  169. {
  170. return do_connect(impl, peer_endpoint.data(), ec);
  171. }
  172. // Start an asynchronous connect.
  173. template <typename Handler>
  174. void async_connect(implementation_type& impl,
  175. const endpoint_type& peer_endpoint, Handler& handler)
  176. {
  177. bool is_continuation =
  178. boost_asio_handler_cont_helpers::is_continuation(handler);
  179. // Allocate and construct an operation to wrap the handler.
  180. typedef winrt_socket_connect_op<Handler> op;
  181. typename op::ptr p = { boost::asio::detail::addressof(handler),
  182. boost_asio_handler_alloc_helpers::allocate(
  183. sizeof(op), handler), 0 };
  184. p.p = new (p.v) op(handler);
  185. BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect"));
  186. start_connect_op(impl, peer_endpoint.data(), p.p, is_continuation);
  187. p.v = p.p = 0;
  188. }
  189. };
  190. } // namespace detail
  191. } // namespace asio
  192. } // namespace boost
  193. #include <boost/asio/detail/pop_options.hpp>
  194. #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
  195. #endif // BOOST_ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP