5 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_WRITE_IPP
12 #define BOOST_ASIO_WRITE_IPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/push_options.hpp>
20 #include <boost/asio/buffer.hpp>
21 #include <boost/asio/completion_condition.hpp>
22 #include <boost/asio/detail/bind_handler.hpp>
23 #include <boost/asio/detail/consuming_buffers.hpp>
24 #include <boost/asio/detail/handler_alloc_helpers.hpp>
25 #include <boost/asio/detail/handler_invoke_helpers.hpp>
26 #include <boost/asio/detail/throw_error.hpp>
31 template <typename SyncWriteStream, typename ConstBufferSequence,
32 typename CompletionCondition>
33 std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
34 CompletionCondition completion_condition, boost::system::error_code& ec)
36 ec = boost::system::error_code();
37 boost::asio::detail::consuming_buffers<
38 const_buffer, ConstBufferSequence> tmp(buffers);
39 std::size_t total_transferred = 0;
40 tmp.set_max_size(detail::adapt_completion_condition_result(
41 completion_condition(ec, total_transferred)));
42 while (tmp.begin() != tmp.end())
44 std::size_t bytes_transferred = s.write_some(tmp, ec);
45 tmp.consume(bytes_transferred);
46 total_transferred += bytes_transferred;
47 tmp.set_max_size(detail::adapt_completion_condition_result(
48 completion_condition(ec, total_transferred)));
50 return total_transferred;
53 template <typename SyncWriteStream, typename ConstBufferSequence>
54 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers)
56 boost::system::error_code ec;
57 std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);
58 boost::asio::detail::throw_error(ec);
59 return bytes_transferred;
62 template <typename SyncWriteStream, typename ConstBufferSequence,
63 typename CompletionCondition>
64 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
65 CompletionCondition completion_condition)
67 boost::system::error_code ec;
68 std::size_t bytes_transferred = write(s, buffers, completion_condition, ec);
69 boost::asio::detail::throw_error(ec);
70 return bytes_transferred;
73 template <typename SyncWriteStream, typename Allocator,
74 typename CompletionCondition>
75 std::size_t write(SyncWriteStream& s,
76 boost::asio::basic_streambuf<Allocator>& b,
77 CompletionCondition completion_condition, boost::system::error_code& ec)
79 std::size_t bytes_transferred = write(s, b.data(), completion_condition, ec);
80 b.consume(bytes_transferred);
81 return bytes_transferred;
84 template <typename SyncWriteStream, typename Allocator>
85 inline std::size_t write(SyncWriteStream& s,
86 boost::asio::basic_streambuf<Allocator>& b)
88 boost::system::error_code ec;
89 std::size_t bytes_transferred = write(s, b, transfer_all(), ec);
90 boost::asio::detail::throw_error(ec);
91 return bytes_transferred;
94 template <typename SyncWriteStream, typename Allocator,
95 typename CompletionCondition>
96 inline std::size_t write(SyncWriteStream& s,
97 boost::asio::basic_streambuf<Allocator>& b,
98 CompletionCondition completion_condition)
100 boost::system::error_code ec;
101 std::size_t bytes_transferred = write(s, b, completion_condition, ec);
102 boost::asio::detail::throw_error(ec);
103 return bytes_transferred;
108 template <typename AsyncWriteStream, typename ConstBufferSequence,
109 typename CompletionCondition, typename WriteHandler>
113 typedef boost::asio::detail::consuming_buffers<
114 const_buffer, ConstBufferSequence> buffers_type;
116 write_handler(AsyncWriteStream& stream, const buffers_type& buffers,
117 CompletionCondition completion_condition, WriteHandler handler)
120 total_transferred_(0),
121 completion_condition_(completion_condition),
126 void operator()(const boost::system::error_code& ec,
127 std::size_t bytes_transferred)
129 total_transferred_ += bytes_transferred;
130 buffers_.consume(bytes_transferred);
131 buffers_.set_max_size(detail::adapt_completion_condition_result(
132 completion_condition_(ec, total_transferred_)));
133 if (buffers_.begin() == buffers_.end())
135 handler_(ec, total_transferred_);
139 stream_.async_write_some(buffers_, *this);
144 AsyncWriteStream& stream_;
145 buffers_type buffers_;
146 std::size_t total_transferred_;
147 CompletionCondition completion_condition_;
148 WriteHandler handler_;
151 template <typename AsyncWriteStream, typename ConstBufferSequence,
152 typename CompletionCondition, typename WriteHandler>
153 inline void* asio_handler_allocate(std::size_t size,
154 write_handler<AsyncWriteStream, ConstBufferSequence,
155 CompletionCondition, WriteHandler>* this_handler)
157 return boost_asio_handler_alloc_helpers::allocate(
158 size, &this_handler->handler_);
161 template <typename AsyncWriteStream, typename ConstBufferSequence,
162 typename CompletionCondition, typename WriteHandler>
163 inline void asio_handler_deallocate(void* pointer, std::size_t size,
164 write_handler<AsyncWriteStream, ConstBufferSequence,
165 CompletionCondition, WriteHandler>* this_handler)
167 boost_asio_handler_alloc_helpers::deallocate(
168 pointer, size, &this_handler->handler_);
171 template <typename Function, typename AsyncWriteStream,
172 typename ConstBufferSequence, typename CompletionCondition,
173 typename WriteHandler>
174 inline void asio_handler_invoke(const Function& function,
175 write_handler<AsyncWriteStream, ConstBufferSequence,
176 CompletionCondition, WriteHandler>* this_handler)
178 boost_asio_handler_invoke_helpers::invoke(
179 function, &this_handler->handler_);
181 } // namespace detail
183 template <typename AsyncWriteStream, typename ConstBufferSequence,
184 typename CompletionCondition, typename WriteHandler>
185 inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
186 CompletionCondition completion_condition, WriteHandler handler)
188 boost::asio::detail::consuming_buffers<
189 const_buffer, ConstBufferSequence> tmp(buffers);
191 boost::system::error_code ec;
192 std::size_t total_transferred = 0;
193 tmp.set_max_size(detail::adapt_completion_condition_result(
194 completion_condition(ec, total_transferred)));
195 if (tmp.begin() == tmp.end())
197 s.get_io_service().post(detail::bind_handler(
198 handler, ec, total_transferred));
202 s.async_write_some(tmp,
203 detail::write_handler<AsyncWriteStream, ConstBufferSequence,
204 CompletionCondition, WriteHandler>(
205 s, tmp, completion_condition, handler));
208 template <typename AsyncWriteStream, typename ConstBufferSequence,
209 typename WriteHandler>
210 inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
211 WriteHandler handler)
213 async_write(s, buffers, transfer_all(), handler);
218 template <typename AsyncWriteStream, typename Allocator,
219 typename WriteHandler>
220 class write_streambuf_handler
223 write_streambuf_handler(boost::asio::basic_streambuf<Allocator>& streambuf,
224 WriteHandler handler)
225 : streambuf_(streambuf),
230 void operator()(const boost::system::error_code& ec,
231 std::size_t bytes_transferred)
233 streambuf_.consume(bytes_transferred);
234 handler_(ec, bytes_transferred);
238 boost::asio::basic_streambuf<Allocator>& streambuf_;
239 WriteHandler handler_;
242 template <typename AsyncWriteStream, typename Allocator,
243 typename WriteHandler>
244 inline void* asio_handler_allocate(std::size_t size,
245 write_streambuf_handler<AsyncWriteStream,
246 Allocator, WriteHandler>* this_handler)
248 return boost_asio_handler_alloc_helpers::allocate(
249 size, &this_handler->handler_);
252 template <typename AsyncWriteStream, typename Allocator,
253 typename WriteHandler>
254 inline void asio_handler_deallocate(void* pointer, std::size_t size,
255 write_streambuf_handler<AsyncWriteStream,
256 Allocator, WriteHandler>* this_handler)
258 boost_asio_handler_alloc_helpers::deallocate(
259 pointer, size, &this_handler->handler_);
262 template <typename Function, typename AsyncWriteStream, typename Allocator,
263 typename WriteHandler>
264 inline void asio_handler_invoke(const Function& function,
265 write_streambuf_handler<AsyncWriteStream,
266 Allocator, WriteHandler>* this_handler)
268 boost_asio_handler_invoke_helpers::invoke(
269 function, &this_handler->handler_);
271 } // namespace detail
273 template <typename AsyncWriteStream, typename Allocator,
274 typename CompletionCondition, typename WriteHandler>
275 inline void async_write(AsyncWriteStream& s,
276 boost::asio::basic_streambuf<Allocator>& b,
277 CompletionCondition completion_condition, WriteHandler handler)
279 async_write(s, b.data(), completion_condition,
280 detail::write_streambuf_handler<
281 AsyncWriteStream, Allocator, WriteHandler>(b, handler));
284 template <typename AsyncWriteStream, typename Allocator, typename WriteHandler>
285 inline void async_write(AsyncWriteStream& s,
286 boost::asio::basic_streambuf<Allocator>& b, WriteHandler handler)
288 async_write(s, b, transfer_all(), handler);
294 #include <boost/asio/detail/pop_options.hpp>
296 #endif // BOOST_ASIO_WRITE_IPP