serial_port.hpp 26 KB

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