Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / asio / ssl / old / stream.hpp
1 //
2 // ssl/old/stream.hpp
3 // ~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
6 // Copyright (c) 2005-2017 Christopher M. Kohlhoff (chris at kohlhoff dot 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
12 #ifndef BOOST_ASIO_SSL_OLD_STREAM_HPP
13 #define BOOST_ASIO_SSL_OLD_STREAM_HPP
14
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 # pragma once
17 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18
19 #include <boost/asio/detail/config.hpp>
20 #include <cstddef>
21 #include <boost/noncopyable.hpp>
22 #include <boost/asio/detail/throw_error.hpp>
23 #include <boost/asio/detail/type_traits.hpp>
24 #include <boost/asio/error.hpp>
25 #include <boost/asio/ssl/basic_context.hpp>
26 #include <boost/asio/ssl/stream_base.hpp>
27 #include <boost/asio/ssl/stream_service.hpp>
28
29 #include <boost/asio/detail/push_options.hpp>
30
31 namespace boost {
32 namespace asio {
33 namespace ssl {
34 namespace old {
35
36 /// Provides stream-oriented functionality using SSL.
37 /**
38  * The stream class template provides asynchronous and blocking stream-oriented
39  * functionality using SSL.
40  *
41  * @par Thread Safety
42  * @e Distinct @e objects: Safe.@n
43  * @e Shared @e objects: Unsafe.
44  *
45  * @par Example
46  * To use the SSL stream template with an ip::tcp::socket, you would write:
47  * @code
48  * boost::asio::io_service io_service;
49  * boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23);
50  * boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sock(io_service, context);
51  * @endcode
52  *
53  * @par Concepts:
54  * AsyncReadStream, AsyncWriteStream, Stream, SyncRead_Stream, SyncWriteStream.
55  */
56 template <typename Stream, typename Service = old::stream_service>
57 class stream
58   : public stream_base,
59     private boost::noncopyable
60 {
61 public:
62   /// The type of the next layer.
63   typedef typename remove_reference<Stream>::type next_layer_type;
64
65   /// The type of the lowest layer.
66   typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
67
68   /// The type of the service that will be used to provide stream operations.
69   typedef Service service_type;
70
71   /// The native implementation type of the stream.
72   typedef typename service_type::impl_type impl_type;
73
74   /// Construct a stream.
75   /**
76    * This constructor creates a stream and initialises the underlying stream
77    * object.
78    *
79    * @param arg The argument to be passed to initialise the underlying stream.
80    *
81    * @param context The SSL context to be used for the stream.
82    */
83   template <typename Arg, typename Context_Service>
84   explicit stream(Arg& arg, basic_context<Context_Service>& context)
85     : next_layer_(arg),
86       service_(boost::asio::use_service<Service>(next_layer_.get_io_service())),
87       impl_(service_.null())
88   {
89     service_.create(impl_, next_layer_, context);
90   }
91
92   /// Destructor.
93   ~stream()
94   {
95     service_.destroy(impl_, next_layer_);
96   }
97
98   /// Get the io_service associated with the object.
99   /**
100    * This function may be used to obtain the io_service object that the stream
101    * uses to dispatch handlers for asynchronous operations.
102    *
103    * @return A reference to the io_service object that stream will use to
104    * dispatch handlers. Ownership is not transferred to the caller.
105    */
106   boost::asio::io_service& get_io_service()
107   {
108     return next_layer_.get_io_service();
109   }
110
111   /// Get a reference to the next layer.
112   /**
113    * This function returns a reference to the next layer in a stack of stream
114    * layers.
115    *
116    * @return A reference to the next layer in the stack of stream layers.
117    * Ownership is not transferred to the caller.
118    */
119   next_layer_type& next_layer()
120   {
121     return next_layer_;
122   }
123
124   /// Get a reference to the lowest layer.
125   /**
126    * This function returns a reference to the lowest layer in a stack of
127    * stream layers.
128    *
129    * @return A reference to the lowest layer in the stack of stream layers.
130    * Ownership is not transferred to the caller.
131    */
132   lowest_layer_type& lowest_layer()
133   {
134     return next_layer_.lowest_layer();
135   }
136
137   /// Get a const reference to the lowest layer.
138   /**
139    * This function returns a const reference to the lowest layer in a stack of
140    * stream layers.
141    *
142    * @return A const reference to the lowest layer in the stack of stream
143    * layers. Ownership is not transferred to the caller.
144    */
145   const lowest_layer_type& lowest_layer() const
146   {
147     return next_layer_.lowest_layer();
148   }
149
150   /// Get the underlying implementation in the native type.
151   /**
152    * This function may be used to obtain the underlying implementation of the
153    * context. This is intended to allow access to stream functionality that is
154    * not otherwise provided.
155    */
156   impl_type impl()
157   {
158     return impl_;
159   }
160
161   /// Perform SSL handshaking.
162   /**
163    * This function is used to perform SSL handshaking on the stream. The
164    * function call will block until handshaking is complete or an error occurs.
165    *
166    * @param type The type of handshaking to be performed, i.e. as a client or as
167    * a server.
168    *
169    * @throws boost::system::system_error Thrown on failure.
170    */
171   void handshake(handshake_type type)
172   {
173     boost::system::error_code ec;
174     service_.handshake(impl_, next_layer_, type, ec);
175     boost::asio::detail::throw_error(ec);
176   }
177
178   /// Perform SSL handshaking.
179   /**
180    * This function is used to perform SSL handshaking on the stream. The
181    * function call will block until handshaking is complete or an error occurs.
182    *
183    * @param type The type of handshaking to be performed, i.e. as a client or as
184    * a server.
185    *
186    * @param ec Set to indicate what error occurred, if any.
187    */
188   boost::system::error_code handshake(handshake_type type,
189       boost::system::error_code& ec)
190   {
191     return service_.handshake(impl_, next_layer_, type, ec);
192   }
193
194   /// Start an asynchronous SSL handshake.
195   /**
196    * This function is used to asynchronously perform an SSL handshake on the
197    * stream. This function call always returns immediately.
198    *
199    * @param type The type of handshaking to be performed, i.e. as a client or as
200    * a server.
201    *
202    * @param handler The handler to be called when the handshake operation
203    * completes. Copies will be made of the handler as required. The equivalent
204    * function signature of the handler must be:
205    * @code void handler(
206    *   const boost::system::error_code& error // Result of operation.
207    * ); @endcode
208    */
209   template <typename HandshakeHandler>
210   void async_handshake(handshake_type type, HandshakeHandler handler)
211   {
212     service_.async_handshake(impl_, next_layer_, type, handler);
213   }
214
215   /// Shut down SSL on the stream.
216   /**
217    * This function is used to shut down SSL on the stream. The function call
218    * will block until SSL has been shut down or an error occurs.
219    *
220    * @throws boost::system::system_error Thrown on failure.
221    */
222   void shutdown()
223   {
224     boost::system::error_code ec;
225     service_.shutdown(impl_, next_layer_, ec);
226     boost::asio::detail::throw_error(ec);
227   }
228
229   /// Shut down SSL on the stream.
230   /**
231    * This function is used to shut down SSL on the stream. The function call
232    * will block until SSL has been shut down or an error occurs.
233    *
234    * @param ec Set to indicate what error occurred, if any.
235    */
236   boost::system::error_code shutdown(boost::system::error_code& ec)
237   {
238     return service_.shutdown(impl_, next_layer_, ec);
239   }
240
241   /// Asynchronously shut down SSL on the stream.
242   /**
243    * This function is used to asynchronously shut down SSL on the stream. This
244    * function call always returns immediately.
245    *
246    * @param handler The handler to be called when the handshake operation
247    * completes. Copies will be made of the handler as required. The equivalent
248    * function signature of the handler must be:
249    * @code void handler(
250    *   const boost::system::error_code& error // Result of operation.
251    * ); @endcode
252    */
253   template <typename ShutdownHandler>
254   void async_shutdown(ShutdownHandler handler)
255   {
256     service_.async_shutdown(impl_, next_layer_, handler);
257   }
258
259   /// Write some data to the stream.
260   /**
261    * This function is used to write data on the stream. The function call will
262    * block until one or more bytes of data has been written successfully, or
263    * until an error occurs.
264    *
265    * @param buffers The data to be written.
266    *
267    * @returns The number of bytes written.
268    *
269    * @throws boost::system::system_error Thrown on failure.
270    *
271    * @note The write_some operation may not transmit all of the data to the
272    * peer. Consider using the @ref write function if you need to ensure that all
273    * data is written before the blocking operation completes.
274    */
275   template <typename ConstBufferSequence>
276   std::size_t write_some(const ConstBufferSequence& buffers)
277   {
278     boost::system::error_code ec;
279     std::size_t s = service_.write_some(impl_, next_layer_, buffers, ec);
280     boost::asio::detail::throw_error(ec);
281     return s;
282   }
283
284   /// Write some data to the stream.
285   /**
286    * This function is used to write data on the stream. The function call will
287    * block until one or more bytes of data has been written successfully, or
288    * until an error occurs.
289    *
290    * @param buffers The data to be written to the stream.
291    *
292    * @param ec Set to indicate what error occurred, if any.
293    *
294    * @returns The number of bytes written. Returns 0 if an error occurred.
295    *
296    * @note The write_some operation may not transmit all of the data to the
297    * peer. Consider using the @ref write function if you need to ensure that all
298    * data is written before the blocking operation completes.
299    */
300   template <typename ConstBufferSequence>
301   std::size_t write_some(const ConstBufferSequence& buffers,
302       boost::system::error_code& ec)
303   {
304     return service_.write_some(impl_, next_layer_, buffers, ec);
305   }
306
307   /// Start an asynchronous write.
308   /**
309    * This function is used to asynchronously write one or more bytes of data to
310    * the stream. The function call always returns immediately.
311    *
312    * @param buffers The data to be written to the stream. Although the buffers
313    * object may be copied as necessary, ownership of the underlying buffers is
314    * retained by the caller, which must guarantee that they remain valid until
315    * the handler is called.
316    *
317    * @param handler The handler to be called when the write operation completes.
318    * Copies will be made of the handler as required. The equivalent function
319    * signature of the handler must be:
320    * @code void handler(
321    *   const boost::system::error_code& error, // Result of operation.
322    *   std::size_t bytes_transferred           // Number of bytes written.
323    * ); @endcode
324    *
325    * @note The async_write_some operation may not transmit all of the data to
326    * the peer. Consider using the @ref async_write function if you need to
327    * ensure that all data is written before the blocking operation completes.
328    */
329   template <typename ConstBufferSequence, typename WriteHandler>
330   void async_write_some(const ConstBufferSequence& buffers,
331       WriteHandler handler)
332   {
333     service_.async_write_some(impl_, next_layer_, buffers, handler);
334   }
335
336   /// Read some data from the stream.
337   /**
338    * This function is used to read data from the stream. The function call will
339    * block until one or more bytes of data has been read successfully, or until
340    * an error occurs.
341    *
342    * @param buffers The buffers into which the data will be read.
343    *
344    * @returns The number of bytes read.
345    *
346    * @throws boost::system::system_error Thrown on failure.
347    *
348    * @note The read_some operation may not read all of the requested number of
349    * bytes. Consider using the @ref read function if you need to ensure that the
350    * requested amount of data is read before the blocking operation completes.
351    */
352   template <typename MutableBufferSequence>
353   std::size_t read_some(const MutableBufferSequence& buffers)
354   {
355     boost::system::error_code ec;
356     std::size_t s = service_.read_some(impl_, next_layer_, buffers, ec);
357     boost::asio::detail::throw_error(ec);
358     return s;
359   }
360
361   /// Read some data from the stream.
362   /**
363    * This function is used to read data from the stream. The function call will
364    * block until one or more bytes of data has been read successfully, or until
365    * an error occurs.
366    *
367    * @param buffers The buffers into which the data will be read.
368    *
369    * @param ec Set to indicate what error occurred, if any.
370    *
371    * @returns The number of bytes read. Returns 0 if an error occurred.
372    *
373    * @note The read_some operation may not read all of the requested number of
374    * bytes. Consider using the @ref read function if you need to ensure that the
375    * requested amount of data is read before the blocking operation completes.
376    */
377   template <typename MutableBufferSequence>
378   std::size_t read_some(const MutableBufferSequence& buffers,
379       boost::system::error_code& ec)
380   {
381     return service_.read_some(impl_, next_layer_, buffers, ec);
382   }
383
384   /// Start an asynchronous read.
385   /**
386    * This function is used to asynchronously read one or more bytes of data from
387    * the stream. The function call always returns immediately.
388    *
389    * @param buffers The buffers into which the data will be read. Although the
390    * buffers object may be copied as necessary, ownership of the underlying
391    * buffers is retained by the caller, which must guarantee that they remain
392    * valid until the handler is called.
393    *
394    * @param handler The handler to be called when the read operation completes.
395    * Copies will be made of the handler as required. The equivalent function
396    * signature of the handler must be:
397    * @code void handler(
398    *   const boost::system::error_code& error, // Result of operation.
399    *   std::size_t bytes_transferred           // Number of bytes read.
400    * ); @endcode
401    *
402    * @note The async_read_some operation may not read all of the requested
403    * number of bytes. Consider using the @ref async_read function if you need to
404    * ensure that the requested amount of data is read before the asynchronous
405    * operation completes.
406    */
407   template <typename MutableBufferSequence, typename ReadHandler>
408   void async_read_some(const MutableBufferSequence& buffers,
409       ReadHandler handler)
410   {
411     service_.async_read_some(impl_, next_layer_, buffers, handler);
412   }
413
414   /// Peek at the incoming data on the stream.
415   /**
416    * This function is used to peek at the incoming data on the stream, without
417    * removing it from the input queue. The function call will block until data
418    * has been read successfully or an error occurs.
419    *
420    * @param buffers The buffers into which the data will be read.
421    *
422    * @returns The number of bytes read.
423    *
424    * @throws boost::system::system_error Thrown on failure.
425    */
426   template <typename MutableBufferSequence>
427   std::size_t peek(const MutableBufferSequence& buffers)
428   {
429     boost::system::error_code ec;
430     std::size_t s = service_.peek(impl_, next_layer_, buffers, ec);
431     boost::asio::detail::throw_error(ec);
432     return s;
433   }
434
435   /// Peek at the incoming data on the stream.
436   /**
437    * This function is used to peek at the incoming data on the stream, withoutxi
438    * removing it from the input queue. The function call will block until data
439    * has been read successfully or an error occurs.
440    *
441    * @param buffers The buffers into which the data will be read.
442    *
443    * @param ec Set to indicate what error occurred, if any.
444    *
445    * @returns The number of bytes read. Returns 0 if an error occurred.
446    */
447   template <typename MutableBufferSequence>
448   std::size_t peek(const MutableBufferSequence& buffers,
449       boost::system::error_code& ec)
450   {
451     return service_.peek(impl_, next_layer_, buffers, ec);
452   }
453
454   /// Determine the amount of data that may be read without blocking.
455   /**
456    * This function is used to determine the amount of data, in bytes, that may
457    * be read from the stream without blocking.
458    *
459    * @returns The number of bytes of data that can be read without blocking.
460    *
461    * @throws boost::system::system_error Thrown on failure.
462    */
463   std::size_t in_avail()
464   {
465     boost::system::error_code ec;
466     std::size_t s = service_.in_avail(impl_, next_layer_, ec);
467     boost::asio::detail::throw_error(ec);
468     return s;
469   }
470
471   /// Determine the amount of data that may be read without blocking.
472   /**
473    * This function is used to determine the amount of data, in bytes, that may
474    * be read from the stream without blocking.
475    *
476    * @param ec Set to indicate what error occurred, if any.
477    *
478    * @returns The number of bytes of data that can be read without blocking.
479    */
480   std::size_t in_avail(boost::system::error_code& ec)
481   {
482     return service_.in_avail(impl_, next_layer_, ec);
483   }
484
485 private:
486   /// The next layer.
487   Stream next_layer_;
488
489   /// The backend service implementation.
490   service_type& service_;
491
492   /// The underlying native implementation.
493   impl_type impl_;
494 };
495
496 } // namespace old
497 } // namespace ssl
498 } // namespace asio
499 } // namespace boost
500
501 #include <boost/asio/detail/pop_options.hpp>
502
503 #endif // BOOST_ASIO_SSL_OLD_STREAM_HPP