basic_stream_descriptor.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. //
  2. // basic_stream_descriptor.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2008 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 BOOST_ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP
  11. #define BOOST_ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/push_options.hpp>
  16. #include <boost/asio/detail/push_options.hpp>
  17. #include <cstddef>
  18. #include <boost/config.hpp>
  19. #include <boost/asio/detail/pop_options.hpp>
  20. #include <boost/asio/error.hpp>
  21. #include <boost/asio/posix/basic_descriptor.hpp>
  22. #include <boost/asio/posix/stream_descriptor_service.hpp>
  23. #include <boost/asio/detail/throw_error.hpp>
  24. #if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
  25. || defined(GENERATING_DOCUMENTATION)
  26. namespace boost {
  27. namespace asio {
  28. namespace posix {
  29. /// Provides stream-oriented descriptor functionality.
  30. /**
  31. * The posix::basic_stream_descriptor class template provides asynchronous and
  32. * blocking stream-oriented descriptor functionality.
  33. *
  34. * @par Thread Safety
  35. * @e Distinct @e objects: Safe.@n
  36. * @e Shared @e objects: Unsafe.
  37. *
  38. * @par Concepts:
  39. * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
  40. */
  41. template <typename StreamDescriptorService = stream_descriptor_service>
  42. class basic_stream_descriptor
  43. : public basic_descriptor<StreamDescriptorService>
  44. {
  45. public:
  46. /// The native representation of a descriptor.
  47. typedef typename StreamDescriptorService::native_type native_type;
  48. /// Construct a basic_stream_descriptor without opening it.
  49. /**
  50. * This constructor creates a stream descriptor without opening it. The
  51. * descriptor needs to be opened and then connected or accepted before data
  52. * can be sent or received on it.
  53. *
  54. * @param io_service The io_service object that the stream descriptor will
  55. * use to dispatch handlers for any asynchronous operations performed on the
  56. * descriptor.
  57. */
  58. explicit basic_stream_descriptor(boost::asio::io_service& io_service)
  59. : basic_descriptor<StreamDescriptorService>(io_service)
  60. {
  61. }
  62. /// Construct a basic_stream_descriptor on an existing native descriptor.
  63. /**
  64. * This constructor creates a stream descriptor object to hold an existing
  65. * native descriptor.
  66. *
  67. * @param io_service The io_service object that the stream descriptor will
  68. * use to dispatch handlers for any asynchronous operations performed on the
  69. * descriptor.
  70. *
  71. * @param native_descriptor The new underlying descriptor implementation.
  72. *
  73. * @throws boost::system::system_error Thrown on failure.
  74. */
  75. basic_stream_descriptor(boost::asio::io_service& io_service,
  76. const native_type& native_descriptor)
  77. : basic_descriptor<StreamDescriptorService>(io_service, native_descriptor)
  78. {
  79. }
  80. /// Write some data to the descriptor.
  81. /**
  82. * This function is used to write data to the stream descriptor. The function
  83. * call will block until one or more bytes of the data has been written
  84. * successfully, or until an error occurs.
  85. *
  86. * @param buffers One or more data buffers to be written to the descriptor.
  87. *
  88. * @returns The number of bytes written.
  89. *
  90. * @throws boost::system::system_error Thrown on failure. An error code of
  91. * boost::asio::error::eof indicates that the connection was closed by the
  92. * peer.
  93. *
  94. * @note The write_some operation may not transmit all of the data to the
  95. * peer. Consider using the @ref write function if you need to ensure that
  96. * all data is written before the blocking operation completes.
  97. *
  98. * @par Example
  99. * To write a single data buffer use the @ref buffer function as follows:
  100. * @code
  101. * descriptor.write_some(boost::asio::buffer(data, size));
  102. * @endcode
  103. * See the @ref buffer documentation for information on writing multiple
  104. * buffers in one go, and how to use it with arrays, boost::array or
  105. * std::vector.
  106. */
  107. template <typename ConstBufferSequence>
  108. std::size_t write_some(const ConstBufferSequence& buffers)
  109. {
  110. boost::system::error_code ec;
  111. std::size_t s = this->service.write_some(this->implementation, buffers, ec);
  112. boost::asio::detail::throw_error(ec);
  113. return s;
  114. }
  115. /// Write some data to the descriptor.
  116. /**
  117. * This function is used to write data to the stream descriptor. The function
  118. * call will block until one or more bytes of the data has been written
  119. * successfully, or until an error occurs.
  120. *
  121. * @param buffers One or more data buffers to be written to the descriptor.
  122. *
  123. * @param ec Set to indicate what error occurred, if any.
  124. *
  125. * @returns The number of bytes written. Returns 0 if an error occurred.
  126. *
  127. * @note The write_some operation may not transmit all of the data to the
  128. * peer. Consider using the @ref write function if you need to ensure that
  129. * all data is written before the blocking operation completes.
  130. */
  131. template <typename ConstBufferSequence>
  132. std::size_t write_some(const ConstBufferSequence& buffers,
  133. boost::system::error_code& ec)
  134. {
  135. return this->service.write_some(this->implementation, buffers, ec);
  136. }
  137. /// Start an asynchronous write.
  138. /**
  139. * This function is used to asynchronously write data to the stream
  140. * descriptor. The function call always returns immediately.
  141. *
  142. * @param buffers One or more data buffers to be written to the descriptor.
  143. * Although the buffers object may be copied as necessary, ownership of the
  144. * underlying memory blocks is retained by the caller, which must guarantee
  145. * that they remain valid until the handler is called.
  146. *
  147. * @param handler The handler to be called when the write operation completes.
  148. * Copies will be made of the handler as required. The function signature of
  149. * the handler must be:
  150. * @code void handler(
  151. * const boost::system::error_code& error, // Result of operation.
  152. * std::size_t bytes_transferred // Number of bytes written.
  153. * ); @endcode
  154. * Regardless of whether the asynchronous operation completes immediately or
  155. * not, the handler will not be invoked from within this function. Invocation
  156. * of the handler will be performed in a manner equivalent to using
  157. * boost::asio::io_service::post().
  158. *
  159. * @note The write operation may not transmit all of the data to the peer.
  160. * Consider using the @ref async_write function if you need to ensure that all
  161. * data is written before the asynchronous operation completes.
  162. *
  163. * @par Example
  164. * To write a single data buffer use the @ref buffer function as follows:
  165. * @code
  166. * descriptor.async_write_some(boost::asio::buffer(data, size), handler);
  167. * @endcode
  168. * See the @ref buffer documentation for information on writing multiple
  169. * buffers in one go, and how to use it with arrays, boost::array or
  170. * std::vector.
  171. */
  172. template <typename ConstBufferSequence, typename WriteHandler>
  173. void async_write_some(const ConstBufferSequence& buffers,
  174. WriteHandler handler)
  175. {
  176. this->service.async_write_some(this->implementation, buffers, handler);
  177. }
  178. /// Read some data from the descriptor.
  179. /**
  180. * This function is used to read data from the stream descriptor. The function
  181. * call will block until one or more bytes of data has been read successfully,
  182. * or until an error occurs.
  183. *
  184. * @param buffers One or more buffers into which the data will be read.
  185. *
  186. * @returns The number of bytes read.
  187. *
  188. * @throws boost::system::system_error Thrown on failure. An error code of
  189. * boost::asio::error::eof indicates that the connection was closed by the
  190. * peer.
  191. *
  192. * @note The read_some operation may not read all of the requested number of
  193. * bytes. Consider using the @ref read function if you need to ensure that
  194. * the requested amount of data is read before the blocking operation
  195. * completes.
  196. *
  197. * @par Example
  198. * To read into a single data buffer use the @ref buffer function as follows:
  199. * @code
  200. * descriptor.read_some(boost::asio::buffer(data, size));
  201. * @endcode
  202. * See the @ref buffer documentation for information on reading into multiple
  203. * buffers in one go, and how to use it with arrays, boost::array or
  204. * std::vector.
  205. */
  206. template <typename MutableBufferSequence>
  207. std::size_t read_some(const MutableBufferSequence& buffers)
  208. {
  209. boost::system::error_code ec;
  210. std::size_t s = this->service.read_some(this->implementation, buffers, ec);
  211. boost::asio::detail::throw_error(ec);
  212. return s;
  213. }
  214. /// Read some data from the descriptor.
  215. /**
  216. * This function is used to read data from the stream descriptor. The function
  217. * call will block until one or more bytes of data has been read successfully,
  218. * or until an error occurs.
  219. *
  220. * @param buffers One or more buffers into which the data will be read.
  221. *
  222. * @param ec Set to indicate what error occurred, if any.
  223. *
  224. * @returns The number of bytes read. Returns 0 if an error occurred.
  225. *
  226. * @note The read_some operation may not read all of the requested number of
  227. * bytes. Consider using the @ref read function if you need to ensure that
  228. * the requested amount of data is read before the blocking operation
  229. * completes.
  230. */
  231. template <typename MutableBufferSequence>
  232. std::size_t read_some(const MutableBufferSequence& buffers,
  233. boost::system::error_code& ec)
  234. {
  235. return this->service.read_some(this->implementation, buffers, ec);
  236. }
  237. /// Start an asynchronous read.
  238. /**
  239. * This function is used to asynchronously read data from the stream
  240. * descriptor. The function call always returns immediately.
  241. *
  242. * @param buffers One or more buffers into which the data will be read.
  243. * Although the buffers object may be copied as necessary, ownership of the
  244. * underlying memory blocks is retained by the caller, which must guarantee
  245. * that they remain valid until the handler is called.
  246. *
  247. * @param handler The handler to be called when the read operation completes.
  248. * Copies will be made of the handler as required. The function signature of
  249. * the handler must be:
  250. * @code void handler(
  251. * const boost::system::error_code& error, // Result of operation.
  252. * std::size_t bytes_transferred // Number of bytes read.
  253. * ); @endcode
  254. * Regardless of whether the asynchronous operation completes immediately or
  255. * not, the handler will not be invoked from within this function. Invocation
  256. * of the handler will be performed in a manner equivalent to using
  257. * boost::asio::io_service::post().
  258. *
  259. * @note The read operation may not read all of the requested number of bytes.
  260. * Consider using the @ref async_read function if you need to ensure that the
  261. * requested amount of data is read before the asynchronous operation
  262. * completes.
  263. *
  264. * @par Example
  265. * To read into a single data buffer use the @ref buffer function as follows:
  266. * @code
  267. * descriptor.async_read_some(boost::asio::buffer(data, size), handler);
  268. * @endcode
  269. * See the @ref buffer documentation for information on reading into multiple
  270. * buffers in one go, and how to use it with arrays, boost::array or
  271. * std::vector.
  272. */
  273. template <typename MutableBufferSequence, typename ReadHandler>
  274. void async_read_some(const MutableBufferSequence& buffers,
  275. ReadHandler handler)
  276. {
  277. this->service.async_read_some(this->implementation, buffers, handler);
  278. }
  279. };
  280. } // namespace posix
  281. } // namespace asio
  282. } // namespace boost
  283. #endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
  284. // || defined(GENERATING_DOCUMENTATION)
  285. #include <boost/asio/detail/pop_options.hpp>
  286. #endif // BOOST_ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP