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.

basic_serial_port.hpp 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. //
  2. // basic_serial_port.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
  7. //
  8. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  9. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. #ifndef ASIO_BASIC_SERIAL_PORT_HPP
  12. #define ASIO_BASIC_SERIAL_PORT_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  16. #include "asio/detail/config.hpp"
  17. #if defined(ASIO_HAS_SERIAL_PORT) \
  18. || defined(GENERATING_DOCUMENTATION)
  19. #include <string>
  20. #include "asio/async_result.hpp"
  21. #include "asio/detail/handler_type_requirements.hpp"
  22. #include "asio/detail/io_object_impl.hpp"
  23. #include "asio/detail/non_const_lvalue.hpp"
  24. #include "asio/detail/throw_error.hpp"
  25. #include "asio/detail/type_traits.hpp"
  26. #include "asio/error.hpp"
  27. #include "asio/execution_context.hpp"
  28. #include "asio/executor.hpp"
  29. #include "asio/serial_port_base.hpp"
  30. #if defined(ASIO_HAS_IOCP)
  31. # include "asio/detail/win_iocp_serial_port_service.hpp"
  32. #else
  33. # include "asio/detail/reactive_serial_port_service.hpp"
  34. #endif
  35. #if defined(ASIO_HAS_MOVE)
  36. # include <utility>
  37. #endif // defined(ASIO_HAS_MOVE)
  38. #include "asio/detail/push_options.hpp"
  39. namespace asio {
  40. /// Provides serial port functionality.
  41. /**
  42. * The basic_serial_port class provides a wrapper over serial port
  43. * functionality.
  44. *
  45. * @par Thread Safety
  46. * @e Distinct @e objects: Safe.@n
  47. * @e Shared @e objects: Unsafe.
  48. */
  49. template <typename Executor = executor>
  50. class basic_serial_port
  51. : public serial_port_base
  52. {
  53. public:
  54. /// The type of the executor associated with the object.
  55. typedef Executor executor_type;
  56. /// The native representation of a serial port.
  57. #if defined(GENERATING_DOCUMENTATION)
  58. typedef implementation_defined native_handle_type;
  59. #elif defined(ASIO_HAS_IOCP)
  60. typedef detail::win_iocp_serial_port_service::native_handle_type
  61. native_handle_type;
  62. #else
  63. typedef detail::reactive_serial_port_service::native_handle_type
  64. native_handle_type;
  65. #endif
  66. /// A basic_basic_serial_port is always the lowest layer.
  67. typedef basic_serial_port lowest_layer_type;
  68. /// Construct a basic_serial_port without opening it.
  69. /**
  70. * This constructor creates a serial port without opening it.
  71. *
  72. * @param ex The I/O executor that the serial port will use, by default, to
  73. * dispatch handlers for any asynchronous operations performed on the
  74. * serial port.
  75. */
  76. explicit basic_serial_port(const executor_type& ex)
  77. : impl_(ex)
  78. {
  79. }
  80. /// Construct a basic_serial_port without opening it.
  81. /**
  82. * This constructor creates a serial port without opening it.
  83. *
  84. * @param context An execution context which provides the I/O executor that
  85. * the serial port will use, by default, to dispatch handlers for any
  86. * asynchronous operations performed on the serial port.
  87. */
  88. template <typename ExecutionContext>
  89. explicit basic_serial_port(ExecutionContext& context,
  90. typename enable_if<
  91. is_convertible<ExecutionContext&, execution_context&>::value,
  92. basic_serial_port
  93. >::type* = 0)
  94. : impl_(context)
  95. {
  96. }
  97. /// Construct and open a basic_serial_port.
  98. /**
  99. * This constructor creates and opens a serial port for the specified device
  100. * name.
  101. *
  102. * @param ex The I/O executor that the serial port will use, by default, to
  103. * dispatch handlers for any asynchronous operations performed on the
  104. * serial port.
  105. *
  106. * @param device The platform-specific device name for this serial
  107. * port.
  108. */
  109. basic_serial_port(const executor_type& ex, const char* device)
  110. : impl_(ex)
  111. {
  112. asio::error_code ec;
  113. impl_.get_service().open(impl_.get_implementation(), device, ec);
  114. asio::detail::throw_error(ec, "open");
  115. }
  116. /// Construct and open a basic_serial_port.
  117. /**
  118. * This constructor creates and opens a serial port for the specified device
  119. * name.
  120. *
  121. * @param context An execution context which provides the I/O executor that
  122. * the serial port will use, by default, to dispatch handlers for any
  123. * asynchronous operations performed on the serial port.
  124. *
  125. * @param device The platform-specific device name for this serial
  126. * port.
  127. */
  128. template <typename ExecutionContext>
  129. basic_serial_port(ExecutionContext& context, const char* device,
  130. typename enable_if<
  131. is_convertible<ExecutionContext&, execution_context&>::value
  132. >::type* = 0)
  133. : impl_(context)
  134. {
  135. asio::error_code ec;
  136. impl_.get_service().open(impl_.get_implementation(), device, ec);
  137. asio::detail::throw_error(ec, "open");
  138. }
  139. /// Construct and open a basic_serial_port.
  140. /**
  141. * This constructor creates and opens a serial port for the specified device
  142. * name.
  143. *
  144. * @param ex The I/O executor that the serial port will use, by default, to
  145. * dispatch handlers for any asynchronous operations performed on the
  146. * serial port.
  147. *
  148. * @param device The platform-specific device name for this serial
  149. * port.
  150. */
  151. basic_serial_port(const executor_type& ex, const std::string& device)
  152. : impl_(ex)
  153. {
  154. asio::error_code ec;
  155. impl_.get_service().open(impl_.get_implementation(), device, ec);
  156. asio::detail::throw_error(ec, "open");
  157. }
  158. /// Construct and open a basic_serial_port.
  159. /**
  160. * This constructor creates and opens a serial port for the specified device
  161. * name.
  162. *
  163. * @param context An execution context which provides the I/O executor that
  164. * the serial port will use, by default, to dispatch handlers for any
  165. * asynchronous operations performed on the serial port.
  166. *
  167. * @param device The platform-specific device name for this serial
  168. * port.
  169. */
  170. template <typename ExecutionContext>
  171. basic_serial_port(ExecutionContext& context, const std::string& device,
  172. typename enable_if<
  173. is_convertible<ExecutionContext&, execution_context&>::value
  174. >::type* = 0)
  175. : impl_(context)
  176. {
  177. asio::error_code ec;
  178. impl_.get_service().open(impl_.get_implementation(), device, ec);
  179. asio::detail::throw_error(ec, "open");
  180. }
  181. /// Construct a basic_serial_port on an existing native serial port.
  182. /**
  183. * This constructor creates a serial port object to hold an existing native
  184. * serial port.
  185. *
  186. * @param ex The I/O executor that the serial port will use, by default, to
  187. * dispatch handlers for any asynchronous operations performed on the
  188. * serial port.
  189. *
  190. * @param native_serial_port A native serial port.
  191. *
  192. * @throws asio::system_error Thrown on failure.
  193. */
  194. basic_serial_port(const executor_type& ex,
  195. const native_handle_type& native_serial_port)
  196. : impl_(ex)
  197. {
  198. asio::error_code ec;
  199. impl_.get_service().assign(impl_.get_implementation(),
  200. native_serial_port, ec);
  201. asio::detail::throw_error(ec, "assign");
  202. }
  203. /// Construct a basic_serial_port on an existing native serial port.
  204. /**
  205. * This constructor creates a serial port object to hold an existing native
  206. * serial port.
  207. *
  208. * @param context An execution context which provides the I/O executor that
  209. * the serial port will use, by default, to dispatch handlers for any
  210. * asynchronous operations performed on the serial port.
  211. *
  212. * @param native_serial_port A native serial port.
  213. *
  214. * @throws asio::system_error Thrown on failure.
  215. */
  216. template <typename ExecutionContext>
  217. basic_serial_port(ExecutionContext& context,
  218. const native_handle_type& native_serial_port,
  219. typename enable_if<
  220. is_convertible<ExecutionContext&, execution_context&>::value
  221. >::type* = 0)
  222. : impl_(context)
  223. {
  224. asio::error_code ec;
  225. impl_.get_service().assign(impl_.get_implementation(),
  226. native_serial_port, ec);
  227. asio::detail::throw_error(ec, "assign");
  228. }
  229. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  230. /// Move-construct a basic_serial_port from another.
  231. /**
  232. * This constructor moves a serial port from one object to another.
  233. *
  234. * @param other The other basic_serial_port object from which the move will
  235. * occur.
  236. *
  237. * @note Following the move, the moved-from object is in the same state as if
  238. * constructed using the @c basic_serial_port(const executor_type&)
  239. * constructor.
  240. */
  241. basic_serial_port(basic_serial_port&& other)
  242. : impl_(std::move(other.impl_))
  243. {
  244. }
  245. /// Move-assign a basic_serial_port from another.
  246. /**
  247. * This assignment operator moves a serial port from one object to another.
  248. *
  249. * @param other The other basic_serial_port object from which the move will
  250. * occur.
  251. *
  252. * @note Following the move, the moved-from object is in the same state as if
  253. * constructed using the @c basic_serial_port(const executor_type&)
  254. * constructor.
  255. */
  256. basic_serial_port& operator=(basic_serial_port&& other)
  257. {
  258. impl_ = std::move(other.impl_);
  259. return *this;
  260. }
  261. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  262. /// Destroys the serial port.
  263. /**
  264. * This function destroys the serial port, cancelling any outstanding
  265. * asynchronous wait operations associated with the serial port as if by
  266. * calling @c cancel.
  267. */
  268. ~basic_serial_port()
  269. {
  270. }
  271. /// Get the executor associated with the object.
  272. executor_type get_executor() ASIO_NOEXCEPT
  273. {
  274. return impl_.get_executor();
  275. }
  276. /// Get a reference to the lowest layer.
  277. /**
  278. * This function returns a reference to the lowest layer in a stack of
  279. * layers. Since a basic_serial_port cannot contain any further layers, it
  280. * simply returns a reference to itself.
  281. *
  282. * @return A reference to the lowest layer in the stack of layers. Ownership
  283. * is not transferred to the caller.
  284. */
  285. lowest_layer_type& lowest_layer()
  286. {
  287. return *this;
  288. }
  289. /// Get a const reference to the lowest layer.
  290. /**
  291. * This function returns a const reference to the lowest layer in a stack of
  292. * layers. Since a basic_serial_port cannot contain any further layers, it
  293. * simply returns a reference to itself.
  294. *
  295. * @return A const reference to the lowest layer in the stack of layers.
  296. * Ownership is not transferred to the caller.
  297. */
  298. const lowest_layer_type& lowest_layer() const
  299. {
  300. return *this;
  301. }
  302. /// Open the serial port using the specified device name.
  303. /**
  304. * This function opens the serial port for the specified device name.
  305. *
  306. * @param device The platform-specific device name.
  307. *
  308. * @throws asio::system_error Thrown on failure.
  309. */
  310. void open(const std::string& device)
  311. {
  312. asio::error_code ec;
  313. impl_.get_service().open(impl_.get_implementation(), device, ec);
  314. asio::detail::throw_error(ec, "open");
  315. }
  316. /// Open the serial port using the specified device name.
  317. /**
  318. * This function opens the serial port using the given platform-specific
  319. * device name.
  320. *
  321. * @param device The platform-specific device name.
  322. *
  323. * @param ec Set the indicate what error occurred, if any.
  324. */
  325. ASIO_SYNC_OP_VOID open(const std::string& device,
  326. asio::error_code& ec)
  327. {
  328. impl_.get_service().open(impl_.get_implementation(), device, ec);
  329. ASIO_SYNC_OP_VOID_RETURN(ec);
  330. }
  331. /// Assign an existing native serial port to the serial port.
  332. /*
  333. * This function opens the serial port to hold an existing native serial port.
  334. *
  335. * @param native_serial_port A native serial port.
  336. *
  337. * @throws asio::system_error Thrown on failure.
  338. */
  339. void assign(const native_handle_type& native_serial_port)
  340. {
  341. asio::error_code ec;
  342. impl_.get_service().assign(impl_.get_implementation(),
  343. native_serial_port, ec);
  344. asio::detail::throw_error(ec, "assign");
  345. }
  346. /// Assign an existing native serial port to the serial port.
  347. /*
  348. * This function opens the serial port to hold an existing native serial port.
  349. *
  350. * @param native_serial_port A native serial port.
  351. *
  352. * @param ec Set to indicate what error occurred, if any.
  353. */
  354. ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port,
  355. asio::error_code& ec)
  356. {
  357. impl_.get_service().assign(impl_.get_implementation(),
  358. native_serial_port, ec);
  359. ASIO_SYNC_OP_VOID_RETURN(ec);
  360. }
  361. /// Determine whether the serial port is open.
  362. bool is_open() const
  363. {
  364. return impl_.get_service().is_open(impl_.get_implementation());
  365. }
  366. /// Close the serial port.
  367. /**
  368. * This function is used to close the serial port. Any asynchronous read or
  369. * write operations will be cancelled immediately, and will complete with the
  370. * asio::error::operation_aborted error.
  371. *
  372. * @throws asio::system_error Thrown on failure.
  373. */
  374. void close()
  375. {
  376. asio::error_code ec;
  377. impl_.get_service().close(impl_.get_implementation(), ec);
  378. asio::detail::throw_error(ec, "close");
  379. }
  380. /// Close the serial port.
  381. /**
  382. * This function is used to close the serial port. Any asynchronous read or
  383. * write operations will be cancelled immediately, and will complete with the
  384. * asio::error::operation_aborted error.
  385. *
  386. * @param ec Set to indicate what error occurred, if any.
  387. */
  388. ASIO_SYNC_OP_VOID close(asio::error_code& ec)
  389. {
  390. impl_.get_service().close(impl_.get_implementation(), ec);
  391. ASIO_SYNC_OP_VOID_RETURN(ec);
  392. }
  393. /// Get the native serial port representation.
  394. /**
  395. * This function may be used to obtain the underlying representation of the
  396. * serial port. This is intended to allow access to native serial port
  397. * functionality that is not otherwise provided.
  398. */
  399. native_handle_type native_handle()
  400. {
  401. return impl_.get_service().native_handle(impl_.get_implementation());
  402. }
  403. /// Cancel all asynchronous operations associated with the serial port.
  404. /**
  405. * This function causes all outstanding asynchronous read or write operations
  406. * to finish immediately, and the handlers for cancelled operations will be
  407. * passed the asio::error::operation_aborted error.
  408. *
  409. * @throws asio::system_error Thrown on failure.
  410. */
  411. void cancel()
  412. {
  413. asio::error_code ec;
  414. impl_.get_service().cancel(impl_.get_implementation(), ec);
  415. asio::detail::throw_error(ec, "cancel");
  416. }
  417. /// Cancel all asynchronous operations associated with the serial port.
  418. /**
  419. * This function causes all outstanding asynchronous read or write operations
  420. * to finish immediately, and the handlers for cancelled operations will be
  421. * passed the asio::error::operation_aborted error.
  422. *
  423. * @param ec Set to indicate what error occurred, if any.
  424. */
  425. ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
  426. {
  427. impl_.get_service().cancel(impl_.get_implementation(), ec);
  428. ASIO_SYNC_OP_VOID_RETURN(ec);
  429. }
  430. /// Send a break sequence to the serial port.
  431. /**
  432. * This function causes a break sequence of platform-specific duration to be
  433. * sent out the serial port.
  434. *
  435. * @throws asio::system_error Thrown on failure.
  436. */
  437. void send_break()
  438. {
  439. asio::error_code ec;
  440. impl_.get_service().send_break(impl_.get_implementation(), ec);
  441. asio::detail::throw_error(ec, "send_break");
  442. }
  443. /// Send a break sequence to the serial port.
  444. /**
  445. * This function causes a break sequence of platform-specific duration to be
  446. * sent out the serial port.
  447. *
  448. * @param ec Set to indicate what error occurred, if any.
  449. */
  450. ASIO_SYNC_OP_VOID send_break(asio::error_code& ec)
  451. {
  452. impl_.get_service().send_break(impl_.get_implementation(), ec);
  453. ASIO_SYNC_OP_VOID_RETURN(ec);
  454. }
  455. /// Set an option on the serial port.
  456. /**
  457. * This function is used to set an option on the serial port.
  458. *
  459. * @param option The option value to be set on the serial port.
  460. *
  461. * @throws asio::system_error Thrown on failure.
  462. *
  463. * @sa SettableSerialPortOption @n
  464. * asio::serial_port_base::baud_rate @n
  465. * asio::serial_port_base::flow_control @n
  466. * asio::serial_port_base::parity @n
  467. * asio::serial_port_base::stop_bits @n
  468. * asio::serial_port_base::character_size
  469. */
  470. template <typename SettableSerialPortOption>
  471. void set_option(const SettableSerialPortOption& option)
  472. {
  473. asio::error_code ec;
  474. impl_.get_service().set_option(impl_.get_implementation(), option, ec);
  475. asio::detail::throw_error(ec, "set_option");
  476. }
  477. /// Set an option on the serial port.
  478. /**
  479. * This function is used to set an option on the serial port.
  480. *
  481. * @param option The option value to be set on the serial port.
  482. *
  483. * @param ec Set to indicate what error occurred, if any.
  484. *
  485. * @sa SettableSerialPortOption @n
  486. * asio::serial_port_base::baud_rate @n
  487. * asio::serial_port_base::flow_control @n
  488. * asio::serial_port_base::parity @n
  489. * asio::serial_port_base::stop_bits @n
  490. * asio::serial_port_base::character_size
  491. */
  492. template <typename SettableSerialPortOption>
  493. ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option,
  494. asio::error_code& ec)
  495. {
  496. impl_.get_service().set_option(impl_.get_implementation(), option, ec);
  497. ASIO_SYNC_OP_VOID_RETURN(ec);
  498. }
  499. /// Get an option from the serial port.
  500. /**
  501. * This function is used to get the current value of an option on the serial
  502. * port.
  503. *
  504. * @param option The option value to be obtained from the serial port.
  505. *
  506. * @throws asio::system_error Thrown on failure.
  507. *
  508. * @sa GettableSerialPortOption @n
  509. * asio::serial_port_base::baud_rate @n
  510. * asio::serial_port_base::flow_control @n
  511. * asio::serial_port_base::parity @n
  512. * asio::serial_port_base::stop_bits @n
  513. * asio::serial_port_base::character_size
  514. */
  515. template <typename GettableSerialPortOption>
  516. void get_option(GettableSerialPortOption& option)
  517. {
  518. asio::error_code ec;
  519. impl_.get_service().get_option(impl_.get_implementation(), option, ec);
  520. asio::detail::throw_error(ec, "get_option");
  521. }
  522. /// Get an option from the serial port.
  523. /**
  524. * This function is used to get the current value of an option on the serial
  525. * port.
  526. *
  527. * @param option The option value to be obtained from the serial port.
  528. *
  529. * @param ec Set to indicate what error occurred, if any.
  530. *
  531. * @sa GettableSerialPortOption @n
  532. * asio::serial_port_base::baud_rate @n
  533. * asio::serial_port_base::flow_control @n
  534. * asio::serial_port_base::parity @n
  535. * asio::serial_port_base::stop_bits @n
  536. * asio::serial_port_base::character_size
  537. */
  538. template <typename GettableSerialPortOption>
  539. ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option,
  540. asio::error_code& ec)
  541. {
  542. impl_.get_service().get_option(impl_.get_implementation(), option, ec);
  543. ASIO_SYNC_OP_VOID_RETURN(ec);
  544. }
  545. /// Write some data to the serial port.
  546. /**
  547. * This function is used to write data to the serial port. The function call
  548. * will block until one or more bytes of the data has been written
  549. * successfully, or until an error occurs.
  550. *
  551. * @param buffers One or more data buffers to be written to the serial port.
  552. *
  553. * @returns The number of bytes written.
  554. *
  555. * @throws asio::system_error Thrown on failure. An error code of
  556. * asio::error::eof indicates that the connection was closed by the
  557. * peer.
  558. *
  559. * @note The write_some operation may not transmit all of the data to the
  560. * peer. Consider using the @ref write function if you need to ensure that
  561. * all data is written before the blocking operation completes.
  562. *
  563. * @par Example
  564. * To write a single data buffer use the @ref buffer function as follows:
  565. * @code
  566. * basic_serial_port.write_some(asio::buffer(data, size));
  567. * @endcode
  568. * See the @ref buffer documentation for information on writing multiple
  569. * buffers in one go, and how to use it with arrays, boost::array or
  570. * std::vector.
  571. */
  572. template <typename ConstBufferSequence>
  573. std::size_t write_some(const ConstBufferSequence& buffers)
  574. {
  575. asio::error_code ec;
  576. std::size_t s = impl_.get_service().write_some(
  577. impl_.get_implementation(), buffers, ec);
  578. asio::detail::throw_error(ec, "write_some");
  579. return s;
  580. }
  581. /// Write some data to the serial port.
  582. /**
  583. * This function is used to write data to the serial port. The function call
  584. * will block until one or more bytes of the data has been written
  585. * successfully, or until an error occurs.
  586. *
  587. * @param buffers One or more data buffers to be written to the serial port.
  588. *
  589. * @param ec Set to indicate what error occurred, if any.
  590. *
  591. * @returns The number of bytes written. Returns 0 if an error occurred.
  592. *
  593. * @note The write_some operation may not transmit all of the data to the
  594. * peer. Consider using the @ref write function if you need to ensure that
  595. * all data is written before the blocking operation completes.
  596. */
  597. template <typename ConstBufferSequence>
  598. std::size_t write_some(const ConstBufferSequence& buffers,
  599. asio::error_code& ec)
  600. {
  601. return impl_.get_service().write_some(
  602. impl_.get_implementation(), buffers, ec);
  603. }
  604. /// Start an asynchronous write.
  605. /**
  606. * This function is used to asynchronously write data to the serial port.
  607. * The function call always returns immediately.
  608. *
  609. * @param buffers One or more data buffers to be written to the serial port.
  610. * Although the buffers object may be copied as necessary, ownership of the
  611. * underlying memory blocks is retained by the caller, which must guarantee
  612. * that they remain valid until the handler is called.
  613. *
  614. * @param handler The handler to be called when the write operation completes.
  615. * Copies will be made of the handler as required. The function signature of
  616. * the handler must be:
  617. * @code void handler(
  618. * const asio::error_code& error, // Result of operation.
  619. * std::size_t bytes_transferred // Number of bytes written.
  620. * ); @endcode
  621. * Regardless of whether the asynchronous operation completes immediately or
  622. * not, the handler will not be invoked from within this function. On
  623. * immediate completion, invocation of the handler will be performed in a
  624. * manner equivalent to using asio::post().
  625. *
  626. * @note The write operation may not transmit all of the data to the peer.
  627. * Consider using the @ref async_write function if you need to ensure that all
  628. * data is written before the asynchronous operation completes.
  629. *
  630. * @par Example
  631. * To write a single data buffer use the @ref buffer function as follows:
  632. * @code
  633. * basic_serial_port.async_write_some(
  634. * asio::buffer(data, size), handler);
  635. * @endcode
  636. * See the @ref buffer documentation for information on writing multiple
  637. * buffers in one go, and how to use it with arrays, boost::array or
  638. * std::vector.
  639. */
  640. template <typename ConstBufferSequence, typename WriteHandler>
  641. ASIO_INITFN_RESULT_TYPE(WriteHandler,
  642. void (asio::error_code, std::size_t))
  643. async_write_some(const ConstBufferSequence& buffers,
  644. ASIO_MOVE_ARG(WriteHandler) handler)
  645. {
  646. return async_initiate<WriteHandler,
  647. void (asio::error_code, std::size_t)>(
  648. initiate_async_write_some(), handler, this, buffers);
  649. }
  650. /// Read some data from the serial port.
  651. /**
  652. * This function is used to read data from the serial port. The function
  653. * call will block until one or more bytes of data has been read successfully,
  654. * or until an error occurs.
  655. *
  656. * @param buffers One or more buffers into which the data will be read.
  657. *
  658. * @returns The number of bytes read.
  659. *
  660. * @throws asio::system_error Thrown on failure. An error code of
  661. * asio::error::eof indicates that the connection was closed by the
  662. * peer.
  663. *
  664. * @note The read_some operation may not read all of the requested number of
  665. * bytes. Consider using the @ref read function if you need to ensure that
  666. * the requested amount of data is read before the blocking operation
  667. * completes.
  668. *
  669. * @par Example
  670. * To read into a single data buffer use the @ref buffer function as follows:
  671. * @code
  672. * basic_serial_port.read_some(asio::buffer(data, size));
  673. * @endcode
  674. * See the @ref buffer documentation for information on reading into multiple
  675. * buffers in one go, and how to use it with arrays, boost::array or
  676. * std::vector.
  677. */
  678. template <typename MutableBufferSequence>
  679. std::size_t read_some(const MutableBufferSequence& buffers)
  680. {
  681. asio::error_code ec;
  682. std::size_t s = impl_.get_service().read_some(
  683. impl_.get_implementation(), buffers, ec);
  684. asio::detail::throw_error(ec, "read_some");
  685. return s;
  686. }
  687. /// Read some data from the serial port.
  688. /**
  689. * This function is used to read data from the serial port. The function
  690. * call will block until one or more bytes of data has been read successfully,
  691. * or until an error occurs.
  692. *
  693. * @param buffers One or more buffers into which the data will be read.
  694. *
  695. * @param ec Set to indicate what error occurred, if any.
  696. *
  697. * @returns The number of bytes read. Returns 0 if an error occurred.
  698. *
  699. * @note The read_some operation may not read all of the requested number of
  700. * bytes. Consider using the @ref read function if you need to ensure that
  701. * the requested amount of data is read before the blocking operation
  702. * completes.
  703. */
  704. template <typename MutableBufferSequence>
  705. std::size_t read_some(const MutableBufferSequence& buffers,
  706. asio::error_code& ec)
  707. {
  708. return impl_.get_service().read_some(
  709. impl_.get_implementation(), buffers, ec);
  710. }
  711. /// Start an asynchronous read.
  712. /**
  713. * This function is used to asynchronously read data from the serial port.
  714. * The function call always returns immediately.
  715. *
  716. * @param buffers One or more buffers into which the data will be read.
  717. * Although the buffers object may be copied as necessary, ownership of the
  718. * underlying memory blocks is retained by the caller, which must guarantee
  719. * that they remain valid until the handler is called.
  720. *
  721. * @param handler The handler to be called when the read operation completes.
  722. * Copies will be made of the handler as required. The function signature of
  723. * the handler must be:
  724. * @code void handler(
  725. * const asio::error_code& error, // Result of operation.
  726. * std::size_t bytes_transferred // Number of bytes read.
  727. * ); @endcode
  728. * Regardless of whether the asynchronous operation completes immediately or
  729. * not, the handler will not be invoked from within this function. On
  730. * immediate completion, invocation of the handler will be performed in a
  731. * manner equivalent to using asio::post().
  732. *
  733. * @note The read operation may not read all of the requested number of bytes.
  734. * Consider using the @ref async_read function if you need to ensure that the
  735. * requested amount of data is read before the asynchronous operation
  736. * completes.
  737. *
  738. * @par Example
  739. * To read into a single data buffer use the @ref buffer function as follows:
  740. * @code
  741. * basic_serial_port.async_read_some(
  742. * asio::buffer(data, size), handler);
  743. * @endcode
  744. * See the @ref buffer documentation for information on reading into multiple
  745. * buffers in one go, and how to use it with arrays, boost::array or
  746. * std::vector.
  747. */
  748. template <typename MutableBufferSequence, typename ReadHandler>
  749. ASIO_INITFN_RESULT_TYPE(ReadHandler,
  750. void (asio::error_code, std::size_t))
  751. async_read_some(const MutableBufferSequence& buffers,
  752. ASIO_MOVE_ARG(ReadHandler) handler)
  753. {
  754. return async_initiate<ReadHandler,
  755. void (asio::error_code, std::size_t)>(
  756. initiate_async_read_some(), handler, this, buffers);
  757. }
  758. private:
  759. // Disallow copying and assignment.
  760. basic_serial_port(const basic_serial_port&) ASIO_DELETED;
  761. basic_serial_port& operator=(const basic_serial_port&) ASIO_DELETED;
  762. struct initiate_async_write_some
  763. {
  764. template <typename WriteHandler, typename ConstBufferSequence>
  765. void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
  766. basic_serial_port* self, const ConstBufferSequence& buffers) const
  767. {
  768. // If you get an error on the following line it means that your handler
  769. // does not meet the documented type requirements for a WriteHandler.
  770. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  771. detail::non_const_lvalue<WriteHandler> handler2(handler);
  772. self->impl_.get_service().async_write_some(
  773. self->impl_.get_implementation(), buffers, handler2.value,
  774. self->impl_.get_implementation_executor());
  775. }
  776. };
  777. struct initiate_async_read_some
  778. {
  779. template <typename ReadHandler, typename MutableBufferSequence>
  780. void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
  781. basic_serial_port* self, const MutableBufferSequence& buffers) const
  782. {
  783. // If you get an error on the following line it means that your handler
  784. // does not meet the documented type requirements for a ReadHandler.
  785. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  786. detail::non_const_lvalue<ReadHandler> handler2(handler);
  787. self->impl_.get_service().async_read_some(
  788. self->impl_.get_implementation(), buffers, handler2.value,
  789. self->impl_.get_implementation_executor());
  790. }
  791. };
  792. #if defined(ASIO_HAS_IOCP)
  793. detail::io_object_impl<detail::win_iocp_serial_port_service, Executor> impl_;
  794. #else
  795. detail::io_object_impl<detail::reactive_serial_port_service, Executor> impl_;
  796. #endif
  797. };
  798. } // namespace asio
  799. #include "asio/detail/pop_options.hpp"
  800. #endif // defined(ASIO_HAS_SERIAL_PORT)
  801. // || defined(GENERATING_DOCUMENTATION)
  802. #endif // ASIO_BASIC_SERIAL_PORT_HPP