Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / asio / buffered_write_stream.hpp
1 //
2 // buffered_write_stream.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_BUFFERED_WRITE_STREAM_HPP
12 #define BOOST_ASIO_BUFFERED_WRITE_STREAM_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 #include <cstddef>
20 #include <boost/asio/buffered_write_stream_fwd.hpp>
21 #include <boost/asio/buffer.hpp>
22 #include <boost/asio/completion_condition.hpp>
23 #include <boost/asio/detail/bind_handler.hpp>
24 #include <boost/asio/detail/buffered_stream_storage.hpp>
25 #include <boost/asio/detail/noncopyable.hpp>
26 #include <boost/asio/detail/type_traits.hpp>
27 #include <boost/asio/error.hpp>
28 #include <boost/asio/io_service.hpp>
29 #include <boost/asio/write.hpp>
30
31 #include <boost/asio/detail/push_options.hpp>
32
33 namespace boost {
34 namespace asio {
35
36 /// Adds buffering to the write-related operations of a stream.
37 /**
38  * The buffered_write_stream class template can be used to add buffering to the
39  * synchronous and asynchronous write operations of a stream.
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 Stream>
49 class buffered_write_stream
50   : private noncopyable
51 {
52 public:
53   /// The type of the next layer.
54   typedef typename remove_reference<Stream>::type next_layer_type;
55
56   /// The type of the lowest layer.
57   typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
58
59 #if defined(GENERATING_DOCUMENTATION)
60   /// The default buffer size.
61   static const std::size_t default_buffer_size = implementation_defined;
62 #else
63   BOOST_ASIO_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024);
64 #endif
65
66   /// Construct, passing the specified argument to initialise the next layer.
67   template <typename Arg>
68   explicit buffered_write_stream(Arg& a)
69     : next_layer_(a),
70       storage_(default_buffer_size)
71   {
72   }
73
74   /// Construct, passing the specified argument to initialise the next layer.
75   template <typename Arg>
76   buffered_write_stream(Arg& a, std::size_t buffer_size)
77     : next_layer_(a),
78       storage_(buffer_size)
79   {
80   }
81
82   /// Get a reference to the next layer.
83   next_layer_type& next_layer()
84   {
85     return next_layer_;
86   }
87
88   /// Get a reference to the lowest layer.
89   lowest_layer_type& lowest_layer()
90   {
91     return next_layer_.lowest_layer();
92   }
93
94   /// Get a const reference to the lowest layer.
95   const lowest_layer_type& lowest_layer() const
96   {
97     return next_layer_.lowest_layer();
98   }
99
100   /// Get the io_service associated with the object.
101   boost::asio::io_service& get_io_service()
102   {
103     return next_layer_.get_io_service();
104   }
105
106   /// Close the stream.
107   void close()
108   {
109     next_layer_.close();
110   }
111
112   /// Close the stream.
113   boost::system::error_code close(boost::system::error_code& ec)
114   {
115     return next_layer_.close(ec);
116   }
117
118   /// Flush all data from the buffer to the next layer. Returns the number of
119   /// bytes written to the next layer on the last write operation. Throws an
120   /// exception on failure.
121   std::size_t flush();
122
123   /// Flush all data from the buffer to the next layer. Returns the number of
124   /// bytes written to the next layer on the last write operation, or 0 if an
125   /// error occurred.
126   std::size_t flush(boost::system::error_code& ec);
127
128   /// Start an asynchronous flush.
129   template <typename WriteHandler>
130   BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
131       void (boost::system::error_code, std::size_t))
132   async_flush(BOOST_ASIO_MOVE_ARG(WriteHandler) handler);
133
134   /// Write the given data to the stream. Returns the number of bytes written.
135   /// Throws an exception on failure.
136   template <typename ConstBufferSequence>
137   std::size_t write_some(const ConstBufferSequence& buffers);
138
139   /// Write the given data to the stream. Returns the number of bytes written,
140   /// or 0 if an error occurred and the error handler did not throw.
141   template <typename ConstBufferSequence>
142   std::size_t write_some(const ConstBufferSequence& buffers,
143       boost::system::error_code& ec);
144
145   /// Start an asynchronous write. The data being written must be valid for the
146   /// lifetime of the asynchronous operation.
147   template <typename ConstBufferSequence, typename WriteHandler>
148   BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
149       void (boost::system::error_code, std::size_t))
150   async_write_some(const ConstBufferSequence& buffers,
151       BOOST_ASIO_MOVE_ARG(WriteHandler) handler);
152
153   /// Read some data from the stream. Returns the number of bytes read. Throws
154   /// an exception on failure.
155   template <typename MutableBufferSequence>
156   std::size_t read_some(const MutableBufferSequence& buffers)
157   {
158     return next_layer_.read_some(buffers);
159   }
160
161   /// Read some data from the stream. Returns the number of bytes read or 0 if
162   /// an error occurred.
163   template <typename MutableBufferSequence>
164   std::size_t read_some(const MutableBufferSequence& buffers,
165       boost::system::error_code& ec)
166   {
167     return next_layer_.read_some(buffers, ec);
168   }
169
170   /// Start an asynchronous read. The buffer into which the data will be read
171   /// must be valid for the lifetime of the asynchronous operation.
172   template <typename MutableBufferSequence, typename ReadHandler>
173   BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
174       void (boost::system::error_code, std::size_t))
175   async_read_some(const MutableBufferSequence& buffers,
176       BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
177   {
178     detail::async_result_init<
179       ReadHandler, void (boost::system::error_code, std::size_t)> init(
180         BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
181
182     next_layer_.async_read_some(buffers,
183         BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(ReadHandler,
184             void (boost::system::error_code, std::size_t)))(init.handler));
185
186     return init.result.get();
187   }
188
189   /// Peek at the incoming data on the stream. Returns the number of bytes read.
190   /// Throws an exception on failure.
191   template <typename MutableBufferSequence>
192   std::size_t peek(const MutableBufferSequence& buffers)
193   {
194     return next_layer_.peek(buffers);
195   }
196
197   /// Peek at the incoming data on the stream. Returns the number of bytes read,
198   /// or 0 if an error occurred.
199   template <typename MutableBufferSequence>
200   std::size_t peek(const MutableBufferSequence& buffers,
201       boost::system::error_code& ec)
202   {
203     return next_layer_.peek(buffers, ec);
204   }
205
206   /// Determine the amount of data that may be read without blocking.
207   std::size_t in_avail()
208   {
209     return next_layer_.in_avail();
210   }
211
212   /// Determine the amount of data that may be read without blocking.
213   std::size_t in_avail(boost::system::error_code& ec)
214   {
215     return next_layer_.in_avail(ec);
216   }
217
218 private:
219   /// Copy data into the internal buffer from the specified source buffer.
220   /// Returns the number of bytes copied.
221   template <typename ConstBufferSequence>
222   std::size_t copy(const ConstBufferSequence& buffers);
223
224   /// The next layer.
225   Stream next_layer_;
226
227   // The data in the buffer.
228   detail::buffered_stream_storage storage_;
229 };
230
231 } // namespace asio
232 } // namespace boost
233
234 #include <boost/asio/detail/pop_options.hpp>
235
236 #include <boost/asio/impl/buffered_write_stream.hpp>
237
238 #endif // BOOST_ASIO_BUFFERED_WRITE_STREAM_HPP