Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / asio / posix / basic_stream_descriptor.hpp
1 //
2 // posix/basic_stream_descriptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 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
11 #ifndef BOOST_ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP
12 #define BOOST_ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include <boost/asio/detail/config.hpp>
19
20 #if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
21   || defined(GENERATING_DOCUMENTATION)
22
23 #include <cstddef>
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>
29
30 #include <boost/asio/detail/push_options.hpp>
31
32 namespace boost {
33 namespace asio {
34 namespace posix {
35
36 /// Provides stream-oriented descriptor functionality.
37 /**
38  * The posix::basic_stream_descriptor class template provides asynchronous and
39  * blocking stream-oriented descriptor functionality.
40  *
41  * @par Thread Safety
42  * @e Distinct @e objects: Safe.@n
43  * @e Shared @e objects: Unsafe.
44  *
45  * @par Concepts:
46  * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
47  */
48 template <typename StreamDescriptorService = stream_descriptor_service>
49 class basic_stream_descriptor
50   : public basic_descriptor<StreamDescriptorService>
51 {
52 public:
53   /// (Deprecated: Use native_handle_type.) The native representation of a
54   /// descriptor.
55   typedef typename StreamDescriptorService::native_handle_type native_type;
56
57   /// The native representation of a descriptor.
58   typedef typename StreamDescriptorService::native_handle_type
59     native_handle_type;
60
61   /// Construct a basic_stream_descriptor without opening it.
62   /**
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.
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   explicit basic_stream_descriptor(boost::asio::io_service& io_service)
72     : basic_descriptor<StreamDescriptorService>(io_service)
73   {
74   }
75
76   /// Construct a basic_stream_descriptor on an existing native descriptor.
77   /**
78    * This constructor creates a stream descriptor object to hold an existing
79    * native descriptor.
80    *
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
83    * descriptor.
84    *
85    * @param native_descriptor The new underlying descriptor implementation.
86    *
87    * @throws boost::system::system_error Thrown on failure.
88    */
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)
92   {
93   }
94
95 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
96   /// Move-construct a basic_stream_descriptor from another.
97   /**
98    * This constructor moves a stream descriptor from one object to another.
99    *
100    * @param other The other basic_stream_descriptor object from which the move
101    * will occur.
102    *
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.
105    */
106   basic_stream_descriptor(basic_stream_descriptor&& other)
107     : basic_descriptor<StreamDescriptorService>(
108         BOOST_ASIO_MOVE_CAST(basic_stream_descriptor)(other))
109   {
110   }
111
112   /// Move-assign a basic_stream_descriptor from another.
113   /**
114    * This assignment operator moves a stream descriptor from one object to
115    * another.
116    *
117    * @param other The other basic_stream_descriptor object from which the move
118    * will occur.
119    *
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.
122    */
123   basic_stream_descriptor& operator=(basic_stream_descriptor&& other)
124   {
125     basic_descriptor<StreamDescriptorService>::operator=(
126         BOOST_ASIO_MOVE_CAST(basic_stream_descriptor)(other));
127     return *this;
128   }
129 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
130
131   /// Write some data to the descriptor.
132   /**
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.
136    *
137    * @param buffers One or more data buffers to be written to the descriptor.
138    *
139    * @returns The number of bytes written.
140    *
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
143    * peer.
144    *
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.
148    *
149    * @par Example
150    * To write a single data buffer use the @ref buffer function as follows:
151    * @code
152    * descriptor.write_some(boost::asio::buffer(data, size));
153    * @endcode
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
156    * std::vector.
157    */
158   template <typename ConstBufferSequence>
159   std::size_t write_some(const ConstBufferSequence& buffers)
160   {
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");
165     return s;
166   }
167
168   /// Write some data to the descriptor.
169   /**
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.
173    *
174    * @param buffers One or more data buffers to be written to the descriptor.
175    *
176    * @param ec Set to indicate what error occurred, if any.
177    *
178    * @returns The number of bytes written. Returns 0 if an error occurred.
179    *
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.
183    */
184   template <typename ConstBufferSequence>
185   std::size_t write_some(const ConstBufferSequence& buffers,
186       boost::system::error_code& ec)
187   {
188     return this->get_service().write_some(
189         this->get_implementation(), buffers, ec);
190   }
191
192   /// Start an asynchronous write.
193   /**
194    * This function is used to asynchronously write data to the stream
195    * descriptor. The function call always returns immediately.
196    *
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.
201    *
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.
208    * ); @endcode
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().
213    *
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.
217    *
218    * @par Example
219    * To write a single data buffer use the @ref buffer function as follows:
220    * @code
221    * descriptor.async_write_some(boost::asio::buffer(data, size), handler);
222    * @endcode
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
225    * std::vector.
226    */
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)
232   {
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;
236
237     return this->get_service().async_write_some(this->get_implementation(),
238         buffers, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
239   }
240
241   /// Read some data from the descriptor.
242   /**
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.
246    *
247    * @param buffers One or more buffers into which the data will be read.
248    *
249    * @returns The number of bytes read.
250    *
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
253    * peer.
254    *
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
258    * completes.
259    *
260    * @par Example
261    * To read into a single data buffer use the @ref buffer function as follows:
262    * @code
263    * descriptor.read_some(boost::asio::buffer(data, size));
264    * @endcode
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
267    * std::vector.
268    */
269   template <typename MutableBufferSequence>
270   std::size_t read_some(const MutableBufferSequence& buffers)
271   {
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");
276     return s;
277   }
278
279   /// Read some data from the descriptor.
280   /**
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.
284    *
285    * @param buffers One or more buffers into which the data will be read.
286    *
287    * @param ec Set to indicate what error occurred, if any.
288    *
289    * @returns The number of bytes read. Returns 0 if an error occurred.
290    *
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
294    * completes.
295    */
296   template <typename MutableBufferSequence>
297   std::size_t read_some(const MutableBufferSequence& buffers,
298       boost::system::error_code& ec)
299   {
300     return this->get_service().read_some(
301         this->get_implementation(), buffers, ec);
302   }
303
304   /// Start an asynchronous read.
305   /**
306    * This function is used to asynchronously read data from the stream
307    * descriptor. The function call always returns immediately.
308    *
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.
313    *
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.
320    * ); @endcode
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().
325    *
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
329    * completes.
330    *
331    * @par Example
332    * To read into a single data buffer use the @ref buffer function as follows:
333    * @code
334    * descriptor.async_read_some(boost::asio::buffer(data, size), handler);
335    * @endcode
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
338    * std::vector.
339    */
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)
345   {
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;
349
350     return this->get_service().async_read_some(this->get_implementation(),
351         buffers, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
352   }
353 };
354
355 } // namespace posix
356 } // namespace asio
357 } // namespace boost
358
359 #include <boost/asio/detail/pop_options.hpp>
360
361 #endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
362        //   || defined(GENERATING_DOCUMENTATION)
363
364 #endif // BOOST_ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP