basic_stream_file.hpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. //
  2. // basic_stream_file.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2022 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_BASIC_STREAM_FILE_HPP
  11. #define ASIO_BASIC_STREAM_FILE_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_HAS_FILE) \
  17. || defined(GENERATING_DOCUMENTATION)
  18. #include <cstddef>
  19. #include "asio/async_result.hpp"
  20. #include "asio/basic_file.hpp"
  21. #include "asio/detail/handler_type_requirements.hpp"
  22. #include "asio/detail/non_const_lvalue.hpp"
  23. #include "asio/detail/throw_error.hpp"
  24. #include "asio/error.hpp"
  25. #include "asio/detail/push_options.hpp"
  26. namespace asio {
  27. #if !defined(ASIO_BASIC_STREAM_FILE_FWD_DECL)
  28. #define ASIO_BASIC_STREAM_FILE_FWD_DECL
  29. // Forward declaration with defaulted arguments.
  30. template <typename Executor = any_io_executor>
  31. class basic_stream_file;
  32. #endif // !defined(ASIO_BASIC_STREAM_FILE_FWD_DECL)
  33. /// Provides stream-oriented file functionality.
  34. /**
  35. * The basic_stream_file class template provides asynchronous and blocking
  36. * stream-oriented file functionality.
  37. *
  38. * @par Thread Safety
  39. * @e Distinct @e objects: Safe.@n
  40. * @e Shared @e objects: Unsafe.
  41. *
  42. * @par Concepts:
  43. * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
  44. */
  45. template <typename Executor>
  46. class basic_stream_file
  47. : public basic_file<Executor>
  48. {
  49. public:
  50. /// The type of the executor associated with the object.
  51. typedef Executor executor_type;
  52. /// Rebinds the file type to another executor.
  53. template <typename Executor1>
  54. struct rebind_executor
  55. {
  56. /// The file type when rebound to the specified executor.
  57. typedef basic_stream_file<Executor1> other;
  58. };
  59. /// The native representation of a file.
  60. #if defined(GENERATING_DOCUMENTATION)
  61. typedef implementation_defined native_handle_type;
  62. #else
  63. typedef typename basic_file<Executor>::native_handle_type native_handle_type;
  64. #endif
  65. /// Construct a basic_stream_file without opening it.
  66. /**
  67. * This constructor initialises a file without opening it. The file needs to
  68. * be opened before data can be read from or or written to it.
  69. *
  70. * @param ex The I/O executor that the file will use, by default, to
  71. * dispatch handlers for any asynchronous operations performed on the file.
  72. */
  73. explicit basic_stream_file(const executor_type& ex)
  74. : basic_file<Executor>(ex)
  75. {
  76. this->impl_.get_service().set_is_stream(
  77. this->impl_.get_implementation(), true);
  78. }
  79. /// Construct a basic_stream_file without opening it.
  80. /**
  81. * This constructor initialises a file without opening it. The file needs to
  82. * be opened before data can be read from or or written to it.
  83. *
  84. * @param context An execution context which provides the I/O executor that
  85. * the file will use, by default, to dispatch handlers for any asynchronous
  86. * operations performed on the file.
  87. */
  88. template <typename ExecutionContext>
  89. explicit basic_stream_file(ExecutionContext& context,
  90. typename constraint<
  91. is_convertible<ExecutionContext&, execution_context&>::value,
  92. defaulted_constraint
  93. >::type = defaulted_constraint())
  94. : basic_file<Executor>(context)
  95. {
  96. this->impl_.get_service().set_is_stream(
  97. this->impl_.get_implementation(), true);
  98. }
  99. /// Construct and open a basic_stream_file.
  100. /**
  101. * This constructor initialises and opens a file.
  102. *
  103. * @param ex The I/O executor that the file will use, by default, to
  104. * dispatch handlers for any asynchronous operations performed on the file.
  105. *
  106. * @param path The path name identifying the file to be opened.
  107. *
  108. * @param open_flags A set of flags that determine how the file should be
  109. * opened.
  110. *
  111. * @throws asio::system_error Thrown on failure.
  112. */
  113. basic_stream_file(const executor_type& ex,
  114. const char* path, file_base::flags open_flags)
  115. : basic_file<Executor>(ex)
  116. {
  117. asio::error_code ec;
  118. this->impl_.get_service().set_is_stream(
  119. this->impl_.get_implementation(), true);
  120. this->impl_.get_service().open(
  121. this->impl_.get_implementation(),
  122. path, open_flags, ec);
  123. asio::detail::throw_error(ec, "open");
  124. }
  125. /// Construct and open a basic_stream_file.
  126. /**
  127. * This constructor initialises and opens a file.
  128. *
  129. * @param context An execution context which provides the I/O executor that
  130. * the file will use, by default, to dispatch handlers for any asynchronous
  131. * operations performed on the file.
  132. *
  133. * @param path The path name identifying the file to be opened.
  134. *
  135. * @param open_flags A set of flags that determine how the file should be
  136. * opened.
  137. *
  138. * @throws asio::system_error Thrown on failure.
  139. */
  140. template <typename ExecutionContext>
  141. basic_stream_file(ExecutionContext& context,
  142. const char* path, file_base::flags open_flags,
  143. typename constraint<
  144. is_convertible<ExecutionContext&, execution_context&>::value,
  145. defaulted_constraint
  146. >::type = defaulted_constraint())
  147. : basic_file<Executor>(context)
  148. {
  149. asio::error_code ec;
  150. this->impl_.get_service().set_is_stream(
  151. this->impl_.get_implementation(), true);
  152. this->impl_.get_service().open(
  153. this->impl_.get_implementation(),
  154. path, open_flags, ec);
  155. asio::detail::throw_error(ec, "open");
  156. }
  157. /// Construct and open a basic_stream_file.
  158. /**
  159. * This constructor initialises and opens a file.
  160. *
  161. * @param ex The I/O executor that the file will use, by default, to
  162. * dispatch handlers for any asynchronous operations performed on the file.
  163. *
  164. * @param path The path name identifying the file to be opened.
  165. *
  166. * @param open_flags A set of flags that determine how the file should be
  167. * opened.
  168. *
  169. * @throws asio::system_error Thrown on failure.
  170. */
  171. basic_stream_file(const executor_type& ex,
  172. const std::string& path, file_base::flags open_flags)
  173. : basic_file<Executor>(ex)
  174. {
  175. asio::error_code ec;
  176. this->impl_.get_service().set_is_stream(
  177. this->impl_.get_implementation(), true);
  178. this->impl_.get_service().open(
  179. this->impl_.get_implementation(),
  180. path.c_str(), open_flags, ec);
  181. asio::detail::throw_error(ec, "open");
  182. }
  183. /// Construct and open a basic_stream_file.
  184. /**
  185. * This constructor initialises and opens a file.
  186. *
  187. * @param context An execution context which provides the I/O executor that
  188. * the file will use, by default, to dispatch handlers for any asynchronous
  189. * operations performed on the file.
  190. *
  191. * @param path The path name identifying the file to be opened.
  192. *
  193. * @param open_flags A set of flags that determine how the file should be
  194. * opened.
  195. *
  196. * @throws asio::system_error Thrown on failure.
  197. */
  198. template <typename ExecutionContext>
  199. basic_stream_file(ExecutionContext& context,
  200. const std::string& path, file_base::flags open_flags,
  201. typename constraint<
  202. is_convertible<ExecutionContext&, execution_context&>::value,
  203. defaulted_constraint
  204. >::type = defaulted_constraint())
  205. : basic_file<Executor>(context)
  206. {
  207. asio::error_code ec;
  208. this->impl_.get_service().set_is_stream(
  209. this->impl_.get_implementation(), true);
  210. this->impl_.get_service().open(
  211. this->impl_.get_implementation(),
  212. path.c_str(), open_flags, ec);
  213. asio::detail::throw_error(ec, "open");
  214. }
  215. /// Construct a basic_stream_file on an existing native file.
  216. /**
  217. * This constructor initialises a stream file object to hold an existing
  218. * native file.
  219. *
  220. * @param ex The I/O executor that the file will use, by default, to
  221. * dispatch handlers for any asynchronous operations performed on the file.
  222. *
  223. * @param native_file The new underlying file implementation.
  224. *
  225. * @throws asio::system_error Thrown on failure.
  226. */
  227. basic_stream_file(const executor_type& ex,
  228. const native_handle_type& native_file)
  229. : basic_file<Executor>(ex, native_file)
  230. {
  231. this->impl_.get_service().set_is_stream(
  232. this->impl_.get_implementation(), true);
  233. }
  234. /// Construct a basic_stream_file on an existing native file.
  235. /**
  236. * This constructor initialises a stream file object to hold an existing
  237. * native file.
  238. *
  239. * @param context An execution context which provides the I/O executor that
  240. * the file will use, by default, to dispatch handlers for any asynchronous
  241. * operations performed on the file.
  242. *
  243. * @param native_file The new underlying file implementation.
  244. *
  245. * @throws asio::system_error Thrown on failure.
  246. */
  247. template <typename ExecutionContext>
  248. basic_stream_file(ExecutionContext& context,
  249. const native_handle_type& native_file,
  250. typename constraint<
  251. is_convertible<ExecutionContext&, execution_context&>::value,
  252. defaulted_constraint
  253. >::type = defaulted_constraint())
  254. : basic_file<Executor>(context, native_file)
  255. {
  256. this->impl_.get_service().set_is_stream(
  257. this->impl_.get_implementation(), true);
  258. }
  259. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  260. /// Move-construct a basic_stream_file from another.
  261. /**
  262. * This constructor moves a stream file from one object to another.
  263. *
  264. * @param other The other basic_stream_file object from which the move
  265. * will occur.
  266. *
  267. * @note Following the move, the moved-from object is in the same state as if
  268. * constructed using the @c basic_stream_file(const executor_type&)
  269. * constructor.
  270. */
  271. basic_stream_file(basic_stream_file&& other) ASIO_NOEXCEPT
  272. : basic_file<Executor>(std::move(other))
  273. {
  274. }
  275. /// Move-assign a basic_stream_file from another.
  276. /**
  277. * This assignment operator moves a stream file from one object to another.
  278. *
  279. * @param other The other basic_stream_file object from which the move
  280. * will occur.
  281. *
  282. * @note Following the move, the moved-from object is in the same state as if
  283. * constructed using the @c basic_stream_file(const executor_type&)
  284. * constructor.
  285. */
  286. basic_stream_file& operator=(basic_stream_file&& other)
  287. {
  288. basic_file<Executor>::operator=(std::move(other));
  289. return *this;
  290. }
  291. /// Move-construct a basic_stream_file from a file of another executor
  292. /// type.
  293. /**
  294. * This constructor moves a stream file from one object to another.
  295. *
  296. * @param other The other basic_stream_file object from which the move
  297. * will occur.
  298. *
  299. * @note Following the move, the moved-from object is in the same state as if
  300. * constructed using the @c basic_stream_file(const executor_type&)
  301. * constructor.
  302. */
  303. template <typename Executor1>
  304. basic_stream_file(basic_stream_file<Executor1>&& other,
  305. typename constraint<
  306. is_convertible<Executor1, Executor>::value,
  307. defaulted_constraint
  308. >::type = defaulted_constraint())
  309. : basic_file<Executor>(std::move(other))
  310. {
  311. }
  312. /// Move-assign a basic_stream_file from a file of another executor type.
  313. /**
  314. * This assignment operator moves a stream file from one object to another.
  315. *
  316. * @param other The other basic_stream_file object from which the move
  317. * will occur.
  318. *
  319. * @note Following the move, the moved-from object is in the same state as if
  320. * constructed using the @c basic_stream_file(const executor_type&)
  321. * constructor.
  322. */
  323. template <typename Executor1>
  324. typename constraint<
  325. is_convertible<Executor1, Executor>::value,
  326. basic_stream_file&
  327. >::type operator=(basic_stream_file<Executor1>&& other)
  328. {
  329. basic_file<Executor>::operator=(std::move(other));
  330. return *this;
  331. }
  332. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  333. /// Destroys the file.
  334. /**
  335. * This function destroys the file, cancelling any outstanding asynchronous
  336. * operations associated with the file as if by calling @c cancel.
  337. */
  338. ~basic_stream_file()
  339. {
  340. }
  341. /// Seek to a position in the file.
  342. /**
  343. * This function updates the current position in the file.
  344. *
  345. * @param offset The requested position in the file, relative to @c whence.
  346. *
  347. * @param whence One of @c seek_set, @c seek_cur or @c seek_end.
  348. *
  349. * @returns The new position relative to the beginning of the file.
  350. *
  351. * @throws asio::system_error Thrown on failure.
  352. */
  353. uint64_t seek(int64_t offset, file_base::seek_basis whence)
  354. {
  355. asio::error_code ec;
  356. uint64_t n = this->impl_.get_service().seek(
  357. this->impl_.get_implementation(), offset, whence, ec);
  358. asio::detail::throw_error(ec, "seek");
  359. return n;
  360. }
  361. /// Seek to a position in the file.
  362. /**
  363. * This function updates the current position in the file.
  364. *
  365. * @param offset The requested position in the file, relative to @c whence.
  366. *
  367. * @param whence One of @c seek_set, @c seek_cur or @c seek_end.
  368. *
  369. * @param ec Set to indicate what error occurred, if any.
  370. *
  371. * @returns The new position relative to the beginning of the file.
  372. */
  373. uint64_t seek(int64_t offset, file_base::seek_basis whence,
  374. asio::error_code& ec)
  375. {
  376. return this->impl_.get_service().seek(
  377. this->impl_.get_implementation(), offset, whence, ec);
  378. }
  379. /// Write some data to the file.
  380. /**
  381. * This function is used to write data to the stream file. The function call
  382. * will block until one or more bytes of the data has been written
  383. * successfully, or until an error occurs.
  384. *
  385. * @param buffers One or more data buffers to be written to the file.
  386. *
  387. * @returns The number of bytes written.
  388. *
  389. * @throws asio::system_error Thrown on failure. An error code of
  390. * asio::error::eof indicates that the end of the file was reached.
  391. *
  392. * @note The write_some operation may not transmit all of the data to the
  393. * peer. Consider using the @ref write function if you need to ensure that
  394. * all data is written before the blocking operation completes.
  395. *
  396. * @par Example
  397. * To write a single data buffer use the @ref buffer function as follows:
  398. * @code
  399. * file.write_some(asio::buffer(data, size));
  400. * @endcode
  401. * See the @ref buffer documentation for information on writing multiple
  402. * buffers in one go, and how to use it with arrays, boost::array or
  403. * std::vector.
  404. */
  405. template <typename ConstBufferSequence>
  406. std::size_t write_some(const ConstBufferSequence& buffers)
  407. {
  408. asio::error_code ec;
  409. std::size_t s = this->impl_.get_service().write_some(
  410. this->impl_.get_implementation(), buffers, ec);
  411. asio::detail::throw_error(ec, "write_some");
  412. return s;
  413. }
  414. /// Write some data to the file.
  415. /**
  416. * This function is used to write data to the stream file. The function call
  417. * will block until one or more bytes of the data has been written
  418. * successfully, or until an error occurs.
  419. *
  420. * @param buffers One or more data buffers to be written to the file.
  421. *
  422. * @param ec Set to indicate what error occurred, if any.
  423. *
  424. * @returns The number of bytes written. Returns 0 if an error occurred.
  425. *
  426. * @note The write_some operation may not transmit all of the data to the
  427. * peer. Consider using the @ref write function if you need to ensure that
  428. * all data is written before the blocking operation completes.
  429. */
  430. template <typename ConstBufferSequence>
  431. std::size_t write_some(const ConstBufferSequence& buffers,
  432. asio::error_code& ec)
  433. {
  434. return this->impl_.get_service().write_some(
  435. this->impl_.get_implementation(), buffers, ec);
  436. }
  437. /// Start an asynchronous write.
  438. /**
  439. * This function is used to asynchronously write data to the stream file.
  440. * It is an initiating function for an @ref asynchronous_operation, and always
  441. * returns immediately.
  442. *
  443. * @param buffers One or more data buffers to be written to the file.
  444. * Although the buffers object may be copied as necessary, ownership of the
  445. * underlying memory blocks is retained by the caller, which must guarantee
  446. * that they remain valid until the completion handler is called.
  447. *
  448. * @param token The @ref completion_token that will be used to produce a
  449. * completion handler, which will be called when the write completes.
  450. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  451. * @ref yield_context, or a function object with the correct completion
  452. * signature. The function signature of the completion handler must be:
  453. * @code void handler(
  454. * const asio::error_code& error, // Result of operation.
  455. * std::size_t bytes_transferred // Number of bytes written.
  456. * ); @endcode
  457. * Regardless of whether the asynchronous operation completes immediately or
  458. * not, the completion handler will not be invoked from within this function.
  459. * On immediate completion, invocation of the handler will be performed in a
  460. * manner equivalent to using asio::post().
  461. *
  462. * @par Completion Signature
  463. * @code void(asio::error_code, std::size_t) @endcode
  464. *
  465. * @note The write operation may not transmit all of the data to the peer.
  466. * Consider using the @ref async_write function if you need to ensure that all
  467. * data is written before the asynchronous operation completes.
  468. *
  469. * @par Example
  470. * To write a single data buffer use the @ref buffer function as follows:
  471. * @code
  472. * file.async_write_some(asio::buffer(data, size), handler);
  473. * @endcode
  474. * See the @ref buffer documentation for information on writing multiple
  475. * buffers in one go, and how to use it with arrays, boost::array or
  476. * std::vector.
  477. *
  478. * @par Per-Operation Cancellation
  479. * On POSIX or Windows operating systems, this asynchronous operation supports
  480. * cancellation for the following asio::cancellation_type values:
  481. *
  482. * @li @c cancellation_type::terminal
  483. *
  484. * @li @c cancellation_type::partial
  485. *
  486. * @li @c cancellation_type::total
  487. */
  488. template <typename ConstBufferSequence,
  489. ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
  490. std::size_t)) WriteToken
  491. ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  492. ASIO_INITFN_AUTO_RESULT_TYPE(WriteToken,
  493. void (asio::error_code, std::size_t))
  494. async_write_some(const ConstBufferSequence& buffers,
  495. ASIO_MOVE_ARG(WriteToken) token
  496. ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  497. {
  498. return async_initiate<WriteToken,
  499. void (asio::error_code, std::size_t)>(
  500. initiate_async_write_some(this), token, buffers);
  501. }
  502. /// Read some data from the file.
  503. /**
  504. * This function is used to read data from the stream file. The function
  505. * call will block until one or more bytes of data has been read successfully,
  506. * or until an error occurs.
  507. *
  508. * @param buffers One or more buffers into which the data will be read.
  509. *
  510. * @returns The number of bytes read.
  511. *
  512. * @throws asio::system_error Thrown on failure. An error code of
  513. * asio::error::eof indicates that the end of the file was reached.
  514. *
  515. * @note The read_some operation may not read all of the requested number of
  516. * bytes. Consider using the @ref read function if you need to ensure that
  517. * the requested amount of data is read before the blocking operation
  518. * completes.
  519. *
  520. * @par Example
  521. * To read into a single data buffer use the @ref buffer function as follows:
  522. * @code
  523. * file.read_some(asio::buffer(data, size));
  524. * @endcode
  525. * See the @ref buffer documentation for information on reading into multiple
  526. * buffers in one go, and how to use it with arrays, boost::array or
  527. * std::vector.
  528. */
  529. template <typename MutableBufferSequence>
  530. std::size_t read_some(const MutableBufferSequence& buffers)
  531. {
  532. asio::error_code ec;
  533. std::size_t s = this->impl_.get_service().read_some(
  534. this->impl_.get_implementation(), buffers, ec);
  535. asio::detail::throw_error(ec, "read_some");
  536. return s;
  537. }
  538. /// Read some data from the file.
  539. /**
  540. * This function is used to read data from the stream file. The function
  541. * call will block until one or more bytes of data has been read successfully,
  542. * or until an error occurs.
  543. *
  544. * @param buffers One or more buffers into which the data will be read.
  545. *
  546. * @param ec Set to indicate what error occurred, if any.
  547. *
  548. * @returns The number of bytes read. Returns 0 if an error occurred.
  549. *
  550. * @note The read_some operation may not read all of the requested number of
  551. * bytes. Consider using the @ref read function if you need to ensure that
  552. * the requested amount of data is read before the blocking operation
  553. * completes.
  554. */
  555. template <typename MutableBufferSequence>
  556. std::size_t read_some(const MutableBufferSequence& buffers,
  557. asio::error_code& ec)
  558. {
  559. return this->impl_.get_service().read_some(
  560. this->impl_.get_implementation(), buffers, ec);
  561. }
  562. /// Start an asynchronous read.
  563. /**
  564. * This function is used to asynchronously read data from the stream file.
  565. * It is an initiating function for an @ref asynchronous_operation, and always
  566. * returns immediately.
  567. *
  568. * @param buffers One or more buffers into which the data will be read.
  569. * Although the buffers object may be copied as necessary, ownership of the
  570. * underlying memory blocks is retained by the caller, which must guarantee
  571. * that they remain valid until the completion handler is called.
  572. *
  573. * @param token The @ref completion_token that will be used to produce a
  574. * completion handler, which will be called when the read completes.
  575. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  576. * @ref yield_context, or a function object with the correct completion
  577. * signature. The function signature of the completion handler must be:
  578. * @code void handler(
  579. * const asio::error_code& error, // Result of operation.
  580. * std::size_t bytes_transferred // Number of bytes read.
  581. * ); @endcode
  582. * Regardless of whether the asynchronous operation completes immediately or
  583. * not, the completion handler will not be invoked from within this function.
  584. * On immediate completion, invocation of the handler will be performed in a
  585. * manner equivalent to using asio::post().
  586. *
  587. * @par Completion Signature
  588. * @code void(asio::error_code, std::size_t) @endcode
  589. *
  590. * @note The read operation may not read all of the requested number of bytes.
  591. * Consider using the @ref async_read function if you need to ensure that the
  592. * requested amount of data is read before the asynchronous operation
  593. * completes.
  594. *
  595. * @par Example
  596. * To read into a single data buffer use the @ref buffer function as follows:
  597. * @code
  598. * file.async_read_some(asio::buffer(data, size), handler);
  599. * @endcode
  600. * See the @ref buffer documentation for information on reading into multiple
  601. * buffers in one go, and how to use it with arrays, boost::array or
  602. * std::vector.
  603. *
  604. * @par Per-Operation Cancellation
  605. * On POSIX or Windows operating systems, this asynchronous operation supports
  606. * cancellation for the following asio::cancellation_type values:
  607. *
  608. * @li @c cancellation_type::terminal
  609. *
  610. * @li @c cancellation_type::partial
  611. *
  612. * @li @c cancellation_type::total
  613. */
  614. template <typename MutableBufferSequence,
  615. ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
  616. std::size_t)) ReadToken
  617. ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  618. ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken,
  619. void (asio::error_code, std::size_t))
  620. async_read_some(const MutableBufferSequence& buffers,
  621. ASIO_MOVE_ARG(ReadToken) token
  622. ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  623. {
  624. return async_initiate<ReadToken,
  625. void (asio::error_code, std::size_t)>(
  626. initiate_async_read_some(this), token, buffers);
  627. }
  628. private:
  629. // Disallow copying and assignment.
  630. basic_stream_file(const basic_stream_file&) ASIO_DELETED;
  631. basic_stream_file& operator=(const basic_stream_file&) ASIO_DELETED;
  632. class initiate_async_write_some
  633. {
  634. public:
  635. typedef Executor executor_type;
  636. explicit initiate_async_write_some(basic_stream_file* self)
  637. : self_(self)
  638. {
  639. }
  640. executor_type get_executor() const ASIO_NOEXCEPT
  641. {
  642. return self_->get_executor();
  643. }
  644. template <typename WriteHandler, typename ConstBufferSequence>
  645. void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
  646. const ConstBufferSequence& buffers) const
  647. {
  648. // If you get an error on the following line it means that your handler
  649. // does not meet the documented type requirements for a WriteHandler.
  650. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  651. detail::non_const_lvalue<WriteHandler> handler2(handler);
  652. self_->impl_.get_service().async_write_some(
  653. self_->impl_.get_implementation(), buffers,
  654. handler2.value, self_->impl_.get_executor());
  655. }
  656. private:
  657. basic_stream_file* self_;
  658. };
  659. class initiate_async_read_some
  660. {
  661. public:
  662. typedef Executor executor_type;
  663. explicit initiate_async_read_some(basic_stream_file* self)
  664. : self_(self)
  665. {
  666. }
  667. executor_type get_executor() const ASIO_NOEXCEPT
  668. {
  669. return self_->get_executor();
  670. }
  671. template <typename ReadHandler, typename MutableBufferSequence>
  672. void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
  673. const MutableBufferSequence& buffers) const
  674. {
  675. // If you get an error on the following line it means that your handler
  676. // does not meet the documented type requirements for a ReadHandler.
  677. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  678. detail::non_const_lvalue<ReadHandler> handler2(handler);
  679. self_->impl_.get_service().async_read_some(
  680. self_->impl_.get_implementation(), buffers,
  681. handler2.value, self_->impl_.get_executor());
  682. }
  683. private:
  684. basic_stream_file* self_;
  685. };
  686. };
  687. } // namespace asio
  688. #include "asio/detail/pop_options.hpp"
  689. #endif // defined(ASIO_HAS_FILE)
  690. // || defined(GENERATING_DOCUMENTATION)
  691. #endif // ASIO_BASIC_STREAM_FILE_HPP