5 // Copyright (c) 2003-2020 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_IMPL_WRITE_HPP
12 #define BOOST_ASIO_IMPL_WRITE_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/associated_allocator.hpp>
19 #include <boost/asio/associated_executor.hpp>
20 #include <boost/asio/buffer.hpp>
21 #include <boost/asio/completion_condition.hpp>
22 #include <boost/asio/detail/array_fwd.hpp>
23 #include <boost/asio/detail/base_from_completion_cond.hpp>
24 #include <boost/asio/detail/bind_handler.hpp>
25 #include <boost/asio/detail/consuming_buffers.hpp>
26 #include <boost/asio/detail/dependent_type.hpp>
27 #include <boost/asio/detail/handler_alloc_helpers.hpp>
28 #include <boost/asio/detail/handler_cont_helpers.hpp>
29 #include <boost/asio/detail/handler_invoke_helpers.hpp>
30 #include <boost/asio/detail/handler_tracking.hpp>
31 #include <boost/asio/detail/handler_type_requirements.hpp>
32 #include <boost/asio/detail/non_const_lvalue.hpp>
33 #include <boost/asio/detail/throw_error.hpp>
35 #include <boost/asio/detail/push_options.hpp>
42 template <typename SyncWriteStream, typename ConstBufferSequence,
43 typename ConstBufferIterator, typename CompletionCondition>
44 std::size_t write_buffer_sequence(SyncWriteStream& s,
45 const ConstBufferSequence& buffers, const ConstBufferIterator&,
46 CompletionCondition completion_condition, boost::system::error_code& ec)
48 ec = boost::system::error_code();
49 boost::asio::detail::consuming_buffers<const_buffer,
50 ConstBufferSequence, ConstBufferIterator> tmp(buffers);
53 if (std::size_t max_size = detail::adapt_completion_condition_result(
54 completion_condition(ec, tmp.total_consumed())))
55 tmp.consume(s.write_some(tmp.prepare(max_size), ec));
59 return tmp.total_consumed();
63 template <typename SyncWriteStream, typename ConstBufferSequence,
64 typename CompletionCondition>
65 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
66 CompletionCondition completion_condition, boost::system::error_code& ec,
68 is_const_buffer_sequence<ConstBufferSequence>::value
71 return detail::write_buffer_sequence(s, buffers,
72 boost::asio::buffer_sequence_begin(buffers),
73 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
76 template <typename SyncWriteStream, typename ConstBufferSequence>
77 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
79 is_const_buffer_sequence<ConstBufferSequence>::value
82 boost::system::error_code ec;
83 std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);
84 boost::asio::detail::throw_error(ec, "write");
85 return bytes_transferred;
88 template <typename SyncWriteStream, typename ConstBufferSequence>
89 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
90 boost::system::error_code& ec,
92 is_const_buffer_sequence<ConstBufferSequence>::value
95 return write(s, buffers, transfer_all(), ec);
98 template <typename SyncWriteStream, typename ConstBufferSequence,
99 typename CompletionCondition>
100 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
101 CompletionCondition completion_condition,
103 is_const_buffer_sequence<ConstBufferSequence>::value
106 boost::system::error_code ec;
107 std::size_t bytes_transferred = write(s, buffers,
108 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
109 boost::asio::detail::throw_error(ec, "write");
110 return bytes_transferred;
113 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
115 template <typename SyncWriteStream, typename DynamicBuffer_v1,
116 typename CompletionCondition>
117 std::size_t write(SyncWriteStream& s,
118 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
119 CompletionCondition completion_condition, boost::system::error_code& ec,
121 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
122 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
125 typename decay<DynamicBuffer_v1>::type b(
126 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));
128 std::size_t bytes_transferred = write(s, b.data(),
129 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
130 b.consume(bytes_transferred);
131 return bytes_transferred;
134 template <typename SyncWriteStream, typename DynamicBuffer_v1>
135 inline std::size_t write(SyncWriteStream& s,
136 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
138 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
139 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
142 boost::system::error_code ec;
143 std::size_t bytes_transferred = write(s,
144 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
146 boost::asio::detail::throw_error(ec, "write");
147 return bytes_transferred;
150 template <typename SyncWriteStream, typename DynamicBuffer_v1>
151 inline std::size_t write(SyncWriteStream& s,
152 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
153 boost::system::error_code& ec,
155 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
156 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
159 return write(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
163 template <typename SyncWriteStream, typename DynamicBuffer_v1,
164 typename CompletionCondition>
165 inline std::size_t write(SyncWriteStream& s,
166 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
167 CompletionCondition completion_condition,
169 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
170 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
173 boost::system::error_code ec;
174 std::size_t bytes_transferred = write(s,
175 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
176 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
177 boost::asio::detail::throw_error(ec, "write");
178 return bytes_transferred;
181 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
182 #if !defined(BOOST_ASIO_NO_IOSTREAM)
184 template <typename SyncWriteStream, typename Allocator,
185 typename CompletionCondition>
186 inline std::size_t write(SyncWriteStream& s,
187 boost::asio::basic_streambuf<Allocator>& b,
188 CompletionCondition completion_condition, boost::system::error_code& ec)
190 return write(s, basic_streambuf_ref<Allocator>(b),
191 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
194 template <typename SyncWriteStream, typename Allocator>
195 inline std::size_t write(SyncWriteStream& s,
196 boost::asio::basic_streambuf<Allocator>& b)
198 return write(s, basic_streambuf_ref<Allocator>(b));
201 template <typename SyncWriteStream, typename Allocator>
202 inline std::size_t write(SyncWriteStream& s,
203 boost::asio::basic_streambuf<Allocator>& b,
204 boost::system::error_code& ec)
206 return write(s, basic_streambuf_ref<Allocator>(b), ec);
209 template <typename SyncWriteStream, typename Allocator,
210 typename CompletionCondition>
211 inline std::size_t write(SyncWriteStream& s,
212 boost::asio::basic_streambuf<Allocator>& b,
213 CompletionCondition completion_condition)
215 return write(s, basic_streambuf_ref<Allocator>(b),
216 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
219 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
220 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
221 #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
223 template <typename SyncWriteStream, typename DynamicBuffer_v2,
224 typename CompletionCondition>
225 std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
226 CompletionCondition completion_condition, boost::system::error_code& ec,
228 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
231 std::size_t bytes_transferred = write(s, buffers.data(0, buffers.size()),
232 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
233 buffers.consume(bytes_transferred);
234 return bytes_transferred;
237 template <typename SyncWriteStream, typename DynamicBuffer_v2>
238 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
240 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
243 boost::system::error_code ec;
244 std::size_t bytes_transferred = write(s,
245 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
247 boost::asio::detail::throw_error(ec, "write");
248 return bytes_transferred;
251 template <typename SyncWriteStream, typename DynamicBuffer_v2>
252 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
253 boost::system::error_code& ec,
255 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
258 return write(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
262 template <typename SyncWriteStream, typename DynamicBuffer_v2,
263 typename CompletionCondition>
264 inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
265 CompletionCondition completion_condition,
267 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
270 boost::system::error_code ec;
271 std::size_t bytes_transferred = write(s,
272 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
273 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
274 boost::asio::detail::throw_error(ec, "write");
275 return bytes_transferred;
280 template <typename AsyncWriteStream, typename ConstBufferSequence,
281 typename ConstBufferIterator, typename CompletionCondition,
282 typename WriteHandler>
284 : detail::base_from_completion_cond<CompletionCondition>
287 write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers,
288 CompletionCondition& completion_condition, WriteHandler& handler)
289 : detail::base_from_completion_cond<
290 CompletionCondition>(completion_condition),
294 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
298 #if defined(BOOST_ASIO_HAS_MOVE)
299 write_op(const write_op& other)
300 : detail::base_from_completion_cond<CompletionCondition>(other),
301 stream_(other.stream_),
302 buffers_(other.buffers_),
303 start_(other.start_),
304 handler_(other.handler_)
308 write_op(write_op&& other)
309 : detail::base_from_completion_cond<CompletionCondition>(
310 BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
311 CompletionCondition>)(other)),
312 stream_(other.stream_),
313 buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)),
314 start_(other.start_),
315 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
318 #endif // defined(BOOST_ASIO_HAS_MOVE)
320 void operator()(const boost::system::error_code& ec,
321 std::size_t bytes_transferred, int start = 0)
323 std::size_t max_size;
324 switch (start_ = start)
327 max_size = this->check_for_completion(ec, buffers_.total_consumed());
331 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_write"));
332 stream_.async_write_some(buffers_.prepare(max_size),
333 BOOST_ASIO_MOVE_CAST(write_op)(*this));
336 buffers_.consume(bytes_transferred);
337 if ((!ec && bytes_transferred == 0) || buffers_.empty())
339 max_size = this->check_for_completion(ec, buffers_.total_consumed());
340 } while (max_size > 0);
342 handler_(ec, buffers_.total_consumed());
347 typedef boost::asio::detail::consuming_buffers<const_buffer,
348 ConstBufferSequence, ConstBufferIterator> buffers_type;
350 AsyncWriteStream& stream_;
351 buffers_type buffers_;
353 WriteHandler handler_;
356 template <typename AsyncWriteStream, typename ConstBufferSequence,
357 typename ConstBufferIterator, typename CompletionCondition,
358 typename WriteHandler>
359 inline asio_handler_allocate_is_deprecated
360 asio_handler_allocate(std::size_t size,
361 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
362 CompletionCondition, WriteHandler>* this_handler)
364 #if defined(BOOST_ASIO_NO_DEPRECATED)
365 boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
366 return asio_handler_allocate_is_no_longer_used();
367 #else // defined(BOOST_ASIO_NO_DEPRECATED)
368 return boost_asio_handler_alloc_helpers::allocate(
369 size, this_handler->handler_);
370 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
373 template <typename AsyncWriteStream, typename ConstBufferSequence,
374 typename ConstBufferIterator, typename CompletionCondition,
375 typename WriteHandler>
376 inline asio_handler_deallocate_is_deprecated
377 asio_handler_deallocate(void* pointer, std::size_t size,
378 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
379 CompletionCondition, WriteHandler>* this_handler)
381 boost_asio_handler_alloc_helpers::deallocate(
382 pointer, size, this_handler->handler_);
383 #if defined(BOOST_ASIO_NO_DEPRECATED)
384 return asio_handler_deallocate_is_no_longer_used();
385 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
388 template <typename AsyncWriteStream, typename ConstBufferSequence,
389 typename ConstBufferIterator, typename CompletionCondition,
390 typename WriteHandler>
391 inline bool asio_handler_is_continuation(
392 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
393 CompletionCondition, WriteHandler>* this_handler)
395 return this_handler->start_ == 0 ? true
396 : boost_asio_handler_cont_helpers::is_continuation(
397 this_handler->handler_);
400 template <typename Function, typename AsyncWriteStream,
401 typename ConstBufferSequence, typename ConstBufferIterator,
402 typename CompletionCondition, typename WriteHandler>
403 inline asio_handler_invoke_is_deprecated
404 asio_handler_invoke(Function& function,
405 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
406 CompletionCondition, WriteHandler>* this_handler)
408 boost_asio_handler_invoke_helpers::invoke(
409 function, this_handler->handler_);
410 #if defined(BOOST_ASIO_NO_DEPRECATED)
411 return asio_handler_invoke_is_no_longer_used();
412 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
415 template <typename Function, typename AsyncWriteStream,
416 typename ConstBufferSequence, typename ConstBufferIterator,
417 typename CompletionCondition, typename WriteHandler>
418 inline asio_handler_invoke_is_deprecated
419 asio_handler_invoke(const Function& function,
420 write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,
421 CompletionCondition, WriteHandler>* this_handler)
423 boost_asio_handler_invoke_helpers::invoke(
424 function, this_handler->handler_);
425 #if defined(BOOST_ASIO_NO_DEPRECATED)
426 return asio_handler_invoke_is_no_longer_used();
427 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
430 template <typename AsyncWriteStream, typename ConstBufferSequence,
431 typename ConstBufferIterator, typename CompletionCondition,
432 typename WriteHandler>
433 inline void start_write_buffer_sequence_op(AsyncWriteStream& stream,
434 const ConstBufferSequence& buffers, const ConstBufferIterator&,
435 CompletionCondition& completion_condition, WriteHandler& handler)
437 detail::write_op<AsyncWriteStream, ConstBufferSequence,
438 ConstBufferIterator, CompletionCondition, WriteHandler>(
439 stream, buffers, completion_condition, handler)(
440 boost::system::error_code(), 0, 1);
443 template <typename AsyncWriteStream>
444 class initiate_async_write_buffer_sequence
447 typedef typename AsyncWriteStream::executor_type executor_type;
449 explicit initiate_async_write_buffer_sequence(AsyncWriteStream& stream)
454 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
456 return stream_.get_executor();
459 template <typename WriteHandler, typename ConstBufferSequence,
460 typename CompletionCondition>
461 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
462 const ConstBufferSequence& buffers,
463 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
465 // If you get an error on the following line it means that your handler
466 // does not meet the documented type requirements for a WriteHandler.
467 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
469 non_const_lvalue<WriteHandler> handler2(handler);
470 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
471 start_write_buffer_sequence_op(stream_, buffers,
472 boost::asio::buffer_sequence_begin(buffers),
473 completion_cond2.value, handler2.value);
477 AsyncWriteStream& stream_;
479 } // namespace detail
481 #if !defined(GENERATING_DOCUMENTATION)
483 template <typename AsyncWriteStream, typename ConstBufferSequence,
484 typename ConstBufferIterator, typename CompletionCondition,
485 typename WriteHandler, typename Allocator>
486 struct associated_allocator<
487 detail::write_op<AsyncWriteStream, ConstBufferSequence,
488 ConstBufferIterator, CompletionCondition, WriteHandler>,
491 typedef typename associated_allocator<WriteHandler, Allocator>::type type;
494 const detail::write_op<AsyncWriteStream, ConstBufferSequence,
495 ConstBufferIterator, CompletionCondition, WriteHandler>& h,
496 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
498 return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
502 template <typename AsyncWriteStream, typename ConstBufferSequence,
503 typename ConstBufferIterator, typename CompletionCondition,
504 typename WriteHandler, typename Executor>
505 struct associated_executor<
506 detail::write_op<AsyncWriteStream, ConstBufferSequence,
507 ConstBufferIterator, CompletionCondition, WriteHandler>,
509 : detail::associated_executor_forwarding_base<WriteHandler, Executor>
511 typedef typename associated_executor<WriteHandler, Executor>::type type;
514 const detail::write_op<AsyncWriteStream, ConstBufferSequence,
515 ConstBufferIterator, CompletionCondition, WriteHandler>& h,
516 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
518 return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
522 #endif // !defined(GENERATING_DOCUMENTATION)
524 template <typename AsyncWriteStream,
525 typename ConstBufferSequence, typename CompletionCondition,
526 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
527 std::size_t)) WriteHandler>
528 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
529 void (boost::system::error_code, std::size_t))
530 async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
531 CompletionCondition completion_condition,
532 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
534 is_const_buffer_sequence<ConstBufferSequence>::value
537 return async_initiate<WriteHandler,
538 void (boost::system::error_code, std::size_t)>(
539 detail::initiate_async_write_buffer_sequence<AsyncWriteStream>(s),
541 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
544 template <typename AsyncWriteStream, typename ConstBufferSequence,
545 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
546 std::size_t)) WriteHandler>
547 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
548 void (boost::system::error_code, std::size_t))
549 async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
550 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
552 is_const_buffer_sequence<ConstBufferSequence>::value
555 return async_initiate<WriteHandler,
556 void (boost::system::error_code, std::size_t)>(
557 detail::initiate_async_write_buffer_sequence<AsyncWriteStream>(s),
558 handler, buffers, transfer_all());
561 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
565 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
566 typename CompletionCondition, typename WriteHandler>
567 class write_dynbuf_v1_op
570 template <typename BufferSequence>
571 write_dynbuf_v1_op(AsyncWriteStream& stream,
572 BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
573 CompletionCondition& completion_condition, WriteHandler& handler)
575 buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
576 completion_condition_(
577 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),
578 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
582 #if defined(BOOST_ASIO_HAS_MOVE)
583 write_dynbuf_v1_op(const write_dynbuf_v1_op& other)
584 : stream_(other.stream_),
585 buffers_(other.buffers_),
586 completion_condition_(other.completion_condition_),
587 handler_(other.handler_)
591 write_dynbuf_v1_op(write_dynbuf_v1_op&& other)
592 : stream_(other.stream_),
593 buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
594 completion_condition_(
595 BOOST_ASIO_MOVE_CAST(CompletionCondition)(
596 other.completion_condition_)),
597 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
600 #endif // defined(BOOST_ASIO_HAS_MOVE)
602 void operator()(const boost::system::error_code& ec,
603 std::size_t bytes_transferred, int start = 0)
608 async_write(stream_, buffers_.data(),
609 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),
610 BOOST_ASIO_MOVE_CAST(write_dynbuf_v1_op)(*this));
612 buffers_.consume(bytes_transferred);
613 handler_(ec, static_cast<const std::size_t&>(bytes_transferred));
618 AsyncWriteStream& stream_;
619 DynamicBuffer_v1 buffers_;
620 CompletionCondition completion_condition_;
621 WriteHandler handler_;
624 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
625 typename CompletionCondition, typename WriteHandler>
626 inline asio_handler_allocate_is_deprecated
627 asio_handler_allocate(std::size_t size,
628 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
629 CompletionCondition, WriteHandler>* this_handler)
631 #if defined(BOOST_ASIO_NO_DEPRECATED)
632 boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
633 return asio_handler_allocate_is_no_longer_used();
634 #else // defined(BOOST_ASIO_NO_DEPRECATED)
635 return boost_asio_handler_alloc_helpers::allocate(
636 size, this_handler->handler_);
637 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
640 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
641 typename CompletionCondition, typename WriteHandler>
642 inline asio_handler_deallocate_is_deprecated
643 asio_handler_deallocate(void* pointer, std::size_t size,
644 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
645 CompletionCondition, WriteHandler>* this_handler)
647 boost_asio_handler_alloc_helpers::deallocate(
648 pointer, size, this_handler->handler_);
649 #if defined(BOOST_ASIO_NO_DEPRECATED)
650 return asio_handler_deallocate_is_no_longer_used();
651 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
654 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
655 typename CompletionCondition, typename WriteHandler>
656 inline bool asio_handler_is_continuation(
657 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
658 CompletionCondition, WriteHandler>* this_handler)
660 return boost_asio_handler_cont_helpers::is_continuation(
661 this_handler->handler_);
664 template <typename Function, typename AsyncWriteStream,
665 typename DynamicBuffer_v1, typename CompletionCondition,
666 typename WriteHandler>
667 inline asio_handler_invoke_is_deprecated
668 asio_handler_invoke(Function& function,
669 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
670 CompletionCondition, WriteHandler>* this_handler)
672 boost_asio_handler_invoke_helpers::invoke(
673 function, this_handler->handler_);
674 #if defined(BOOST_ASIO_NO_DEPRECATED)
675 return asio_handler_invoke_is_no_longer_used();
676 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
679 template <typename Function, typename AsyncWriteStream,
680 typename DynamicBuffer_v1, typename CompletionCondition,
681 typename WriteHandler>
682 inline asio_handler_invoke_is_deprecated
683 asio_handler_invoke(const Function& function,
684 write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
685 CompletionCondition, WriteHandler>* this_handler)
687 boost_asio_handler_invoke_helpers::invoke(
688 function, this_handler->handler_);
689 #if defined(BOOST_ASIO_NO_DEPRECATED)
690 return asio_handler_invoke_is_no_longer_used();
691 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
694 template <typename AsyncWriteStream>
695 class initiate_async_write_dynbuf_v1
698 typedef typename AsyncWriteStream::executor_type executor_type;
700 explicit initiate_async_write_dynbuf_v1(AsyncWriteStream& stream)
705 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
707 return stream_.get_executor();
710 template <typename WriteHandler, typename DynamicBuffer_v1,
711 typename CompletionCondition>
712 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
713 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
714 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
716 // If you get an error on the following line it means that your handler
717 // does not meet the documented type requirements for a WriteHandler.
718 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
720 non_const_lvalue<WriteHandler> handler2(handler);
721 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
722 write_dynbuf_v1_op<AsyncWriteStream,
723 typename decay<DynamicBuffer_v1>::type,
724 CompletionCondition, typename decay<WriteHandler>::type>(
725 stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
726 completion_cond2.value, handler2.value)(
727 boost::system::error_code(), 0, 1);
731 AsyncWriteStream& stream_;
733 } // namespace detail
735 #if !defined(GENERATING_DOCUMENTATION)
737 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
738 typename CompletionCondition, typename WriteHandler, typename Allocator>
739 struct associated_allocator<
740 detail::write_dynbuf_v1_op<AsyncWriteStream,
741 DynamicBuffer_v1, CompletionCondition, WriteHandler>,
744 typedef typename associated_allocator<WriteHandler, Allocator>::type type;
747 const detail::write_dynbuf_v1_op<AsyncWriteStream,
748 DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,
749 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
751 return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
755 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
756 typename CompletionCondition, typename WriteHandler, typename Executor>
757 struct associated_executor<
758 detail::write_dynbuf_v1_op<AsyncWriteStream,
759 DynamicBuffer_v1, CompletionCondition, WriteHandler>,
761 : detail::associated_executor_forwarding_base<WriteHandler, Executor>
763 typedef typename associated_executor<WriteHandler, Executor>::type type;
766 const detail::write_dynbuf_v1_op<AsyncWriteStream,
767 DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,
768 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
770 return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
774 #endif // !defined(GENERATING_DOCUMENTATION)
776 template <typename AsyncWriteStream, typename DynamicBuffer_v1,
777 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
778 std::size_t)) WriteHandler>
779 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
780 void (boost::system::error_code, std::size_t))
781 async_write(AsyncWriteStream& s,
782 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
783 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
785 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
786 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
789 return async_write(s,
790 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
791 transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
794 template <typename AsyncWriteStream,
795 typename DynamicBuffer_v1, typename CompletionCondition,
796 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
797 std::size_t)) WriteHandler>
798 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
799 void (boost::system::error_code, std::size_t))
800 async_write(AsyncWriteStream& s,
801 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
802 CompletionCondition completion_condition,
803 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
805 is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
806 && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
809 return async_initiate<WriteHandler,
810 void (boost::system::error_code, std::size_t)>(
811 detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),
812 handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
813 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
816 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
817 #if !defined(BOOST_ASIO_NO_IOSTREAM)
819 template <typename AsyncWriteStream, typename Allocator,
820 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
821 std::size_t)) WriteHandler>
822 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
823 void (boost::system::error_code, std::size_t))
824 async_write(AsyncWriteStream& s,
825 boost::asio::basic_streambuf<Allocator>& b,
826 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
828 return async_write(s, basic_streambuf_ref<Allocator>(b),
829 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
832 template <typename AsyncWriteStream,
833 typename Allocator, typename CompletionCondition,
834 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
835 std::size_t)) WriteHandler>
836 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
837 void (boost::system::error_code, std::size_t))
838 async_write(AsyncWriteStream& s,
839 boost::asio::basic_streambuf<Allocator>& b,
840 CompletionCondition completion_condition,
841 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
843 return async_write(s, basic_streambuf_ref<Allocator>(b),
844 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition),
845 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
848 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
849 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
850 #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
854 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
855 typename CompletionCondition, typename WriteHandler>
856 class write_dynbuf_v2_op
859 template <typename BufferSequence>
860 write_dynbuf_v2_op(AsyncWriteStream& stream,
861 BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
862 CompletionCondition& completion_condition, WriteHandler& handler)
864 buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
865 completion_condition_(
866 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),
867 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
871 #if defined(BOOST_ASIO_HAS_MOVE)
872 write_dynbuf_v2_op(const write_dynbuf_v2_op& other)
873 : stream_(other.stream_),
874 buffers_(other.buffers_),
875 completion_condition_(other.completion_condition_),
876 handler_(other.handler_)
880 write_dynbuf_v2_op(write_dynbuf_v2_op&& other)
881 : stream_(other.stream_),
882 buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
883 completion_condition_(
884 BOOST_ASIO_MOVE_CAST(CompletionCondition)(
885 other.completion_condition_)),
886 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
889 #endif // defined(BOOST_ASIO_HAS_MOVE)
891 void operator()(const boost::system::error_code& ec,
892 std::size_t bytes_transferred, int start = 0)
897 async_write(stream_, buffers_.data(0, buffers_.size()),
898 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),
899 BOOST_ASIO_MOVE_CAST(write_dynbuf_v2_op)(*this));
901 buffers_.consume(bytes_transferred);
902 handler_(ec, static_cast<const std::size_t&>(bytes_transferred));
907 AsyncWriteStream& stream_;
908 DynamicBuffer_v2 buffers_;
909 CompletionCondition completion_condition_;
910 WriteHandler handler_;
913 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
914 typename CompletionCondition, typename WriteHandler>
915 inline asio_handler_allocate_is_deprecated
916 asio_handler_allocate(std::size_t size,
917 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
918 CompletionCondition, WriteHandler>* this_handler)
920 #if defined(BOOST_ASIO_NO_DEPRECATED)
921 boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_);
922 return asio_handler_allocate_is_no_longer_used();
923 #else // defined(BOOST_ASIO_NO_DEPRECATED)
924 return boost_asio_handler_alloc_helpers::allocate(
925 size, this_handler->handler_);
926 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
929 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
930 typename CompletionCondition, typename WriteHandler>
931 inline asio_handler_deallocate_is_deprecated
932 asio_handler_deallocate(void* pointer, std::size_t size,
933 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
934 CompletionCondition, WriteHandler>* this_handler)
936 boost_asio_handler_alloc_helpers::deallocate(
937 pointer, size, this_handler->handler_);
938 #if defined(BOOST_ASIO_NO_DEPRECATED)
939 return asio_handler_deallocate_is_no_longer_used();
940 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
943 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
944 typename CompletionCondition, typename WriteHandler>
945 inline bool asio_handler_is_continuation(
946 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
947 CompletionCondition, WriteHandler>* this_handler)
949 return boost_asio_handler_cont_helpers::is_continuation(
950 this_handler->handler_);
953 template <typename Function, typename AsyncWriteStream,
954 typename DynamicBuffer_v2, typename CompletionCondition,
955 typename WriteHandler>
956 inline asio_handler_invoke_is_deprecated
957 asio_handler_invoke(Function& function,
958 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
959 CompletionCondition, WriteHandler>* this_handler)
961 boost_asio_handler_invoke_helpers::invoke(
962 function, this_handler->handler_);
963 #if defined(BOOST_ASIO_NO_DEPRECATED)
964 return asio_handler_invoke_is_no_longer_used();
965 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
968 template <typename Function, typename AsyncWriteStream,
969 typename DynamicBuffer_v2, typename CompletionCondition,
970 typename WriteHandler>
971 inline asio_handler_invoke_is_deprecated
972 asio_handler_invoke(const Function& function,
973 write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
974 CompletionCondition, WriteHandler>* this_handler)
976 boost_asio_handler_invoke_helpers::invoke(
977 function, this_handler->handler_);
978 #if defined(BOOST_ASIO_NO_DEPRECATED)
979 return asio_handler_invoke_is_no_longer_used();
980 #endif // defined(BOOST_ASIO_NO_DEPRECATED)
983 template <typename AsyncWriteStream>
984 class initiate_async_write_dynbuf_v2
987 typedef typename AsyncWriteStream::executor_type executor_type;
989 explicit initiate_async_write_dynbuf_v2(AsyncWriteStream& stream)
994 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
996 return stream_.get_executor();
999 template <typename WriteHandler, typename DynamicBuffer_v2,
1000 typename CompletionCondition>
1001 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
1002 BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
1003 BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
1005 // If you get an error on the following line it means that your handler
1006 // does not meet the documented type requirements for a WriteHandler.
1007 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
1009 non_const_lvalue<WriteHandler> handler2(handler);
1010 non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
1011 write_dynbuf_v2_op<AsyncWriteStream,
1012 typename decay<DynamicBuffer_v2>::type,
1013 CompletionCondition, typename decay<WriteHandler>::type>(
1014 stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
1015 completion_cond2.value, handler2.value)(
1016 boost::system::error_code(), 0, 1);
1020 AsyncWriteStream& stream_;
1022 } // namespace detail
1024 #if !defined(GENERATING_DOCUMENTATION)
1026 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
1027 typename CompletionCondition, typename WriteHandler, typename Allocator>
1028 struct associated_allocator<
1029 detail::write_dynbuf_v2_op<AsyncWriteStream,
1030 DynamicBuffer_v2, CompletionCondition, WriteHandler>,
1033 typedef typename associated_allocator<WriteHandler, Allocator>::type type;
1036 const detail::write_dynbuf_v2_op<AsyncWriteStream,
1037 DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,
1038 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
1040 return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
1044 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
1045 typename CompletionCondition, typename WriteHandler, typename Executor>
1046 struct associated_executor<
1047 detail::write_dynbuf_v2_op<AsyncWriteStream,
1048 DynamicBuffer_v2, CompletionCondition, WriteHandler>,
1050 : detail::associated_executor_forwarding_base<WriteHandler, Executor>
1052 typedef typename associated_executor<WriteHandler, Executor>::type type;
1055 const detail::write_dynbuf_v2_op<AsyncWriteStream,
1056 DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,
1057 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
1059 return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
1063 #endif // !defined(GENERATING_DOCUMENTATION)
1065 template <typename AsyncWriteStream, typename DynamicBuffer_v2,
1066 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1067 std::size_t)) WriteHandler>
1068 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
1069 void (boost::system::error_code, std::size_t))
1070 async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
1071 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
1073 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1076 return async_write(s,
1077 BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
1078 transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
1081 template <typename AsyncWriteStream,
1082 typename DynamicBuffer_v2, typename CompletionCondition,
1083 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1084 std::size_t)) WriteHandler>
1085 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
1086 void (boost::system::error_code, std::size_t))
1087 async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
1088 CompletionCondition completion_condition,
1089 BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
1091 is_dynamic_buffer_v2<DynamicBuffer_v2>::value
1094 return async_initiate<WriteHandler,
1095 void (boost::system::error_code, std::size_t)>(
1096 detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),
1097 handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
1098 BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
1102 } // namespace boost
1104 #include <boost/asio/detail/pop_options.hpp>
1106 #endif // BOOST_ASIO_IMPL_WRITE_HPP