Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:08

0001 //
0002 // buffered_stream.hpp
0003 // ~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_BUFFERED_STREAM_HPP
0012 #define BOOST_ASIO_BUFFERED_STREAM_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 #include <cstddef>
0020 #include <boost/asio/async_result.hpp>
0021 #include <boost/asio/buffered_read_stream.hpp>
0022 #include <boost/asio/buffered_write_stream.hpp>
0023 #include <boost/asio/buffered_stream_fwd.hpp>
0024 #include <boost/asio/detail/noncopyable.hpp>
0025 #include <boost/asio/error.hpp>
0026 
0027 #include <boost/asio/detail/push_options.hpp>
0028 
0029 namespace boost {
0030 namespace asio {
0031 
0032 /// Adds buffering to the read- and write-related operations of a stream.
0033 /**
0034  * The buffered_stream class template can be used to add buffering to the
0035  * synchronous and asynchronous read and write operations of a stream.
0036  *
0037  * @par Thread Safety
0038  * @e Distinct @e objects: Safe.@n
0039  * @e Shared @e objects: Unsafe.
0040  *
0041  * @par Concepts:
0042  * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
0043  */
0044 template <typename Stream>
0045 class buffered_stream
0046   : private noncopyable
0047 {
0048 public:
0049   /// The type of the next layer.
0050   typedef remove_reference_t<Stream> next_layer_type;
0051 
0052   /// The type of the lowest layer.
0053   typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
0054 
0055   /// The type of the executor associated with the object.
0056   typedef typename lowest_layer_type::executor_type executor_type;
0057 
0058   /// Construct, passing the specified argument to initialise the next layer.
0059   template <typename Arg>
0060   explicit buffered_stream(Arg&& a)
0061     : inner_stream_impl_(static_cast<Arg&&>(a)),
0062       stream_impl_(inner_stream_impl_)
0063   {
0064   }
0065 
0066   /// Construct, passing the specified argument to initialise the next layer.
0067   template <typename Arg>
0068   explicit buffered_stream(Arg&& a,
0069       std::size_t read_buffer_size, std::size_t write_buffer_size)
0070     : inner_stream_impl_(static_cast<Arg&&>(a), write_buffer_size),
0071       stream_impl_(inner_stream_impl_, read_buffer_size)
0072   {
0073   }
0074 
0075   /// Get a reference to the next layer.
0076   next_layer_type& next_layer()
0077   {
0078     return stream_impl_.next_layer().next_layer();
0079   }
0080 
0081   /// Get a reference to the lowest layer.
0082   lowest_layer_type& lowest_layer()
0083   {
0084     return stream_impl_.lowest_layer();
0085   }
0086 
0087   /// Get a const reference to the lowest layer.
0088   const lowest_layer_type& lowest_layer() const
0089   {
0090     return stream_impl_.lowest_layer();
0091   }
0092 
0093   /// Get the executor associated with the object.
0094   executor_type get_executor() noexcept
0095   {
0096     return stream_impl_.lowest_layer().get_executor();
0097   }
0098 
0099   /// Close the stream.
0100   void close()
0101   {
0102     stream_impl_.close();
0103   }
0104 
0105   /// Close the stream.
0106   BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
0107   {
0108     stream_impl_.close(ec);
0109     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0110   }
0111 
0112   /// Flush all data from the buffer to the next layer. Returns the number of
0113   /// bytes written to the next layer on the last write operation. Throws an
0114   /// exception on failure.
0115   std::size_t flush()
0116   {
0117     return stream_impl_.next_layer().flush();
0118   }
0119 
0120   /// Flush all data from the buffer to the next layer. Returns the number of
0121   /// bytes written to the next layer on the last write operation, or 0 if an
0122   /// error occurred.
0123   std::size_t flush(boost::system::error_code& ec)
0124   {
0125     return stream_impl_.next_layer().flush(ec);
0126   }
0127 
0128   /// Start an asynchronous flush.
0129   /**
0130    * @par Completion Signature
0131    * @code void(boost::system::error_code, std::size_t) @endcode
0132    */
0133   template <
0134       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0135         std::size_t)) WriteHandler = default_completion_token_t<executor_type>>
0136   auto async_flush(
0137       WriteHandler&& handler = default_completion_token_t<executor_type>())
0138     -> decltype(
0139       declval<buffered_write_stream<Stream>&>().async_flush(
0140         static_cast<WriteHandler&&>(handler)))
0141   {
0142     return stream_impl_.next_layer().async_flush(
0143         static_cast<WriteHandler&&>(handler));
0144   }
0145 
0146   /// Write the given data to the stream. Returns the number of bytes written.
0147   /// Throws an exception on failure.
0148   template <typename ConstBufferSequence>
0149   std::size_t write_some(const ConstBufferSequence& buffers)
0150   {
0151     return stream_impl_.write_some(buffers);
0152   }
0153 
0154   /// Write the given data to the stream. Returns the number of bytes written,
0155   /// or 0 if an error occurred.
0156   template <typename ConstBufferSequence>
0157   std::size_t write_some(const ConstBufferSequence& buffers,
0158       boost::system::error_code& ec)
0159   {
0160     return stream_impl_.write_some(buffers, ec);
0161   }
0162 
0163   /// Start an asynchronous write. The data being written must be valid for the
0164   /// lifetime of the asynchronous operation.
0165   /**
0166    * @par Completion Signature
0167    * @code void(boost::system::error_code, std::size_t) @endcode
0168    */
0169   template <typename ConstBufferSequence,
0170       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0171         std::size_t)) WriteHandler = default_completion_token_t<executor_type>>
0172   auto async_write_some(const ConstBufferSequence& buffers,
0173       WriteHandler&& handler = default_completion_token_t<executor_type>())
0174     -> decltype(
0175       declval<Stream&>().async_write_some(buffers,
0176         static_cast<WriteHandler&&>(handler)))
0177   {
0178     return stream_impl_.async_write_some(buffers,
0179         static_cast<WriteHandler&&>(handler));
0180   }
0181 
0182   /// Fill the buffer with some data. Returns the number of bytes placed in the
0183   /// buffer as a result of the operation. Throws an exception on failure.
0184   std::size_t fill()
0185   {
0186     return stream_impl_.fill();
0187   }
0188 
0189   /// Fill the buffer with some data. Returns the number of bytes placed in the
0190   /// buffer as a result of the operation, or 0 if an error occurred.
0191   std::size_t fill(boost::system::error_code& ec)
0192   {
0193     return stream_impl_.fill(ec);
0194   }
0195 
0196   /// Start an asynchronous fill.
0197   /**
0198    * @par Completion Signature
0199    * @code void(boost::system::error_code, std::size_t) @endcode
0200    */
0201   template <
0202       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0203         std::size_t)) ReadHandler = default_completion_token_t<executor_type>>
0204   auto async_fill(
0205       ReadHandler&& handler = default_completion_token_t<executor_type>())
0206     -> decltype(
0207       declval<buffered_read_stream<
0208         buffered_write_stream<Stream>>&>().async_fill(
0209           static_cast<ReadHandler&&>(handler)))
0210   {
0211     return stream_impl_.async_fill(static_cast<ReadHandler&&>(handler));
0212   }
0213 
0214   /// Read some data from the stream. Returns the number of bytes read. Throws
0215   /// an exception on failure.
0216   template <typename MutableBufferSequence>
0217   std::size_t read_some(const MutableBufferSequence& buffers)
0218   {
0219     return stream_impl_.read_some(buffers);
0220   }
0221 
0222   /// Read some data from the stream. Returns the number of bytes read or 0 if
0223   /// an error occurred.
0224   template <typename MutableBufferSequence>
0225   std::size_t read_some(const MutableBufferSequence& buffers,
0226       boost::system::error_code& ec)
0227   {
0228     return stream_impl_.read_some(buffers, ec);
0229   }
0230 
0231   /// Start an asynchronous read. The buffer into which the data will be read
0232   /// must be valid for the lifetime of the asynchronous operation.
0233   /**
0234    * @par Completion Signature
0235    * @code void(boost::system::error_code, std::size_t) @endcode
0236    */
0237   template <typename MutableBufferSequence,
0238       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0239         std::size_t)) ReadHandler = default_completion_token_t<executor_type>>
0240   auto async_read_some(const MutableBufferSequence& buffers,
0241       ReadHandler&& handler = default_completion_token_t<executor_type>())
0242     -> decltype(
0243       declval<Stream&>().async_read_some(buffers,
0244         static_cast<ReadHandler&&>(handler)))
0245   {
0246     return stream_impl_.async_read_some(buffers,
0247         static_cast<ReadHandler&&>(handler));
0248   }
0249 
0250   /// Peek at the incoming data on the stream. Returns the number of bytes read.
0251   /// Throws an exception on failure.
0252   template <typename MutableBufferSequence>
0253   std::size_t peek(const MutableBufferSequence& buffers)
0254   {
0255     return stream_impl_.peek(buffers);
0256   }
0257 
0258   /// Peek at the incoming data on the stream. Returns the number of bytes read,
0259   /// or 0 if an error occurred.
0260   template <typename MutableBufferSequence>
0261   std::size_t peek(const MutableBufferSequence& buffers,
0262       boost::system::error_code& ec)
0263   {
0264     return stream_impl_.peek(buffers, ec);
0265   }
0266 
0267   /// Determine the amount of data that may be read without blocking.
0268   std::size_t in_avail()
0269   {
0270     return stream_impl_.in_avail();
0271   }
0272 
0273   /// Determine the amount of data that may be read without blocking.
0274   std::size_t in_avail(boost::system::error_code& ec)
0275   {
0276     return stream_impl_.in_avail(ec);
0277   }
0278 
0279 private:
0280   // The buffered write stream.
0281   typedef buffered_write_stream<Stream> write_stream_type;
0282   write_stream_type inner_stream_impl_;
0283 
0284   // The buffered read stream.
0285   typedef buffered_read_stream<write_stream_type&> read_stream_type;
0286   read_stream_type stream_impl_;
0287 };
0288 
0289 } // namespace asio
0290 } // namespace boost
0291 
0292 #include <boost/asio/detail/pop_options.hpp>
0293 
0294 #endif // BOOST_ASIO_BUFFERED_STREAM_HPP