PageRenderTime 55ms CodeModel.GetById 29ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/asio/ssl/old/stream.hpp

http://hadesmem.googlecode.com/
C++ Header | 503 lines | 168 code | 38 blank | 297 comment | 1 complexity | ce40e640b778921641a0e251c6dd204d MD5 | raw file
  1//
  2// ssl/old/stream.hpp
  3// ~~~~~~~~~~~~~~~~~~
  4//
  5// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
  6// Copyright (c) 2005-2011 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/type_traits/remove_reference.hpp>
 23#include <boost/asio/detail/throw_error.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
 31namespace boost {
 32namespace asio {
 33namespace ssl {
 34namespace 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 */
 56template <typename Stream, typename Service = old::stream_service>
 57class stream
 58  : public stream_base,
 59    private boost::noncopyable
 60{
 61public:
 62  /// The type of the next layer.
 63  typedef typename boost::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
485private:
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