2 // posix/basic_stream_descriptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP
12 #define BOOST_ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
20 #if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
21 || defined(GENERATING_DOCUMENTATION)
24 #include <boost/asio/detail/handler_type_requirements.hpp>
25 #include <boost/asio/detail/throw_error.hpp>
26 #include <boost/asio/error.hpp>
27 #include <boost/asio/posix/basic_descriptor.hpp>
28 #include <boost/asio/posix/stream_descriptor_service.hpp>
30 #include <boost/asio/detail/push_options.hpp>
36 /// Provides stream-oriented descriptor functionality.
38 * The posix::basic_stream_descriptor class template provides asynchronous and
39 * blocking stream-oriented descriptor functionality.
42 * @e Distinct @e objects: Safe.@n
43 * @e Shared @e objects: Unsafe.
46 * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
48 template <typename StreamDescriptorService = stream_descriptor_service>
49 class basic_stream_descriptor
50 : public basic_descriptor<StreamDescriptorService>
53 /// (Deprecated: Use native_handle_type.) The native representation of a
55 typedef typename StreamDescriptorService::native_handle_type native_type;
57 /// The native representation of a descriptor.
58 typedef typename StreamDescriptorService::native_handle_type
61 /// Construct a basic_stream_descriptor without opening it.
63 * This constructor creates a stream descriptor without opening it. The
64 * descriptor needs to be opened and then connected or accepted before data
65 * can be sent or received on it.
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
71 explicit basic_stream_descriptor(boost::asio::io_service& io_service)
72 : basic_descriptor<StreamDescriptorService>(io_service)
76 /// Construct a basic_stream_descriptor on an existing native descriptor.
78 * This constructor creates a stream descriptor object to hold an existing
81 * @param io_service The io_service object that the stream descriptor will
82 * use to dispatch handlers for any asynchronous operations performed on the
85 * @param native_descriptor The new underlying descriptor implementation.
87 * @throws boost::system::system_error Thrown on failure.
89 basic_stream_descriptor(boost::asio::io_service& io_service,
90 const native_handle_type& native_descriptor)
91 : basic_descriptor<StreamDescriptorService>(io_service, native_descriptor)
95 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
96 /// Move-construct a basic_stream_descriptor from another.
98 * This constructor moves a stream descriptor from one object to another.
100 * @param other The other basic_stream_descriptor object from which the move
103 * @note Following the move, the moved-from object is in the same state as if
104 * constructed using the @c basic_stream_descriptor(io_service&) constructor.
106 basic_stream_descriptor(basic_stream_descriptor&& other)
107 : basic_descriptor<StreamDescriptorService>(
108 BOOST_ASIO_MOVE_CAST(basic_stream_descriptor)(other))
112 /// Move-assign a basic_stream_descriptor from another.
114 * This assignment operator moves a stream descriptor from one object to
117 * @param other The other basic_stream_descriptor object from which the move
120 * @note Following the move, the moved-from object is in the same state as if
121 * constructed using the @c basic_stream_descriptor(io_service&) constructor.
123 basic_stream_descriptor& operator=(basic_stream_descriptor&& other)
125 basic_descriptor<StreamDescriptorService>::operator=(
126 BOOST_ASIO_MOVE_CAST(basic_stream_descriptor)(other));
129 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
131 /// Write some data to the descriptor.
133 * This function is used to write data to the stream descriptor. The function
134 * call will block until one or more bytes of the data has been written
135 * successfully, or until an error occurs.
137 * @param buffers One or more data buffers to be written to the descriptor.
139 * @returns The number of bytes written.
141 * @throws boost::system::system_error Thrown on failure. An error code of
142 * boost::asio::error::eof indicates that the connection was closed by the
145 * @note The write_some operation may not transmit all of the data to the
146 * peer. Consider using the @ref write function if you need to ensure that
147 * all data is written before the blocking operation completes.
150 * To write a single data buffer use the @ref buffer function as follows:
152 * descriptor.write_some(boost::asio::buffer(data, size));
154 * See the @ref buffer documentation for information on writing multiple
155 * buffers in one go, and how to use it with arrays, boost::array or
158 template <typename ConstBufferSequence>
159 std::size_t write_some(const ConstBufferSequence& buffers)
161 boost::system::error_code ec;
162 std::size_t s = this->get_service().write_some(
163 this->get_implementation(), buffers, ec);
164 boost::asio::detail::throw_error(ec, "write_some");
168 /// Write some data to the descriptor.
170 * This function is used to write data to the stream descriptor. The function
171 * call will block until one or more bytes of the data has been written
172 * successfully, or until an error occurs.
174 * @param buffers One or more data buffers to be written to the descriptor.
176 * @param ec Set to indicate what error occurred, if any.
178 * @returns The number of bytes written. Returns 0 if an error occurred.
180 * @note The write_some operation may not transmit all of the data to the
181 * peer. Consider using the @ref write function if you need to ensure that
182 * all data is written before the blocking operation completes.
184 template <typename ConstBufferSequence>
185 std::size_t write_some(const ConstBufferSequence& buffers,
186 boost::system::error_code& ec)
188 return this->get_service().write_some(
189 this->get_implementation(), buffers, ec);
192 /// Start an asynchronous write.
194 * This function is used to asynchronously write data to the stream
195 * descriptor. The function call always returns immediately.
197 * @param buffers One or more data buffers to be written to the descriptor.
198 * Although the buffers object may be copied as necessary, ownership of the
199 * underlying memory blocks is retained by the caller, which must guarantee
200 * that they remain valid until the handler is called.
202 * @param handler The handler to be called when the write operation completes.
203 * Copies will be made of the handler as required. The function signature of
204 * the handler must be:
205 * @code void handler(
206 * const boost::system::error_code& error, // Result of operation.
207 * std::size_t bytes_transferred // Number of bytes written.
209 * Regardless of whether the asynchronous operation completes immediately or
210 * not, the handler will not be invoked from within this function. Invocation
211 * of the handler will be performed in a manner equivalent to using
212 * boost::asio::io_service::post().
214 * @note The write operation may not transmit all of the data to the peer.
215 * Consider using the @ref async_write function if you need to ensure that all
216 * data is written before the asynchronous operation completes.
219 * To write a single data buffer use the @ref buffer function as follows:
221 * descriptor.async_write_some(boost::asio::buffer(data, size), handler);
223 * See the @ref buffer documentation for information on writing multiple
224 * buffers in one go, and how to use it with arrays, boost::array or
227 template <typename ConstBufferSequence, typename WriteHandler>
228 BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
229 void (boost::system::error_code, std::size_t))
230 async_write_some(const ConstBufferSequence& buffers,
231 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
233 // If you get an error on the following line it means that your handler does
234 // not meet the documented type requirements for a WriteHandler.
235 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
237 return this->get_service().async_write_some(this->get_implementation(),
238 buffers, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
241 /// Read some data from the descriptor.
243 * This function is used to read data from the stream descriptor. The function
244 * call will block until one or more bytes of data has been read successfully,
245 * or until an error occurs.
247 * @param buffers One or more buffers into which the data will be read.
249 * @returns The number of bytes read.
251 * @throws boost::system::system_error Thrown on failure. An error code of
252 * boost::asio::error::eof indicates that the connection was closed by the
255 * @note The read_some operation may not read all of the requested number of
256 * bytes. Consider using the @ref read function if you need to ensure that
257 * the requested amount of data is read before the blocking operation
261 * To read into a single data buffer use the @ref buffer function as follows:
263 * descriptor.read_some(boost::asio::buffer(data, size));
265 * See the @ref buffer documentation for information on reading into multiple
266 * buffers in one go, and how to use it with arrays, boost::array or
269 template <typename MutableBufferSequence>
270 std::size_t read_some(const MutableBufferSequence& buffers)
272 boost::system::error_code ec;
273 std::size_t s = this->get_service().read_some(
274 this->get_implementation(), buffers, ec);
275 boost::asio::detail::throw_error(ec, "read_some");
279 /// Read some data from the descriptor.
281 * This function is used to read data from the stream descriptor. The function
282 * call will block until one or more bytes of data has been read successfully,
283 * or until an error occurs.
285 * @param buffers One or more buffers into which the data will be read.
287 * @param ec Set to indicate what error occurred, if any.
289 * @returns The number of bytes read. Returns 0 if an error occurred.
291 * @note The read_some operation may not read all of the requested number of
292 * bytes. Consider using the @ref read function if you need to ensure that
293 * the requested amount of data is read before the blocking operation
296 template <typename MutableBufferSequence>
297 std::size_t read_some(const MutableBufferSequence& buffers,
298 boost::system::error_code& ec)
300 return this->get_service().read_some(
301 this->get_implementation(), buffers, ec);
304 /// Start an asynchronous read.
306 * This function is used to asynchronously read data from the stream
307 * descriptor. The function call always returns immediately.
309 * @param buffers One or more buffers into which the data will be read.
310 * Although the buffers object may be copied as necessary, ownership of the
311 * underlying memory blocks is retained by the caller, which must guarantee
312 * that they remain valid until the handler is called.
314 * @param handler The handler to be called when the read operation completes.
315 * Copies will be made of the handler as required. The function signature of
316 * the handler must be:
317 * @code void handler(
318 * const boost::system::error_code& error, // Result of operation.
319 * std::size_t bytes_transferred // Number of bytes read.
321 * Regardless of whether the asynchronous operation completes immediately or
322 * not, the handler will not be invoked from within this function. Invocation
323 * of the handler will be performed in a manner equivalent to using
324 * boost::asio::io_service::post().
326 * @note The read operation may not read all of the requested number of bytes.
327 * Consider using the @ref async_read function if you need to ensure that the
328 * requested amount of data is read before the asynchronous operation
332 * To read into a single data buffer use the @ref buffer function as follows:
334 * descriptor.async_read_some(boost::asio::buffer(data, size), handler);
336 * See the @ref buffer documentation for information on reading into multiple
337 * buffers in one go, and how to use it with arrays, boost::array or
340 template <typename MutableBufferSequence, typename ReadHandler>
341 BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
342 void (boost::system::error_code, std::size_t))
343 async_read_some(const MutableBufferSequence& buffers,
344 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
346 // If you get an error on the following line it means that your handler does
347 // not meet the documented type requirements for a ReadHandler.
348 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
350 return this->get_service().async_read_some(this->get_implementation(),
351 buffers, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
359 #include <boost/asio/detail/pop_options.hpp>
361 #endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
362 // || defined(GENERATING_DOCUMENTATION)
364 #endif // BOOST_ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP