annotate DEPENDENCIES/generic/include/boost/asio/impl/write.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 //
Chris@16 2 // impl/write.hpp
Chris@16 3 // ~~~~~~~~~~~~~~
Chris@16 4 //
Chris@101 5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
Chris@16 6 //
Chris@16 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 //
Chris@16 10
Chris@16 11 #ifndef BOOST_ASIO_IMPL_WRITE_HPP
Chris@16 12 #define BOOST_ASIO_IMPL_WRITE_HPP
Chris@16 13
Chris@16 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
Chris@16 15 # pragma once
Chris@16 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
Chris@16 17
Chris@16 18 #include <boost/asio/buffer.hpp>
Chris@16 19 #include <boost/asio/completion_condition.hpp>
Chris@16 20 #include <boost/asio/detail/array_fwd.hpp>
Chris@16 21 #include <boost/asio/detail/base_from_completion_cond.hpp>
Chris@16 22 #include <boost/asio/detail/bind_handler.hpp>
Chris@16 23 #include <boost/asio/detail/consuming_buffers.hpp>
Chris@16 24 #include <boost/asio/detail/dependent_type.hpp>
Chris@16 25 #include <boost/asio/detail/handler_alloc_helpers.hpp>
Chris@16 26 #include <boost/asio/detail/handler_cont_helpers.hpp>
Chris@16 27 #include <boost/asio/detail/handler_invoke_helpers.hpp>
Chris@16 28 #include <boost/asio/detail/handler_type_requirements.hpp>
Chris@16 29 #include <boost/asio/detail/throw_error.hpp>
Chris@16 30
Chris@16 31 #include <boost/asio/detail/push_options.hpp>
Chris@16 32
Chris@16 33 namespace boost {
Chris@16 34 namespace asio {
Chris@16 35
Chris@16 36 template <typename SyncWriteStream, typename ConstBufferSequence,
Chris@16 37 typename CompletionCondition>
Chris@16 38 std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
Chris@16 39 CompletionCondition completion_condition, boost::system::error_code& ec)
Chris@16 40 {
Chris@16 41 ec = boost::system::error_code();
Chris@16 42 boost::asio::detail::consuming_buffers<
Chris@16 43 const_buffer, ConstBufferSequence> tmp(buffers);
Chris@16 44 std::size_t total_transferred = 0;
Chris@16 45 tmp.prepare(detail::adapt_completion_condition_result(
Chris@16 46 completion_condition(ec, total_transferred)));
Chris@16 47 while (tmp.begin() != tmp.end())
Chris@16 48 {
Chris@16 49 std::size_t bytes_transferred = s.write_some(tmp, ec);
Chris@16 50 tmp.consume(bytes_transferred);
Chris@16 51 total_transferred += bytes_transferred;
Chris@16 52 tmp.prepare(detail::adapt_completion_condition_result(
Chris@16 53 completion_condition(ec, total_transferred)));
Chris@16 54 }
Chris@16 55 return total_transferred;
Chris@16 56 }
Chris@16 57
Chris@16 58 template <typename SyncWriteStream, typename ConstBufferSequence>
Chris@16 59 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers)
Chris@16 60 {
Chris@16 61 boost::system::error_code ec;
Chris@16 62 std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);
Chris@16 63 boost::asio::detail::throw_error(ec, "write");
Chris@16 64 return bytes_transferred;
Chris@16 65 }
Chris@16 66
Chris@16 67 template <typename SyncWriteStream, typename ConstBufferSequence>
Chris@16 68 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
Chris@16 69 boost::system::error_code& ec)
Chris@16 70 {
Chris@16 71 return write(s, buffers, transfer_all(), ec);
Chris@16 72 }
Chris@16 73
Chris@16 74 template <typename SyncWriteStream, typename ConstBufferSequence,
Chris@16 75 typename CompletionCondition>
Chris@16 76 inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
Chris@16 77 CompletionCondition completion_condition)
Chris@16 78 {
Chris@16 79 boost::system::error_code ec;
Chris@16 80 std::size_t bytes_transferred = write(s, buffers, completion_condition, ec);
Chris@16 81 boost::asio::detail::throw_error(ec, "write");
Chris@16 82 return bytes_transferred;
Chris@16 83 }
Chris@16 84
Chris@16 85 #if !defined(BOOST_ASIO_NO_IOSTREAM)
Chris@16 86
Chris@16 87 template <typename SyncWriteStream, typename Allocator,
Chris@16 88 typename CompletionCondition>
Chris@16 89 std::size_t write(SyncWriteStream& s,
Chris@16 90 boost::asio::basic_streambuf<Allocator>& b,
Chris@16 91 CompletionCondition completion_condition, boost::system::error_code& ec)
Chris@16 92 {
Chris@16 93 std::size_t bytes_transferred = write(s, b.data(), completion_condition, ec);
Chris@16 94 b.consume(bytes_transferred);
Chris@16 95 return bytes_transferred;
Chris@16 96 }
Chris@16 97
Chris@16 98 template <typename SyncWriteStream, typename Allocator>
Chris@16 99 inline std::size_t write(SyncWriteStream& s,
Chris@16 100 boost::asio::basic_streambuf<Allocator>& b)
Chris@16 101 {
Chris@16 102 boost::system::error_code ec;
Chris@16 103 std::size_t bytes_transferred = write(s, b, transfer_all(), ec);
Chris@16 104 boost::asio::detail::throw_error(ec, "write");
Chris@16 105 return bytes_transferred;
Chris@16 106 }
Chris@16 107
Chris@16 108 template <typename SyncWriteStream, typename Allocator>
Chris@16 109 inline std::size_t write(SyncWriteStream& s,
Chris@16 110 boost::asio::basic_streambuf<Allocator>& b,
Chris@16 111 boost::system::error_code& ec)
Chris@16 112 {
Chris@16 113 return write(s, b, transfer_all(), ec);
Chris@16 114 }
Chris@16 115
Chris@16 116 template <typename SyncWriteStream, typename Allocator,
Chris@16 117 typename CompletionCondition>
Chris@16 118 inline std::size_t write(SyncWriteStream& s,
Chris@16 119 boost::asio::basic_streambuf<Allocator>& b,
Chris@16 120 CompletionCondition completion_condition)
Chris@16 121 {
Chris@16 122 boost::system::error_code ec;
Chris@16 123 std::size_t bytes_transferred = write(s, b, completion_condition, ec);
Chris@16 124 boost::asio::detail::throw_error(ec, "write");
Chris@16 125 return bytes_transferred;
Chris@16 126 }
Chris@16 127
Chris@16 128 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
Chris@16 129
Chris@16 130 namespace detail
Chris@16 131 {
Chris@16 132 template <typename AsyncWriteStream, typename ConstBufferSequence,
Chris@16 133 typename CompletionCondition, typename WriteHandler>
Chris@16 134 class write_op
Chris@16 135 : detail::base_from_completion_cond<CompletionCondition>
Chris@16 136 {
Chris@16 137 public:
Chris@16 138 write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers,
Chris@16 139 CompletionCondition completion_condition, WriteHandler& handler)
Chris@16 140 : detail::base_from_completion_cond<
Chris@16 141 CompletionCondition>(completion_condition),
Chris@16 142 stream_(stream),
Chris@16 143 buffers_(buffers),
Chris@16 144 start_(0),
Chris@16 145 total_transferred_(0),
Chris@16 146 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
Chris@16 147 {
Chris@16 148 }
Chris@16 149
Chris@16 150 #if defined(BOOST_ASIO_HAS_MOVE)
Chris@16 151 write_op(const write_op& other)
Chris@16 152 : detail::base_from_completion_cond<CompletionCondition>(other),
Chris@16 153 stream_(other.stream_),
Chris@16 154 buffers_(other.buffers_),
Chris@16 155 start_(other.start_),
Chris@16 156 total_transferred_(other.total_transferred_),
Chris@16 157 handler_(other.handler_)
Chris@16 158 {
Chris@16 159 }
Chris@16 160
Chris@16 161 write_op(write_op&& other)
Chris@16 162 : detail::base_from_completion_cond<CompletionCondition>(other),
Chris@16 163 stream_(other.stream_),
Chris@16 164 buffers_(other.buffers_),
Chris@16 165 start_(other.start_),
Chris@16 166 total_transferred_(other.total_transferred_),
Chris@16 167 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
Chris@16 168 {
Chris@16 169 }
Chris@16 170 #endif // defined(BOOST_ASIO_HAS_MOVE)
Chris@16 171
Chris@16 172 void operator()(const boost::system::error_code& ec,
Chris@16 173 std::size_t bytes_transferred, int start = 0)
Chris@16 174 {
Chris@16 175 switch (start_ = start)
Chris@16 176 {
Chris@16 177 case 1:
Chris@16 178 buffers_.prepare(this->check_for_completion(ec, total_transferred_));
Chris@16 179 for (;;)
Chris@16 180 {
Chris@16 181 stream_.async_write_some(buffers_,
Chris@16 182 BOOST_ASIO_MOVE_CAST(write_op)(*this));
Chris@16 183 return; default:
Chris@16 184 total_transferred_ += bytes_transferred;
Chris@16 185 buffers_.consume(bytes_transferred);
Chris@16 186 buffers_.prepare(this->check_for_completion(ec, total_transferred_));
Chris@16 187 if ((!ec && bytes_transferred == 0)
Chris@16 188 || buffers_.begin() == buffers_.end())
Chris@16 189 break;
Chris@16 190 }
Chris@16 191
Chris@16 192 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
Chris@16 193 }
Chris@16 194 }
Chris@16 195
Chris@16 196 //private:
Chris@16 197 AsyncWriteStream& stream_;
Chris@16 198 boost::asio::detail::consuming_buffers<
Chris@16 199 const_buffer, ConstBufferSequence> buffers_;
Chris@16 200 int start_;
Chris@16 201 std::size_t total_transferred_;
Chris@16 202 WriteHandler handler_;
Chris@16 203 };
Chris@16 204
Chris@16 205 template <typename AsyncWriteStream,
Chris@16 206 typename CompletionCondition, typename WriteHandler>
Chris@16 207 class write_op<AsyncWriteStream, boost::asio::mutable_buffers_1,
Chris@16 208 CompletionCondition, WriteHandler>
Chris@16 209 : detail::base_from_completion_cond<CompletionCondition>
Chris@16 210 {
Chris@16 211 public:
Chris@16 212 write_op(AsyncWriteStream& stream,
Chris@16 213 const boost::asio::mutable_buffers_1& buffers,
Chris@16 214 CompletionCondition completion_condition,
Chris@16 215 WriteHandler& handler)
Chris@16 216 : detail::base_from_completion_cond<
Chris@16 217 CompletionCondition>(completion_condition),
Chris@16 218 stream_(stream),
Chris@16 219 buffer_(buffers),
Chris@16 220 start_(0),
Chris@16 221 total_transferred_(0),
Chris@16 222 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
Chris@16 223 {
Chris@16 224 }
Chris@16 225
Chris@16 226 #if defined(BOOST_ASIO_HAS_MOVE)
Chris@16 227 write_op(const write_op& other)
Chris@16 228 : detail::base_from_completion_cond<CompletionCondition>(other),
Chris@16 229 stream_(other.stream_),
Chris@16 230 buffer_(other.buffer_),
Chris@16 231 start_(other.start_),
Chris@16 232 total_transferred_(other.total_transferred_),
Chris@16 233 handler_(other.handler_)
Chris@16 234 {
Chris@16 235 }
Chris@16 236
Chris@16 237 write_op(write_op&& other)
Chris@16 238 : detail::base_from_completion_cond<CompletionCondition>(other),
Chris@16 239 stream_(other.stream_),
Chris@16 240 buffer_(other.buffer_),
Chris@16 241 start_(other.start_),
Chris@16 242 total_transferred_(other.total_transferred_),
Chris@16 243 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
Chris@16 244 {
Chris@16 245 }
Chris@16 246 #endif // defined(BOOST_ASIO_HAS_MOVE)
Chris@16 247
Chris@16 248 void operator()(const boost::system::error_code& ec,
Chris@16 249 std::size_t bytes_transferred, int start = 0)
Chris@16 250 {
Chris@16 251 std::size_t n = 0;
Chris@16 252 switch (start_ = start)
Chris@16 253 {
Chris@16 254 case 1:
Chris@16 255 n = this->check_for_completion(ec, total_transferred_);
Chris@16 256 for (;;)
Chris@16 257 {
Chris@16 258 stream_.async_write_some(
Chris@16 259 boost::asio::buffer(buffer_ + total_transferred_, n),
Chris@16 260 BOOST_ASIO_MOVE_CAST(write_op)(*this));
Chris@16 261 return; default:
Chris@16 262 total_transferred_ += bytes_transferred;
Chris@16 263 if ((!ec && bytes_transferred == 0)
Chris@16 264 || (n = this->check_for_completion(ec, total_transferred_)) == 0
Chris@16 265 || total_transferred_ == boost::asio::buffer_size(buffer_))
Chris@16 266 break;
Chris@16 267 }
Chris@16 268
Chris@16 269 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
Chris@16 270 }
Chris@16 271 }
Chris@16 272
Chris@16 273 //private:
Chris@16 274 AsyncWriteStream& stream_;
Chris@16 275 boost::asio::mutable_buffer buffer_;
Chris@16 276 int start_;
Chris@16 277 std::size_t total_transferred_;
Chris@16 278 WriteHandler handler_;
Chris@16 279 };
Chris@16 280
Chris@16 281 template <typename AsyncWriteStream,
Chris@16 282 typename CompletionCondition, typename WriteHandler>
Chris@16 283 class write_op<AsyncWriteStream, boost::asio::const_buffers_1,
Chris@16 284 CompletionCondition, WriteHandler>
Chris@16 285 : detail::base_from_completion_cond<CompletionCondition>
Chris@16 286 {
Chris@16 287 public:
Chris@16 288 write_op(AsyncWriteStream& stream,
Chris@16 289 const boost::asio::const_buffers_1& buffers,
Chris@16 290 CompletionCondition completion_condition,
Chris@16 291 WriteHandler& handler)
Chris@16 292 : detail::base_from_completion_cond<
Chris@16 293 CompletionCondition>(completion_condition),
Chris@16 294 stream_(stream),
Chris@16 295 buffer_(buffers),
Chris@16 296 start_(0),
Chris@16 297 total_transferred_(0),
Chris@16 298 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
Chris@16 299 {
Chris@16 300 }
Chris@16 301
Chris@16 302 #if defined(BOOST_ASIO_HAS_MOVE)
Chris@16 303 write_op(const write_op& other)
Chris@16 304 : detail::base_from_completion_cond<CompletionCondition>(other),
Chris@16 305 stream_(other.stream_),
Chris@16 306 buffer_(other.buffer_),
Chris@16 307 start_(other.start_),
Chris@16 308 total_transferred_(other.total_transferred_),
Chris@16 309 handler_(other.handler_)
Chris@16 310 {
Chris@16 311 }
Chris@16 312
Chris@16 313 write_op(write_op&& other)
Chris@16 314 : detail::base_from_completion_cond<CompletionCondition>(other),
Chris@16 315 stream_(other.stream_),
Chris@16 316 buffer_(other.buffer_),
Chris@16 317 start_(other.start_),
Chris@16 318 total_transferred_(other.total_transferred_),
Chris@16 319 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
Chris@16 320 {
Chris@16 321 }
Chris@16 322 #endif // defined(BOOST_ASIO_HAS_MOVE)
Chris@16 323
Chris@16 324 void operator()(const boost::system::error_code& ec,
Chris@16 325 std::size_t bytes_transferred, int start = 0)
Chris@16 326 {
Chris@16 327 std::size_t n = 0;
Chris@16 328 switch (start_ = start)
Chris@16 329 {
Chris@16 330 case 1:
Chris@16 331 n = this->check_for_completion(ec, total_transferred_);
Chris@16 332 for (;;)
Chris@16 333 {
Chris@16 334 stream_.async_write_some(
Chris@16 335 boost::asio::buffer(buffer_ + total_transferred_, n),
Chris@16 336 BOOST_ASIO_MOVE_CAST(write_op)(*this));
Chris@16 337 return; default:
Chris@16 338 total_transferred_ += bytes_transferred;
Chris@16 339 if ((!ec && bytes_transferred == 0)
Chris@16 340 || (n = this->check_for_completion(ec, total_transferred_)) == 0
Chris@16 341 || total_transferred_ == boost::asio::buffer_size(buffer_))
Chris@16 342 break;
Chris@16 343 }
Chris@16 344
Chris@16 345 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
Chris@16 346 }
Chris@16 347 }
Chris@16 348
Chris@16 349 //private:
Chris@16 350 AsyncWriteStream& stream_;
Chris@16 351 boost::asio::const_buffer buffer_;
Chris@16 352 int start_;
Chris@16 353 std::size_t total_transferred_;
Chris@16 354 WriteHandler handler_;
Chris@16 355 };
Chris@16 356
Chris@16 357 template <typename AsyncWriteStream, typename Elem,
Chris@16 358 typename CompletionCondition, typename WriteHandler>
Chris@16 359 class write_op<AsyncWriteStream, boost::array<Elem, 2>,
Chris@16 360 CompletionCondition, WriteHandler>
Chris@16 361 : detail::base_from_completion_cond<CompletionCondition>
Chris@16 362 {
Chris@16 363 public:
Chris@16 364 write_op(AsyncWriteStream& stream, const boost::array<Elem, 2>& buffers,
Chris@16 365 CompletionCondition completion_condition, WriteHandler& handler)
Chris@16 366 : detail::base_from_completion_cond<
Chris@16 367 CompletionCondition>(completion_condition),
Chris@16 368 stream_(stream),
Chris@16 369 buffers_(buffers),
Chris@16 370 start_(0),
Chris@16 371 total_transferred_(0),
Chris@16 372 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
Chris@16 373 {
Chris@16 374 }
Chris@16 375
Chris@16 376 #if defined(BOOST_ASIO_HAS_MOVE)
Chris@16 377 write_op(const write_op& other)
Chris@16 378 : detail::base_from_completion_cond<CompletionCondition>(other),
Chris@16 379 stream_(other.stream_),
Chris@16 380 buffers_(other.buffers_),
Chris@16 381 start_(other.start_),
Chris@16 382 total_transferred_(other.total_transferred_),
Chris@16 383 handler_(other.handler_)
Chris@16 384 {
Chris@16 385 }
Chris@16 386
Chris@16 387 write_op(write_op&& other)
Chris@16 388 : detail::base_from_completion_cond<CompletionCondition>(other),
Chris@16 389 stream_(other.stream_),
Chris@16 390 buffers_(other.buffers_),
Chris@16 391 start_(other.start_),
Chris@16 392 total_transferred_(other.total_transferred_),
Chris@16 393 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
Chris@16 394 {
Chris@16 395 }
Chris@16 396 #endif // defined(BOOST_ASIO_HAS_MOVE)
Chris@16 397
Chris@16 398 void operator()(const boost::system::error_code& ec,
Chris@16 399 std::size_t bytes_transferred, int start = 0)
Chris@16 400 {
Chris@16 401 typename boost::asio::detail::dependent_type<Elem,
Chris@16 402 boost::array<boost::asio::const_buffer, 2> >::type bufs = {{
Chris@16 403 boost::asio::const_buffer(buffers_[0]),
Chris@16 404 boost::asio::const_buffer(buffers_[1]) }};
Chris@16 405 std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]);
Chris@16 406 std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]);
Chris@16 407 std::size_t n = 0;
Chris@16 408 switch (start_ = start)
Chris@16 409 {
Chris@16 410 case 1:
Chris@16 411 n = this->check_for_completion(ec, total_transferred_);
Chris@16 412 for (;;)
Chris@16 413 {
Chris@16 414 bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n);
Chris@16 415 bufs[1] = boost::asio::buffer(
Chris@16 416 bufs[1] + (total_transferred_ < buffer_size0
Chris@16 417 ? 0 : total_transferred_ - buffer_size0),
Chris@16 418 n - boost::asio::buffer_size(bufs[0]));
Chris@16 419 stream_.async_write_some(bufs, BOOST_ASIO_MOVE_CAST(write_op)(*this));
Chris@16 420 return; default:
Chris@16 421 total_transferred_ += bytes_transferred;
Chris@16 422 if ((!ec && bytes_transferred == 0)
Chris@16 423 || (n = this->check_for_completion(ec, total_transferred_)) == 0
Chris@16 424 || total_transferred_ == buffer_size0 + buffer_size1)
Chris@16 425 break;
Chris@16 426 }
Chris@16 427
Chris@16 428 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
Chris@16 429 }
Chris@16 430 }
Chris@16 431
Chris@16 432 //private:
Chris@16 433 AsyncWriteStream& stream_;
Chris@16 434 boost::array<Elem, 2> buffers_;
Chris@16 435 int start_;
Chris@16 436 std::size_t total_transferred_;
Chris@16 437 WriteHandler handler_;
Chris@16 438 };
Chris@16 439
Chris@16 440 #if defined(BOOST_ASIO_HAS_STD_ARRAY)
Chris@16 441
Chris@16 442 template <typename AsyncWriteStream, typename Elem,
Chris@16 443 typename CompletionCondition, typename WriteHandler>
Chris@16 444 class write_op<AsyncWriteStream, std::array<Elem, 2>,
Chris@16 445 CompletionCondition, WriteHandler>
Chris@16 446 : detail::base_from_completion_cond<CompletionCondition>
Chris@16 447 {
Chris@16 448 public:
Chris@16 449 write_op(AsyncWriteStream& stream, const std::array<Elem, 2>& buffers,
Chris@16 450 CompletionCondition completion_condition, WriteHandler& handler)
Chris@16 451 : detail::base_from_completion_cond<
Chris@16 452 CompletionCondition>(completion_condition),
Chris@16 453 stream_(stream),
Chris@16 454 buffers_(buffers),
Chris@16 455 start_(0),
Chris@16 456 total_transferred_(0),
Chris@16 457 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
Chris@16 458 {
Chris@16 459 }
Chris@16 460
Chris@16 461 #if defined(BOOST_ASIO_HAS_MOVE)
Chris@16 462 write_op(const write_op& other)
Chris@16 463 : detail::base_from_completion_cond<CompletionCondition>(other),
Chris@16 464 stream_(other.stream_),
Chris@16 465 buffers_(other.buffers_),
Chris@16 466 start_(other.start_),
Chris@16 467 total_transferred_(other.total_transferred_),
Chris@16 468 handler_(other.handler_)
Chris@16 469 {
Chris@16 470 }
Chris@16 471
Chris@16 472 write_op(write_op&& other)
Chris@16 473 : detail::base_from_completion_cond<CompletionCondition>(other),
Chris@16 474 stream_(other.stream_),
Chris@16 475 buffers_(other.buffers_),
Chris@16 476 start_(other.start_),
Chris@16 477 total_transferred_(other.total_transferred_),
Chris@16 478 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
Chris@16 479 {
Chris@16 480 }
Chris@16 481 #endif // defined(BOOST_ASIO_HAS_MOVE)
Chris@16 482
Chris@16 483 void operator()(const boost::system::error_code& ec,
Chris@16 484 std::size_t bytes_transferred, int start = 0)
Chris@16 485 {
Chris@16 486 typename boost::asio::detail::dependent_type<Elem,
Chris@16 487 std::array<boost::asio::const_buffer, 2> >::type bufs = {{
Chris@16 488 boost::asio::const_buffer(buffers_[0]),
Chris@16 489 boost::asio::const_buffer(buffers_[1]) }};
Chris@16 490 std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]);
Chris@16 491 std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]);
Chris@16 492 std::size_t n = 0;
Chris@16 493 switch (start_ = start)
Chris@16 494 {
Chris@16 495 case 1:
Chris@16 496 n = this->check_for_completion(ec, total_transferred_);
Chris@16 497 for (;;)
Chris@16 498 {
Chris@16 499 bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n);
Chris@16 500 bufs[1] = boost::asio::buffer(
Chris@16 501 bufs[1] + (total_transferred_ < buffer_size0
Chris@16 502 ? 0 : total_transferred_ - buffer_size0),
Chris@16 503 n - boost::asio::buffer_size(bufs[0]));
Chris@16 504 stream_.async_write_some(bufs, BOOST_ASIO_MOVE_CAST(write_op)(*this));
Chris@16 505 return; default:
Chris@16 506 total_transferred_ += bytes_transferred;
Chris@16 507 if ((!ec && bytes_transferred == 0)
Chris@16 508 || (n = this->check_for_completion(ec, total_transferred_)) == 0
Chris@16 509 || total_transferred_ == buffer_size0 + buffer_size1)
Chris@16 510 break;
Chris@16 511 }
Chris@16 512
Chris@16 513 handler_(ec, static_cast<const std::size_t&>(total_transferred_));
Chris@16 514 }
Chris@16 515 }
Chris@16 516
Chris@16 517 //private:
Chris@16 518 AsyncWriteStream& stream_;
Chris@16 519 std::array<Elem, 2> buffers_;
Chris@16 520 int start_;
Chris@16 521 std::size_t total_transferred_;
Chris@16 522 WriteHandler handler_;
Chris@16 523 };
Chris@16 524
Chris@16 525 #endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
Chris@16 526
Chris@16 527 template <typename AsyncWriteStream, typename ConstBufferSequence,
Chris@16 528 typename CompletionCondition, typename WriteHandler>
Chris@16 529 inline void* asio_handler_allocate(std::size_t size,
Chris@16 530 write_op<AsyncWriteStream, ConstBufferSequence,
Chris@16 531 CompletionCondition, WriteHandler>* this_handler)
Chris@16 532 {
Chris@16 533 return boost_asio_handler_alloc_helpers::allocate(
Chris@16 534 size, this_handler->handler_);
Chris@16 535 }
Chris@16 536
Chris@16 537 template <typename AsyncWriteStream, typename ConstBufferSequence,
Chris@16 538 typename CompletionCondition, typename WriteHandler>
Chris@16 539 inline void asio_handler_deallocate(void* pointer, std::size_t size,
Chris@16 540 write_op<AsyncWriteStream, ConstBufferSequence,
Chris@16 541 CompletionCondition, WriteHandler>* this_handler)
Chris@16 542 {
Chris@16 543 boost_asio_handler_alloc_helpers::deallocate(
Chris@16 544 pointer, size, this_handler->handler_);
Chris@16 545 }
Chris@16 546
Chris@16 547 template <typename AsyncWriteStream, typename ConstBufferSequence,
Chris@16 548 typename CompletionCondition, typename WriteHandler>
Chris@16 549 inline bool asio_handler_is_continuation(
Chris@16 550 write_op<AsyncWriteStream, ConstBufferSequence,
Chris@16 551 CompletionCondition, WriteHandler>* this_handler)
Chris@16 552 {
Chris@16 553 return this_handler->start_ == 0 ? true
Chris@16 554 : boost_asio_handler_cont_helpers::is_continuation(
Chris@16 555 this_handler->handler_);
Chris@16 556 }
Chris@16 557
Chris@16 558 template <typename Function, typename AsyncWriteStream,
Chris@16 559 typename ConstBufferSequence, typename CompletionCondition,
Chris@16 560 typename WriteHandler>
Chris@16 561 inline void asio_handler_invoke(Function& function,
Chris@16 562 write_op<AsyncWriteStream, ConstBufferSequence,
Chris@16 563 CompletionCondition, WriteHandler>* this_handler)
Chris@16 564 {
Chris@16 565 boost_asio_handler_invoke_helpers::invoke(
Chris@16 566 function, this_handler->handler_);
Chris@16 567 }
Chris@16 568
Chris@16 569 template <typename Function, typename AsyncWriteStream,
Chris@16 570 typename ConstBufferSequence, typename CompletionCondition,
Chris@16 571 typename WriteHandler>
Chris@16 572 inline void asio_handler_invoke(const Function& function,
Chris@16 573 write_op<AsyncWriteStream, ConstBufferSequence,
Chris@16 574 CompletionCondition, WriteHandler>* this_handler)
Chris@16 575 {
Chris@16 576 boost_asio_handler_invoke_helpers::invoke(
Chris@16 577 function, this_handler->handler_);
Chris@16 578 }
Chris@16 579 } // namespace detail
Chris@16 580
Chris@16 581 template <typename AsyncWriteStream, typename ConstBufferSequence,
Chris@16 582 typename CompletionCondition, typename WriteHandler>
Chris@16 583 inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
Chris@16 584 void (boost::system::error_code, std::size_t))
Chris@16 585 async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
Chris@16 586 CompletionCondition completion_condition,
Chris@16 587 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
Chris@16 588 {
Chris@16 589 // If you get an error on the following line it means that your handler does
Chris@16 590 // not meet the documented type requirements for a WriteHandler.
Chris@16 591 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
Chris@16 592
Chris@16 593 detail::async_result_init<
Chris@16 594 WriteHandler, void (boost::system::error_code, std::size_t)> init(
Chris@16 595 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
Chris@16 596
Chris@16 597 detail::write_op<AsyncWriteStream, ConstBufferSequence,
Chris@16 598 CompletionCondition, BOOST_ASIO_HANDLER_TYPE(
Chris@16 599 WriteHandler, void (boost::system::error_code, std::size_t))>(
Chris@16 600 s, buffers, completion_condition, init.handler)(
Chris@16 601 boost::system::error_code(), 0, 1);
Chris@16 602
Chris@16 603 return init.result.get();
Chris@16 604 }
Chris@16 605
Chris@16 606 template <typename AsyncWriteStream, typename ConstBufferSequence,
Chris@16 607 typename WriteHandler>
Chris@16 608 inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
Chris@16 609 void (boost::system::error_code, std::size_t))
Chris@16 610 async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
Chris@16 611 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
Chris@16 612 {
Chris@16 613 // If you get an error on the following line it means that your handler does
Chris@16 614 // not meet the documented type requirements for a WriteHandler.
Chris@16 615 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
Chris@16 616
Chris@16 617 detail::async_result_init<
Chris@16 618 WriteHandler, void (boost::system::error_code, std::size_t)> init(
Chris@16 619 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
Chris@16 620
Chris@16 621 detail::write_op<AsyncWriteStream, ConstBufferSequence,
Chris@16 622 detail::transfer_all_t, BOOST_ASIO_HANDLER_TYPE(
Chris@16 623 WriteHandler, void (boost::system::error_code, std::size_t))>(
Chris@16 624 s, buffers, transfer_all(), init.handler)(
Chris@16 625 boost::system::error_code(), 0, 1);
Chris@16 626
Chris@16 627 return init.result.get();
Chris@16 628 }
Chris@16 629
Chris@16 630 #if !defined(BOOST_ASIO_NO_IOSTREAM)
Chris@16 631
Chris@16 632 namespace detail
Chris@16 633 {
Chris@16 634 template <typename Allocator, typename WriteHandler>
Chris@16 635 class write_streambuf_handler
Chris@16 636 {
Chris@16 637 public:
Chris@16 638 write_streambuf_handler(boost::asio::basic_streambuf<Allocator>& streambuf,
Chris@16 639 WriteHandler& handler)
Chris@16 640 : streambuf_(streambuf),
Chris@16 641 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
Chris@16 642 {
Chris@16 643 }
Chris@16 644
Chris@16 645 #if defined(BOOST_ASIO_HAS_MOVE)
Chris@16 646 write_streambuf_handler(const write_streambuf_handler& other)
Chris@16 647 : streambuf_(other.streambuf_),
Chris@16 648 handler_(other.handler_)
Chris@16 649 {
Chris@16 650 }
Chris@16 651
Chris@16 652 write_streambuf_handler(write_streambuf_handler&& other)
Chris@16 653 : streambuf_(other.streambuf_),
Chris@16 654 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
Chris@16 655 {
Chris@16 656 }
Chris@16 657 #endif // defined(BOOST_ASIO_HAS_MOVE)
Chris@16 658
Chris@16 659 void operator()(const boost::system::error_code& ec,
Chris@16 660 const std::size_t bytes_transferred)
Chris@16 661 {
Chris@16 662 streambuf_.consume(bytes_transferred);
Chris@16 663 handler_(ec, bytes_transferred);
Chris@16 664 }
Chris@16 665
Chris@16 666 //private:
Chris@16 667 boost::asio::basic_streambuf<Allocator>& streambuf_;
Chris@16 668 WriteHandler handler_;
Chris@16 669 };
Chris@16 670
Chris@16 671 template <typename Allocator, typename WriteHandler>
Chris@16 672 inline void* asio_handler_allocate(std::size_t size,
Chris@16 673 write_streambuf_handler<Allocator, WriteHandler>* this_handler)
Chris@16 674 {
Chris@16 675 return boost_asio_handler_alloc_helpers::allocate(
Chris@16 676 size, this_handler->handler_);
Chris@16 677 }
Chris@16 678
Chris@16 679 template <typename Allocator, typename WriteHandler>
Chris@16 680 inline void asio_handler_deallocate(void* pointer, std::size_t size,
Chris@16 681 write_streambuf_handler<Allocator, WriteHandler>* this_handler)
Chris@16 682 {
Chris@16 683 boost_asio_handler_alloc_helpers::deallocate(
Chris@16 684 pointer, size, this_handler->handler_);
Chris@16 685 }
Chris@16 686
Chris@16 687 template <typename Allocator, typename WriteHandler>
Chris@16 688 inline bool asio_handler_is_continuation(
Chris@16 689 write_streambuf_handler<Allocator, WriteHandler>* this_handler)
Chris@16 690 {
Chris@16 691 return boost_asio_handler_cont_helpers::is_continuation(
Chris@16 692 this_handler->handler_);
Chris@16 693 }
Chris@16 694
Chris@16 695 template <typename Function, typename Allocator, typename WriteHandler>
Chris@16 696 inline void asio_handler_invoke(Function& function,
Chris@16 697 write_streambuf_handler<Allocator, WriteHandler>* this_handler)
Chris@16 698 {
Chris@16 699 boost_asio_handler_invoke_helpers::invoke(
Chris@16 700 function, this_handler->handler_);
Chris@16 701 }
Chris@16 702
Chris@16 703 template <typename Function, typename Allocator, typename WriteHandler>
Chris@16 704 inline void asio_handler_invoke(const Function& function,
Chris@16 705 write_streambuf_handler<Allocator, WriteHandler>* this_handler)
Chris@16 706 {
Chris@16 707 boost_asio_handler_invoke_helpers::invoke(
Chris@16 708 function, this_handler->handler_);
Chris@16 709 }
Chris@16 710 } // namespace detail
Chris@16 711
Chris@16 712 template <typename AsyncWriteStream, typename Allocator,
Chris@16 713 typename CompletionCondition, typename WriteHandler>
Chris@16 714 inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
Chris@16 715 void (boost::system::error_code, std::size_t))
Chris@16 716 async_write(AsyncWriteStream& s,
Chris@16 717 boost::asio::basic_streambuf<Allocator>& b,
Chris@16 718 CompletionCondition completion_condition,
Chris@16 719 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
Chris@16 720 {
Chris@16 721 // If you get an error on the following line it means that your handler does
Chris@16 722 // not meet the documented type requirements for a WriteHandler.
Chris@16 723 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
Chris@16 724
Chris@16 725 detail::async_result_init<
Chris@16 726 WriteHandler, void (boost::system::error_code, std::size_t)> init(
Chris@16 727 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
Chris@16 728
Chris@16 729 async_write(s, b.data(), completion_condition,
Chris@16 730 detail::write_streambuf_handler<Allocator, BOOST_ASIO_HANDLER_TYPE(
Chris@16 731 WriteHandler, void (boost::system::error_code, std::size_t))>(
Chris@16 732 b, init.handler));
Chris@16 733
Chris@16 734 return init.result.get();
Chris@16 735 }
Chris@16 736
Chris@16 737 template <typename AsyncWriteStream, typename Allocator, typename WriteHandler>
Chris@16 738 inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
Chris@16 739 void (boost::system::error_code, std::size_t))
Chris@16 740 async_write(AsyncWriteStream& s,
Chris@16 741 boost::asio::basic_streambuf<Allocator>& b,
Chris@16 742 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
Chris@16 743 {
Chris@16 744 // If you get an error on the following line it means that your handler does
Chris@16 745 // not meet the documented type requirements for a WriteHandler.
Chris@16 746 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
Chris@16 747
Chris@16 748 detail::async_result_init<
Chris@16 749 WriteHandler, void (boost::system::error_code, std::size_t)> init(
Chris@16 750 BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
Chris@16 751
Chris@16 752 async_write(s, b.data(), transfer_all(),
Chris@16 753 detail::write_streambuf_handler<Allocator, BOOST_ASIO_HANDLER_TYPE(
Chris@16 754 WriteHandler, void (boost::system::error_code, std::size_t))>(
Chris@16 755 b, init.handler));
Chris@16 756
Chris@16 757 return init.result.get();
Chris@16 758 }
Chris@16 759
Chris@16 760 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
Chris@16 761
Chris@16 762 } // namespace asio
Chris@16 763 } // namespace boost
Chris@16 764
Chris@16 765 #include <boost/asio/detail/pop_options.hpp>
Chris@16 766
Chris@16 767 #endif // BOOST_ASIO_IMPL_WRITE_HPP