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.

412 lines
15KB

  1. //
  2. // windows/basic_stream_handle.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_WINDOWS_BASIC_STREAM_HANDLE_HPP
  11. #define ASIO_WINDOWS_BASIC_STREAM_HANDLE_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. #include "asio/windows/basic_overlapped_handle.hpp"
  17. #if defined(ASIO_HAS_WINDOWS_STREAM_HANDLE) \
  18. || defined(GENERATING_DOCUMENTATION)
  19. #include "asio/detail/push_options.hpp"
  20. namespace asio {
  21. namespace windows {
  22. /// Provides stream-oriented handle functionality.
  23. /**
  24. * The windows::basic_stream_handle class provides asynchronous and blocking
  25. * stream-oriented handle functionality.
  26. *
  27. * @par Thread Safety
  28. * @e Distinct @e objects: Safe.@n
  29. * @e Shared @e objects: Unsafe.
  30. *
  31. * @par Concepts:
  32. * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
  33. */
  34. template <typename Executor = executor>
  35. class basic_stream_handle
  36. : public basic_overlapped_handle<Executor>
  37. {
  38. public:
  39. /// The type of the executor associated with the object.
  40. typedef Executor executor_type;
  41. /// The native representation of a handle.
  42. #if defined(GENERATING_DOCUMENTATION)
  43. typedef implementation_defined native_handle_type;
  44. #else
  45. typedef asio::detail::win_iocp_handle_service::native_handle_type
  46. native_handle_type;
  47. #endif
  48. /// Construct a stream handle without opening it.
  49. /**
  50. * This constructor creates a stream handle without opening it.
  51. *
  52. * @param ex The I/O executor that the stream handle will use, by default, to
  53. * dispatch handlers for any asynchronous operations performed on the stream
  54. * handle.
  55. */
  56. explicit basic_stream_handle(const executor_type& ex)
  57. : basic_overlapped_handle<Executor>(ex)
  58. {
  59. }
  60. /// Construct a stream handle without opening it.
  61. /**
  62. * This constructor creates a stream handle without opening it. The handle
  63. * needs to be opened or assigned before data can be sent or received on it.
  64. *
  65. * @param context An execution context which provides the I/O executor that
  66. * the stream handle will use, by default, to dispatch handlers for any
  67. * asynchronous operations performed on the stream handle.
  68. */
  69. template <typename ExecutionContext>
  70. explicit basic_stream_handle(ExecutionContext& context,
  71. typename enable_if<
  72. is_convertible<ExecutionContext&, execution_context&>::value,
  73. basic_stream_handle
  74. >::type* = 0)
  75. : basic_overlapped_handle<Executor>(context)
  76. {
  77. }
  78. /// Construct a stream handle on an existing native handle.
  79. /**
  80. * This constructor creates a stream handle object to hold an existing native
  81. * handle.
  82. *
  83. * @param ex The I/O executor that the stream handle will use, by default, to
  84. * dispatch handlers for any asynchronous operations performed on the stream
  85. * handle.
  86. *
  87. * @param handle The new underlying handle implementation.
  88. *
  89. * @throws asio::system_error Thrown on failure.
  90. */
  91. basic_stream_handle(const executor_type& ex, const native_handle_type& handle)
  92. : basic_overlapped_handle<Executor>(ex, handle)
  93. {
  94. }
  95. /// Construct a stream handle on an existing native handle.
  96. /**
  97. * This constructor creates a stream handle object to hold an existing native
  98. * handle.
  99. *
  100. * @param context An execution context which provides the I/O executor that
  101. * the stream handle will use, by default, to dispatch handlers for any
  102. * asynchronous operations performed on the stream handle.
  103. *
  104. * @param handle The new underlying handle implementation.
  105. *
  106. * @throws asio::system_error Thrown on failure.
  107. */
  108. template <typename ExecutionContext>
  109. basic_stream_handle(ExecutionContext& context,
  110. const native_handle_type& handle,
  111. typename enable_if<
  112. is_convertible<ExecutionContext&, execution_context&>::value
  113. >::type* = 0)
  114. : basic_overlapped_handle<Executor>(context, handle)
  115. {
  116. }
  117. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  118. /// Move-construct a stream handle from another.
  119. /**
  120. * This constructor moves a stream handle from one object to another.
  121. *
  122. * @param other The other stream handle object from which the move
  123. * will occur.
  124. *
  125. * @note Following the move, the moved-from object is in the same state as if
  126. * constructed using the @c basic_stream_handle(const executor_type&)
  127. * constructor.
  128. */
  129. basic_stream_handle(basic_stream_handle&& other)
  130. : basic_overlapped_handle<Executor>(std::move(other))
  131. {
  132. }
  133. /// Move-assign a stream handle from another.
  134. /**
  135. * This assignment operator moves a stream handle from one object to
  136. * another.
  137. *
  138. * @param other The other stream handle object from which the move will occur.
  139. *
  140. * @note Following the move, the moved-from object is in the same state as if
  141. * constructed using the @c basic_stream_handle(const executor_type&)
  142. * constructor.
  143. */
  144. basic_stream_handle& operator=(basic_stream_handle&& other)
  145. {
  146. basic_overlapped_handle<Executor>::operator=(std::move(other));
  147. return *this;
  148. }
  149. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  150. /// Write some data to the handle.
  151. /**
  152. * This function is used to write data to the stream handle. The function call
  153. * will block until one or more bytes of the data has been written
  154. * successfully, or until an error occurs.
  155. *
  156. * @param buffers One or more data buffers to be written to the handle.
  157. *
  158. * @returns The number of bytes written.
  159. *
  160. * @throws asio::system_error Thrown on failure. An error code of
  161. * asio::error::eof indicates that the connection was closed by the
  162. * peer.
  163. *
  164. * @note The write_some operation may not transmit all of the data to the
  165. * peer. Consider using the @ref write function if you need to ensure that
  166. * all data is written before the blocking operation completes.
  167. *
  168. * @par Example
  169. * To write a single data buffer use the @ref buffer function as follows:
  170. * @code
  171. * handle.write_some(asio::buffer(data, size));
  172. * @endcode
  173. * See the @ref buffer documentation for information on writing multiple
  174. * buffers in one go, and how to use it with arrays, boost::array or
  175. * std::vector.
  176. */
  177. template <typename ConstBufferSequence>
  178. std::size_t write_some(const ConstBufferSequence& buffers)
  179. {
  180. asio::error_code ec;
  181. std::size_t s = this->impl_.get_service().write_some(
  182. this->impl_.get_implementation(), buffers, ec);
  183. asio::detail::throw_error(ec, "write_some");
  184. return s;
  185. }
  186. /// Write some data to the handle.
  187. /**
  188. * This function is used to write data to the stream handle. The function call
  189. * will block until one or more bytes of the data has been written
  190. * successfully, or until an error occurs.
  191. *
  192. * @param buffers One or more data buffers to be written to the handle.
  193. *
  194. * @param ec Set to indicate what error occurred, if any.
  195. *
  196. * @returns The number of bytes written. Returns 0 if an error occurred.
  197. *
  198. * @note The write_some operation may not transmit all of the data to the
  199. * peer. Consider using the @ref write function if you need to ensure that
  200. * all data is written before the blocking operation completes.
  201. */
  202. template <typename ConstBufferSequence>
  203. std::size_t write_some(const ConstBufferSequence& buffers,
  204. asio::error_code& ec)
  205. {
  206. return this->impl_.get_service().write_some(
  207. this->impl_.get_implementation(), buffers, ec);
  208. }
  209. /// Start an asynchronous write.
  210. /**
  211. * This function is used to asynchronously write data to the stream handle.
  212. * The function call always returns immediately.
  213. *
  214. * @param buffers One or more data buffers to be written to the handle.
  215. * Although the buffers object may be copied as necessary, ownership of the
  216. * underlying memory blocks is retained by the caller, which must guarantee
  217. * that they remain valid until the handler is called.
  218. *
  219. * @param handler The handler to be called when the write operation completes.
  220. * Copies will be made of the handler as required. The function signature of
  221. * the handler must be:
  222. * @code void handler(
  223. * const asio::error_code& error, // Result of operation.
  224. * std::size_t bytes_transferred // Number of bytes written.
  225. * ); @endcode
  226. * Regardless of whether the asynchronous operation completes immediately or
  227. * not, the handler will not be invoked from within this function. On
  228. * immediate completion, invocation of the handler will be performed in a
  229. * manner equivalent to using asio::post().
  230. *
  231. * @note The write operation may not transmit all of the data to the peer.
  232. * Consider using the @ref async_write function if you need to ensure that all
  233. * data is written before the asynchronous operation completes.
  234. *
  235. * @par Example
  236. * To write a single data buffer use the @ref buffer function as follows:
  237. * @code
  238. * handle.async_write_some(asio::buffer(data, size), handler);
  239. * @endcode
  240. * See the @ref buffer documentation for information on writing multiple
  241. * buffers in one go, and how to use it with arrays, boost::array or
  242. * std::vector.
  243. */
  244. template <typename ConstBufferSequence, typename WriteHandler>
  245. ASIO_INITFN_RESULT_TYPE(WriteHandler,
  246. void (asio::error_code, std::size_t))
  247. async_write_some(const ConstBufferSequence& buffers,
  248. ASIO_MOVE_ARG(WriteHandler) 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 WriteHandler.
  252. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  253. asio::async_completion<WriteHandler,
  254. void (asio::error_code, std::size_t)> init(handler);
  255. this->impl_.get_service().async_write_some(
  256. this->impl_.get_implementation(),
  257. buffers, init.completion_handler,
  258. this->impl_.get_implementation_executor());
  259. return init.result.get();
  260. }
  261. /// Read some data from the handle.
  262. /**
  263. * This function is used to read data from the stream handle. The function
  264. * call will block until one or more bytes of data has been read successfully,
  265. * or until an error occurs.
  266. *
  267. * @param buffers One or more buffers into which the data will be read.
  268. *
  269. * @returns The number of bytes read.
  270. *
  271. * @throws asio::system_error Thrown on failure. An error code of
  272. * asio::error::eof indicates that the connection was closed by the
  273. * peer.
  274. *
  275. * @note The read_some operation may not read all of the requested number of
  276. * bytes. Consider using the @ref read function if you need to ensure that
  277. * the requested amount of data is read before the blocking operation
  278. * completes.
  279. *
  280. * @par Example
  281. * To read into a single data buffer use the @ref buffer function as follows:
  282. * @code
  283. * handle.read_some(asio::buffer(data, size));
  284. * @endcode
  285. * See the @ref buffer documentation for information on reading into multiple
  286. * buffers in one go, and how to use it with arrays, boost::array or
  287. * std::vector.
  288. */
  289. template <typename MutableBufferSequence>
  290. std::size_t read_some(const MutableBufferSequence& buffers)
  291. {
  292. asio::error_code ec;
  293. std::size_t s = this->impl_.get_service().read_some(
  294. this->impl_.get_implementation(), buffers, ec);
  295. asio::detail::throw_error(ec, "read_some");
  296. return s;
  297. }
  298. /// Read some data from the handle.
  299. /**
  300. * This function is used to read data from the stream handle. The function
  301. * call will block until one or more bytes of data has been read successfully,
  302. * or until an error occurs.
  303. *
  304. * @param buffers One or more buffers into which the data will be read.
  305. *
  306. * @param ec Set to indicate what error occurred, if any.
  307. *
  308. * @returns The number of bytes read. Returns 0 if an error occurred.
  309. *
  310. * @note The read_some operation may not read all of the requested number of
  311. * bytes. Consider using the @ref read function if you need to ensure that
  312. * the requested amount of data is read before the blocking operation
  313. * completes.
  314. */
  315. template <typename MutableBufferSequence>
  316. std::size_t read_some(const MutableBufferSequence& buffers,
  317. asio::error_code& ec)
  318. {
  319. return this->impl_.get_service().read_some(
  320. this->impl_.get_implementation(), buffers, ec);
  321. }
  322. /// Start an asynchronous read.
  323. /**
  324. * This function is used to asynchronously read data from the stream handle.
  325. * The function call always returns immediately.
  326. *
  327. * @param buffers One or more buffers into which the data will be read.
  328. * Although the buffers object may be copied as necessary, ownership of the
  329. * underlying memory blocks is retained by the caller, which must guarantee
  330. * that they remain valid until the handler is called.
  331. *
  332. * @param handler The handler to be called when the read operation completes.
  333. * Copies will be made of the handler as required. The function signature of
  334. * the handler must be:
  335. * @code void handler(
  336. * const asio::error_code& error, // Result of operation.
  337. * std::size_t bytes_transferred // Number of bytes read.
  338. * ); @endcode
  339. * Regardless of whether the asynchronous operation completes immediately or
  340. * not, the handler will not be invoked from within this function. On
  341. * immediate completion, invocation of the handler will be performed in a
  342. * manner equivalent to using asio::post().
  343. *
  344. * @note The read operation may not read all of the requested number of bytes.
  345. * Consider using the @ref async_read function if you need to ensure that the
  346. * requested amount of data is read before the asynchronous operation
  347. * completes.
  348. *
  349. * @par Example
  350. * To read into a single data buffer use the @ref buffer function as follows:
  351. * @code
  352. * handle.async_read_some(asio::buffer(data, size), handler);
  353. * @endcode
  354. * See the @ref buffer documentation for information on reading into multiple
  355. * buffers in one go, and how to use it with arrays, boost::array or
  356. * std::vector.
  357. */
  358. template <typename MutableBufferSequence, typename ReadHandler>
  359. ASIO_INITFN_RESULT_TYPE(ReadHandler,
  360. void (asio::error_code, std::size_t))
  361. async_read_some(const MutableBufferSequence& buffers,
  362. ASIO_MOVE_ARG(ReadHandler) handler)
  363. {
  364. // If you get an error on the following line it means that your handler does
  365. // not meet the documented type requirements for a ReadHandler.
  366. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  367. asio::async_completion<ReadHandler,
  368. void (asio::error_code, std::size_t)> init(handler);
  369. this->impl_.get_service().async_read_some(
  370. this->impl_.get_implementation(),
  371. buffers, init.completion_handler,
  372. this->impl_.get_implementation_executor());
  373. return init.result.get();
  374. }
  375. };
  376. } // namespace windows
  377. } // namespace asio
  378. #include "asio/detail/pop_options.hpp"
  379. #endif // defined(ASIO_HAS_WINDOWS_STREAM_HANDLE)
  380. // || defined(GENERATING_DOCUMENTATION)
  381. #endif // ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP