Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
6.7KB

  1. //
  2. // detail/winrt_ssocket_service.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 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 ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP
  11. #define 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 "asio/detail/config.hpp"
  16. #if defined(ASIO_WINDOWS_RUNTIME)
  17. #include "asio/error.hpp"
  18. #include "asio/execution_context.hpp"
  19. #include "asio/detail/memory.hpp"
  20. #include "asio/detail/winrt_socket_connect_op.hpp"
  21. #include "asio/detail/winrt_ssocket_service_base.hpp"
  22. #include "asio/detail/winrt_utils.hpp"
  23. #include "asio/detail/push_options.hpp"
  24. namespace asio {
  25. namespace detail {
  26. template <typename Protocol>
  27. class winrt_ssocket_service :
  28. public execution_context_service_base<winrt_ssocket_service<Protocol> >,
  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(execution_context& context)
  52. : execution_context_service_base<winrt_ssocket_service<Protocol> >(context),
  53. winrt_ssocket_service_base(context)
  54. {
  55. }
  56. // Destroy all user-defined handler objects owned by the service.
  57. void shutdown()
  58. {
  59. this->base_shutdown();
  60. }
  61. // Move-construct a new socket implementation.
  62. void move_construct(implementation_type& impl,
  63. implementation_type& other_impl)
  64. {
  65. this->base_move_construct(impl, other_impl);
  66. impl.protocol_ = other_impl.protocol_;
  67. other_impl.protocol_ = endpoint_type().protocol();
  68. }
  69. // Move-assign from another socket implementation.
  70. void move_assign(implementation_type& impl,
  71. winrt_ssocket_service& other_service,
  72. implementation_type& other_impl)
  73. {
  74. this->base_move_assign(impl, other_service, other_impl);
  75. impl.protocol_ = other_impl.protocol_;
  76. other_impl.protocol_ = endpoint_type().protocol();
  77. }
  78. // Move-construct a new socket implementation from another protocol type.
  79. template <typename Protocol1>
  80. void converting_move_construct(implementation_type& impl,
  81. winrt_ssocket_service<Protocol1>&,
  82. typename winrt_ssocket_service<
  83. Protocol1>::implementation_type& other_impl)
  84. {
  85. this->base_move_construct(impl, other_impl);
  86. impl.protocol_ = protocol_type(other_impl.protocol_);
  87. other_impl.protocol_ = typename Protocol1::endpoint().protocol();
  88. }
  89. // Open a new socket implementation.
  90. asio::error_code open(implementation_type& impl,
  91. const protocol_type& protocol, asio::error_code& ec)
  92. {
  93. if (is_open(impl))
  94. {
  95. ec = asio::error::already_open;
  96. return ec;
  97. }
  98. try
  99. {
  100. impl.socket_ = ref new Windows::Networking::Sockets::StreamSocket;
  101. impl.protocol_ = protocol;
  102. ec = asio::error_code();
  103. }
  104. catch (Platform::Exception^ e)
  105. {
  106. ec = asio::error_code(e->HResult,
  107. asio::system_category());
  108. }
  109. return ec;
  110. }
  111. // Assign a native socket to a socket implementation.
  112. asio::error_code assign(implementation_type& impl,
  113. const protocol_type& protocol, const native_handle_type& native_socket,
  114. asio::error_code& ec)
  115. {
  116. if (is_open(impl))
  117. {
  118. ec = asio::error::already_open;
  119. return ec;
  120. }
  121. impl.socket_ = native_socket;
  122. impl.protocol_ = protocol;
  123. ec = asio::error_code();
  124. return ec;
  125. }
  126. // Bind the socket to the specified local endpoint.
  127. asio::error_code bind(implementation_type&,
  128. const endpoint_type&, asio::error_code& ec)
  129. {
  130. ec = asio::error::operation_not_supported;
  131. return ec;
  132. }
  133. // Get the local endpoint.
  134. endpoint_type local_endpoint(const implementation_type& impl,
  135. asio::error_code& ec) const
  136. {
  137. endpoint_type endpoint;
  138. endpoint.resize(do_get_endpoint(impl, true,
  139. endpoint.data(), endpoint.size(), ec));
  140. return endpoint;
  141. }
  142. // Get the remote endpoint.
  143. endpoint_type remote_endpoint(const implementation_type& impl,
  144. asio::error_code& ec) const
  145. {
  146. endpoint_type endpoint;
  147. endpoint.resize(do_get_endpoint(impl, false,
  148. endpoint.data(), endpoint.size(), ec));
  149. return endpoint;
  150. }
  151. // Set a socket option.
  152. template <typename Option>
  153. asio::error_code set_option(implementation_type& impl,
  154. const Option& option, asio::error_code& ec)
  155. {
  156. return do_set_option(impl, option.level(impl.protocol_),
  157. option.name(impl.protocol_), option.data(impl.protocol_),
  158. option.size(impl.protocol_), ec);
  159. }
  160. // Get a socket option.
  161. template <typename Option>
  162. asio::error_code get_option(const implementation_type& impl,
  163. Option& option, asio::error_code& ec) const
  164. {
  165. std::size_t size = option.size(impl.protocol_);
  166. do_get_option(impl, option.level(impl.protocol_),
  167. option.name(impl.protocol_),
  168. option.data(impl.protocol_), &size, ec);
  169. if (!ec)
  170. option.resize(impl.protocol_, size);
  171. return ec;
  172. }
  173. // Connect the socket to the specified endpoint.
  174. asio::error_code connect(implementation_type& impl,
  175. const endpoint_type& peer_endpoint, asio::error_code& ec)
  176. {
  177. return do_connect(impl, peer_endpoint.data(), ec);
  178. }
  179. // Start an asynchronous connect.
  180. template <typename Handler, typename IoExecutor>
  181. void async_connect(implementation_type& impl,
  182. const endpoint_type& peer_endpoint,
  183. Handler& handler, const IoExecutor& io_ex)
  184. {
  185. bool is_continuation =
  186. asio_handler_cont_helpers::is_continuation(handler);
  187. // Allocate and construct an operation to wrap the handler.
  188. typedef winrt_socket_connect_op<Handler, IoExecutor> op;
  189. typename op::ptr p = { asio::detail::addressof(handler),
  190. op::ptr::allocate(handler), 0 };
  191. p.p = new (p.v) op(handler, io_ex);
  192. ASIO_HANDLER_CREATION((scheduler_.context(),
  193. *p.p, "socket", &impl, 0, "async_connect"));
  194. start_connect_op(impl, peer_endpoint.data(), p.p, is_continuation);
  195. p.v = p.p = 0;
  196. }
  197. };
  198. } // namespace detail
  199. } // namespace asio
  200. #include "asio/detail/pop_options.hpp"
  201. #endif // defined(ASIO_WINDOWS_RUNTIME)
  202. #endif // ASIO_DETAIL_WINRT_SSOCKET_SERVICE_HPP