Statistics
| Revision:

root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / asio / impl / write.hpp @ 2486

History | View | Annotate | Download (26 kB)

1
//
2
// impl/write.hpp
3
// ~~~~~~~~~~~~~~
4
//
5
// Copyright (c) 2003-2015 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_IMPL_WRITE_HPP
12
#define BOOST_ASIO_IMPL_WRITE_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/buffer.hpp>
19
#include <boost/asio/completion_condition.hpp>
20
#include <boost/asio/detail/array_fwd.hpp>
21
#include <boost/asio/detail/base_from_completion_cond.hpp>
22
#include <boost/asio/detail/bind_handler.hpp>
23
#include <boost/asio/detail/consuming_buffers.hpp>
24
#include <boost/asio/detail/dependent_type.hpp>
25
#include <boost/asio/detail/handler_alloc_helpers.hpp>
26
#include <boost/asio/detail/handler_cont_helpers.hpp>
27
#include <boost/asio/detail/handler_invoke_helpers.hpp>
28
#include <boost/asio/detail/handler_type_requirements.hpp>
29
#include <boost/asio/detail/throw_error.hpp>
30

    
31
#include <boost/asio/detail/push_options.hpp>
32

    
33
namespace boost {
34
namespace asio {
35

    
36
template <typename SyncWriteStream, typename ConstBufferSequence,
37
    typename CompletionCondition>
38
std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
39
    CompletionCondition completion_condition, boost::system::error_code& ec)
40
{
41
  ec = boost::system::error_code();
42
  boost::asio::detail::consuming_buffers<
43
    const_buffer, ConstBufferSequence> tmp(buffers);
44
  std::size_t total_transferred = 0;
45
  tmp.prepare(detail::adapt_completion_condition_result(
46
        completion_condition(ec, total_transferred)));
47
  while (tmp.begin() != tmp.end())
48
  {
49
    std::size_t bytes_transferred = s.write_some(tmp, ec);
50
    tmp.consume(bytes_transferred);
51
    total_transferred += bytes_transferred;
52
    tmp.prepare(detail::adapt_completion_condition_result(
53
          completion_condition(ec, total_transferred)));
54
  }
55
  return total_transferred;
56
}
57

    
58
template <typename SyncWriteStream, typename ConstBufferSequence>
59
inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers)
60
{
61
  boost::system::error_code ec;
62
  std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);
63
  boost::asio::detail::throw_error(ec, "write");
64
  return bytes_transferred;
65
}
66

    
67
template <typename SyncWriteStream, typename ConstBufferSequence>
68
inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
69
    boost::system::error_code& ec)
70
{
71
  return write(s, buffers, transfer_all(), ec);
72
}
73

    
74
template <typename SyncWriteStream, typename ConstBufferSequence,
75
    typename CompletionCondition>
76
inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
77
    CompletionCondition completion_condition)
78
{
79
  boost::system::error_code ec;
80
  std::size_t bytes_transferred = write(s, buffers, completion_condition, ec);
81
  boost::asio::detail::throw_error(ec, "write");
82
  return bytes_transferred;
83
}
84

    
85
#if !defined(BOOST_ASIO_NO_IOSTREAM)
86

    
87
template <typename SyncWriteStream, typename Allocator,
88
    typename CompletionCondition>
89
std::size_t write(SyncWriteStream& s,
90
    boost::asio::basic_streambuf<Allocator>& b,
91
    CompletionCondition completion_condition, boost::system::error_code& ec)
92
{
93
  std::size_t bytes_transferred = write(s, b.data(), completion_condition, ec);
94
  b.consume(bytes_transferred);
95
  return bytes_transferred;
96
}
97

    
98
template <typename SyncWriteStream, typename Allocator>
99
inline std::size_t write(SyncWriteStream& s,
100
    boost::asio::basic_streambuf<Allocator>& b)
101
{
102
  boost::system::error_code ec;
103
  std::size_t bytes_transferred = write(s, b, transfer_all(), ec);
104
  boost::asio::detail::throw_error(ec, "write");
105
  return bytes_transferred;
106
}
107

    
108
template <typename SyncWriteStream, typename Allocator>
109
inline std::size_t write(SyncWriteStream& s,
110
    boost::asio::basic_streambuf<Allocator>& b,
111
    boost::system::error_code& ec)
112
{
113
  return write(s, b, transfer_all(), ec);
114
}
115

    
116
template <typename SyncWriteStream, typename Allocator,
117
    typename CompletionCondition>
118
inline std::size_t write(SyncWriteStream& s,
119
    boost::asio::basic_streambuf<Allocator>& b,
120
    CompletionCondition completion_condition)
121
{
122
  boost::system::error_code ec;
123
  std::size_t bytes_transferred = write(s, b, completion_condition, ec);
124
  boost::asio::detail::throw_error(ec, "write");
125
  return bytes_transferred;
126
}
127

    
128
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
129

    
130
namespace detail
131
{
132
  template <typename AsyncWriteStream, typename ConstBufferSequence,
133
      typename CompletionCondition, typename WriteHandler>
134
  class write_op
135
    : detail::base_from_completion_cond<CompletionCondition>
136
  {
137
  public:
138
    write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers,
139
        CompletionCondition completion_condition, WriteHandler& handler)
140
      : detail::base_from_completion_cond<
141
          CompletionCondition>(completion_condition),
142
        stream_(stream),
143
        buffers_(buffers),
144
        start_(0),
145
        total_transferred_(0),
146
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
147
    {
148
    }
149

    
150
#if defined(BOOST_ASIO_HAS_MOVE)
151
    write_op(const write_op& other)
152
      : detail::base_from_completion_cond<CompletionCondition>(other),
153
        stream_(other.stream_),
154
        buffers_(other.buffers_),
155
        start_(other.start_),
156
        total_transferred_(other.total_transferred_),
157
        handler_(other.handler_)
158
    {
159
    }
160

    
161
    write_op(write_op&& other)
162
      : detail::base_from_completion_cond<CompletionCondition>(other),
163
        stream_(other.stream_),
164
        buffers_(other.buffers_),
165
        start_(other.start_),
166
        total_transferred_(other.total_transferred_),
167
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
168
    {
169
    }
170
#endif // defined(BOOST_ASIO_HAS_MOVE)
171

    
172
    void operator()(const boost::system::error_code& ec,
173
        std::size_t bytes_transferred, int start = 0)
174
    {
175
      switch (start_ = start)
176
      {
177
        case 1:
178
        buffers_.prepare(this->check_for_completion(ec, total_transferred_));
179
        for (;;)
180
        {
181
          stream_.async_write_some(buffers_,
182
              BOOST_ASIO_MOVE_CAST(write_op)(*this));
183
          return; default:
184
          total_transferred_ += bytes_transferred;
185
          buffers_.consume(bytes_transferred);
186
          buffers_.prepare(this->check_for_completion(ec, total_transferred_));
187
          if ((!ec && bytes_transferred == 0)
188
              || buffers_.begin() == buffers_.end())
189
            break;
190
        }
191

    
192
        handler_(ec, static_cast<const std::size_t&>(total_transferred_));
193
      }
194
    }
195

    
196
  //private:
197
    AsyncWriteStream& stream_;
198
    boost::asio::detail::consuming_buffers<
199
      const_buffer, ConstBufferSequence> buffers_;
200
    int start_;
201
    std::size_t total_transferred_;
202
    WriteHandler handler_;
203
  };
204

    
205
  template <typename AsyncWriteStream,
206
      typename CompletionCondition, typename WriteHandler>
207
  class write_op<AsyncWriteStream, boost::asio::mutable_buffers_1,
208
      CompletionCondition, WriteHandler>
209
    : detail::base_from_completion_cond<CompletionCondition>
210
  {
211
  public:
212
    write_op(AsyncWriteStream& stream,
213
        const boost::asio::mutable_buffers_1& buffers,
214
        CompletionCondition completion_condition,
215
        WriteHandler& handler)
216
      : detail::base_from_completion_cond<
217
          CompletionCondition>(completion_condition),
218
        stream_(stream),
219
        buffer_(buffers),
220
        start_(0),
221
        total_transferred_(0),
222
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
223
    {
224
    }
225

    
226
#if defined(BOOST_ASIO_HAS_MOVE)
227
    write_op(const write_op& other)
228
      : detail::base_from_completion_cond<CompletionCondition>(other),
229
        stream_(other.stream_),
230
        buffer_(other.buffer_),
231
        start_(other.start_),
232
        total_transferred_(other.total_transferred_),
233
        handler_(other.handler_)
234
    {
235
    }
236

    
237
    write_op(write_op&& other)
238
      : detail::base_from_completion_cond<CompletionCondition>(other),
239
        stream_(other.stream_),
240
        buffer_(other.buffer_),
241
        start_(other.start_),
242
        total_transferred_(other.total_transferred_),
243
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
244
    {
245
    }
246
#endif // defined(BOOST_ASIO_HAS_MOVE)
247

    
248
    void operator()(const boost::system::error_code& ec,
249
        std::size_t bytes_transferred, int start = 0)
250
    {
251
      std::size_t n = 0;
252
      switch (start_ = start)
253
      {
254
        case 1:
255
        n = this->check_for_completion(ec, total_transferred_);
256
        for (;;)
257
        {
258
          stream_.async_write_some(
259
              boost::asio::buffer(buffer_ + total_transferred_, n),
260
              BOOST_ASIO_MOVE_CAST(write_op)(*this));
261
          return; default:
262
          total_transferred_ += bytes_transferred;
263
          if ((!ec && bytes_transferred == 0)
264
              || (n = this->check_for_completion(ec, total_transferred_)) == 0
265
              || total_transferred_ == boost::asio::buffer_size(buffer_))
266
            break;
267
        }
268

    
269
        handler_(ec, static_cast<const std::size_t&>(total_transferred_));
270
      }
271
    }
272

    
273
  //private:
274
    AsyncWriteStream& stream_;
275
    boost::asio::mutable_buffer buffer_;
276
    int start_;
277
    std::size_t total_transferred_;
278
    WriteHandler handler_;
279
  };
280

    
281
  template <typename AsyncWriteStream,
282
      typename CompletionCondition, typename WriteHandler>
283
  class write_op<AsyncWriteStream, boost::asio::const_buffers_1,
284
      CompletionCondition, WriteHandler>
285
    : detail::base_from_completion_cond<CompletionCondition>
286
  {
287
  public:
288
    write_op(AsyncWriteStream& stream,
289
        const boost::asio::const_buffers_1& buffers,
290
        CompletionCondition completion_condition,
291
        WriteHandler& handler)
292
      : detail::base_from_completion_cond<
293
          CompletionCondition>(completion_condition),
294
        stream_(stream),
295
        buffer_(buffers),
296
        start_(0),
297
        total_transferred_(0),
298
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
299
    {
300
    }
301

    
302
#if defined(BOOST_ASIO_HAS_MOVE)
303
    write_op(const write_op& other)
304
      : detail::base_from_completion_cond<CompletionCondition>(other),
305
        stream_(other.stream_),
306
        buffer_(other.buffer_),
307
        start_(other.start_),
308
        total_transferred_(other.total_transferred_),
309
        handler_(other.handler_)
310
    {
311
    }
312

    
313
    write_op(write_op&& other)
314
      : detail::base_from_completion_cond<CompletionCondition>(other),
315
        stream_(other.stream_),
316
        buffer_(other.buffer_),
317
        start_(other.start_),
318
        total_transferred_(other.total_transferred_),
319
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
320
    {
321
    }
322
#endif // defined(BOOST_ASIO_HAS_MOVE)
323

    
324
    void operator()(const boost::system::error_code& ec,
325
        std::size_t bytes_transferred, int start = 0)
326
    {
327
      std::size_t n = 0;
328
      switch (start_ = start)
329
      {
330
        case 1:
331
        n = this->check_for_completion(ec, total_transferred_);
332
        for (;;)
333
        {
334
          stream_.async_write_some(
335
              boost::asio::buffer(buffer_ + total_transferred_, n),
336
              BOOST_ASIO_MOVE_CAST(write_op)(*this));
337
          return; default:
338
          total_transferred_ += bytes_transferred;
339
          if ((!ec && bytes_transferred == 0)
340
              || (n = this->check_for_completion(ec, total_transferred_)) == 0
341
              || total_transferred_ == boost::asio::buffer_size(buffer_))
342
            break;
343
        }
344

    
345
        handler_(ec, static_cast<const std::size_t&>(total_transferred_));
346
      }
347
    }
348

    
349
  //private:
350
    AsyncWriteStream& stream_;
351
    boost::asio::const_buffer buffer_;
352
    int start_;
353
    std::size_t total_transferred_;
354
    WriteHandler handler_;
355
  };
356

    
357
  template <typename AsyncWriteStream, typename Elem,
358
      typename CompletionCondition, typename WriteHandler>
359
  class write_op<AsyncWriteStream, boost::array<Elem, 2>,
360
      CompletionCondition, WriteHandler>
361
    : detail::base_from_completion_cond<CompletionCondition>
362
  {
363
  public:
364
    write_op(AsyncWriteStream& stream, const boost::array<Elem, 2>& buffers,
365
        CompletionCondition completion_condition, WriteHandler& handler)
366
      : detail::base_from_completion_cond<
367
          CompletionCondition>(completion_condition),
368
        stream_(stream),
369
        buffers_(buffers),
370
        start_(0),
371
        total_transferred_(0),
372
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
373
    {
374
    }
375

    
376
#if defined(BOOST_ASIO_HAS_MOVE)
377
    write_op(const write_op& other)
378
      : detail::base_from_completion_cond<CompletionCondition>(other),
379
        stream_(other.stream_),
380
        buffers_(other.buffers_),
381
        start_(other.start_),
382
        total_transferred_(other.total_transferred_),
383
        handler_(other.handler_)
384
    {
385
    }
386

    
387
    write_op(write_op&& other)
388
      : detail::base_from_completion_cond<CompletionCondition>(other),
389
        stream_(other.stream_),
390
        buffers_(other.buffers_),
391
        start_(other.start_),
392
        total_transferred_(other.total_transferred_),
393
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
394
    {
395
    }
396
#endif // defined(BOOST_ASIO_HAS_MOVE)
397

    
398
    void operator()(const boost::system::error_code& ec,
399
        std::size_t bytes_transferred, int start = 0)
400
    {
401
      typename boost::asio::detail::dependent_type<Elem,
402
          boost::array<boost::asio::const_buffer, 2> >::type bufs = {{
403
        boost::asio::const_buffer(buffers_[0]),
404
        boost::asio::const_buffer(buffers_[1]) }};
405
      std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]);
406
      std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]);
407
      std::size_t n = 0;
408
      switch (start_ = start)
409
      {
410
        case 1:
411
        n = this->check_for_completion(ec, total_transferred_);
412
        for (;;)
413
        {
414
          bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n);
415
          bufs[1] = boost::asio::buffer(
416
              bufs[1] + (total_transferred_ < buffer_size0
417
                ? 0 : total_transferred_ - buffer_size0),
418
              n - boost::asio::buffer_size(bufs[0]));
419
          stream_.async_write_some(bufs, BOOST_ASIO_MOVE_CAST(write_op)(*this));
420
          return; default:
421
          total_transferred_ += bytes_transferred;
422
          if ((!ec && bytes_transferred == 0)
423
              || (n = this->check_for_completion(ec, total_transferred_)) == 0
424
              || total_transferred_ == buffer_size0 + buffer_size1)
425
            break;
426
        }
427

    
428
        handler_(ec, static_cast<const std::size_t&>(total_transferred_));
429
      }
430
    }
431

    
432
  //private:
433
    AsyncWriteStream& stream_;
434
    boost::array<Elem, 2> buffers_;
435
    int start_;
436
    std::size_t total_transferred_;
437
    WriteHandler handler_;
438
  };
439

    
440
#if defined(BOOST_ASIO_HAS_STD_ARRAY)
441

    
442
  template <typename AsyncWriteStream, typename Elem,
443
      typename CompletionCondition, typename WriteHandler>
444
  class write_op<AsyncWriteStream, std::array<Elem, 2>,
445
      CompletionCondition, WriteHandler>
446
    : detail::base_from_completion_cond<CompletionCondition>
447
  {
448
  public:
449
    write_op(AsyncWriteStream& stream, const std::array<Elem, 2>& buffers,
450
        CompletionCondition completion_condition, WriteHandler& handler)
451
      : detail::base_from_completion_cond<
452
          CompletionCondition>(completion_condition),
453
        stream_(stream),
454
        buffers_(buffers),
455
        start_(0),
456
        total_transferred_(0),
457
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
458
    {
459
    }
460

    
461
#if defined(BOOST_ASIO_HAS_MOVE)
462
    write_op(const write_op& other)
463
      : detail::base_from_completion_cond<CompletionCondition>(other),
464
        stream_(other.stream_),
465
        buffers_(other.buffers_),
466
        start_(other.start_),
467
        total_transferred_(other.total_transferred_),
468
        handler_(other.handler_)
469
    {
470
    }
471

    
472
    write_op(write_op&& other)
473
      : detail::base_from_completion_cond<CompletionCondition>(other),
474
        stream_(other.stream_),
475
        buffers_(other.buffers_),
476
        start_(other.start_),
477
        total_transferred_(other.total_transferred_),
478
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
479
    {
480
    }
481
#endif // defined(BOOST_ASIO_HAS_MOVE)
482

    
483
    void operator()(const boost::system::error_code& ec,
484
        std::size_t bytes_transferred, int start = 0)
485
    {
486
      typename boost::asio::detail::dependent_type<Elem,
487
          std::array<boost::asio::const_buffer, 2> >::type bufs = {{
488
        boost::asio::const_buffer(buffers_[0]),
489
        boost::asio::const_buffer(buffers_[1]) }};
490
      std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]);
491
      std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]);
492
      std::size_t n = 0;
493
      switch (start_ = start)
494
      {
495
        case 1:
496
        n = this->check_for_completion(ec, total_transferred_);
497
        for (;;)
498
        {
499
          bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n);
500
          bufs[1] = boost::asio::buffer(
501
              bufs[1] + (total_transferred_ < buffer_size0
502
                ? 0 : total_transferred_ - buffer_size0),
503
              n - boost::asio::buffer_size(bufs[0]));
504
          stream_.async_write_some(bufs, BOOST_ASIO_MOVE_CAST(write_op)(*this));
505
          return; default:
506
          total_transferred_ += bytes_transferred;
507
          if ((!ec && bytes_transferred == 0)
508
              || (n = this->check_for_completion(ec, total_transferred_)) == 0
509
              || total_transferred_ == buffer_size0 + buffer_size1)
510
            break;
511
        }
512

    
513
        handler_(ec, static_cast<const std::size_t&>(total_transferred_));
514
      }
515
    }
516

    
517
  //private:
518
    AsyncWriteStream& stream_;
519
    std::array<Elem, 2> buffers_;
520
    int start_;
521
    std::size_t total_transferred_;
522
    WriteHandler handler_;
523
  };
524

    
525
#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
526

    
527
  template <typename AsyncWriteStream, typename ConstBufferSequence,
528
      typename CompletionCondition, typename WriteHandler>
529
  inline void* asio_handler_allocate(std::size_t size,
530
      write_op<AsyncWriteStream, ConstBufferSequence,
531
        CompletionCondition, WriteHandler>* this_handler)
532
  {
533
    return boost_asio_handler_alloc_helpers::allocate(
534
        size, this_handler->handler_);
535
  }
536

    
537
  template <typename AsyncWriteStream, typename ConstBufferSequence,
538
      typename CompletionCondition, typename WriteHandler>
539
  inline void asio_handler_deallocate(void* pointer, std::size_t size,
540
      write_op<AsyncWriteStream, ConstBufferSequence,
541
        CompletionCondition, WriteHandler>* this_handler)
542
  {
543
    boost_asio_handler_alloc_helpers::deallocate(
544
        pointer, size, this_handler->handler_);
545
  }
546

    
547
  template <typename AsyncWriteStream, typename ConstBufferSequence,
548
      typename CompletionCondition, typename WriteHandler>
549
  inline bool asio_handler_is_continuation(
550
      write_op<AsyncWriteStream, ConstBufferSequence,
551
        CompletionCondition, WriteHandler>* this_handler)
552
  {
553
    return this_handler->start_ == 0 ? true
554
      : boost_asio_handler_cont_helpers::is_continuation(
555
          this_handler->handler_);
556
  }
557

    
558
  template <typename Function, typename AsyncWriteStream,
559
      typename ConstBufferSequence, typename CompletionCondition,
560
      typename WriteHandler>
561
  inline void asio_handler_invoke(Function& function,
562
      write_op<AsyncWriteStream, ConstBufferSequence,
563
        CompletionCondition, WriteHandler>* this_handler)
564
  {
565
    boost_asio_handler_invoke_helpers::invoke(
566
        function, this_handler->handler_);
567
  }
568

    
569
  template <typename Function, typename AsyncWriteStream,
570
      typename ConstBufferSequence, typename CompletionCondition,
571
      typename WriteHandler>
572
  inline void asio_handler_invoke(const Function& function,
573
      write_op<AsyncWriteStream, ConstBufferSequence,
574
        CompletionCondition, WriteHandler>* this_handler)
575
  {
576
    boost_asio_handler_invoke_helpers::invoke(
577
        function, this_handler->handler_);
578
  }
579
} // namespace detail
580

    
581
template <typename AsyncWriteStream, typename ConstBufferSequence,
582
  typename CompletionCondition, typename WriteHandler>
583
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
584
    void (boost::system::error_code, std::size_t))
585
async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
586
    CompletionCondition completion_condition,
587
    BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
588
{
589
  // If you get an error on the following line it means that your handler does
590
  // not meet the documented type requirements for a WriteHandler.
591
  BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
592

    
593
  detail::async_result_init<
594
    WriteHandler, void (boost::system::error_code, std::size_t)> init(
595
      BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
596

    
597
  detail::write_op<AsyncWriteStream, ConstBufferSequence,
598
    CompletionCondition, BOOST_ASIO_HANDLER_TYPE(
599
      WriteHandler, void (boost::system::error_code, std::size_t))>(
600
        s, buffers, completion_condition, init.handler)(
601
          boost::system::error_code(), 0, 1);
602

    
603
  return init.result.get();
604
}
605

    
606
template <typename AsyncWriteStream, typename ConstBufferSequence,
607
    typename WriteHandler>
608
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
609
    void (boost::system::error_code, std::size_t))
610
async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
611
    BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
612
{
613
  // If you get an error on the following line it means that your handler does
614
  // not meet the documented type requirements for a WriteHandler.
615
  BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
616

    
617
  detail::async_result_init<
618
    WriteHandler, void (boost::system::error_code, std::size_t)> init(
619
      BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
620

    
621
  detail::write_op<AsyncWriteStream, ConstBufferSequence,
622
    detail::transfer_all_t, BOOST_ASIO_HANDLER_TYPE(
623
      WriteHandler, void (boost::system::error_code, std::size_t))>(
624
        s, buffers, transfer_all(), init.handler)(
625
          boost::system::error_code(), 0, 1);
626

    
627
  return init.result.get();
628
}
629

    
630
#if !defined(BOOST_ASIO_NO_IOSTREAM)
631

    
632
namespace detail
633
{
634
  template <typename Allocator, typename WriteHandler>
635
  class write_streambuf_handler
636
  {
637
  public:
638
    write_streambuf_handler(boost::asio::basic_streambuf<Allocator>& streambuf,
639
        WriteHandler& handler)
640
      : streambuf_(streambuf),
641
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
642
    {
643
    }
644

    
645
#if defined(BOOST_ASIO_HAS_MOVE)
646
    write_streambuf_handler(const write_streambuf_handler& other)
647
      : streambuf_(other.streambuf_),
648
        handler_(other.handler_)
649
    {
650
    }
651

    
652
    write_streambuf_handler(write_streambuf_handler&& other)
653
      : streambuf_(other.streambuf_),
654
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
655
    {
656
    }
657
#endif // defined(BOOST_ASIO_HAS_MOVE)
658

    
659
    void operator()(const boost::system::error_code& ec,
660
        const std::size_t bytes_transferred)
661
    {
662
      streambuf_.consume(bytes_transferred);
663
      handler_(ec, bytes_transferred);
664
    }
665

    
666
  //private:
667
    boost::asio::basic_streambuf<Allocator>& streambuf_;
668
    WriteHandler handler_;
669
  };
670

    
671
  template <typename Allocator, typename WriteHandler>
672
  inline void* asio_handler_allocate(std::size_t size,
673
      write_streambuf_handler<Allocator, WriteHandler>* this_handler)
674
  {
675
    return boost_asio_handler_alloc_helpers::allocate(
676
        size, this_handler->handler_);
677
  }
678

    
679
  template <typename Allocator, typename WriteHandler>
680
  inline void asio_handler_deallocate(void* pointer, std::size_t size,
681
      write_streambuf_handler<Allocator, WriteHandler>* this_handler)
682
  {
683
    boost_asio_handler_alloc_helpers::deallocate(
684
        pointer, size, this_handler->handler_);
685
  }
686

    
687
  template <typename Allocator, typename WriteHandler>
688
  inline bool asio_handler_is_continuation(
689
      write_streambuf_handler<Allocator, WriteHandler>* this_handler)
690
  {
691
    return boost_asio_handler_cont_helpers::is_continuation(
692
        this_handler->handler_);
693
  }
694

    
695
  template <typename Function, typename Allocator, typename WriteHandler>
696
  inline void asio_handler_invoke(Function& function,
697
      write_streambuf_handler<Allocator, WriteHandler>* this_handler)
698
  {
699
    boost_asio_handler_invoke_helpers::invoke(
700
        function, this_handler->handler_);
701
  }
702

    
703
  template <typename Function, typename Allocator, typename WriteHandler>
704
  inline void asio_handler_invoke(const Function& function,
705
      write_streambuf_handler<Allocator, WriteHandler>* this_handler)
706
  {
707
    boost_asio_handler_invoke_helpers::invoke(
708
        function, this_handler->handler_);
709
  }
710
} // namespace detail
711

    
712
template <typename AsyncWriteStream, typename Allocator,
713
    typename CompletionCondition, typename WriteHandler>
714
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
715
    void (boost::system::error_code, std::size_t))
716
async_write(AsyncWriteStream& s,
717
    boost::asio::basic_streambuf<Allocator>& b,
718
    CompletionCondition completion_condition,
719
    BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
720
{
721
  // If you get an error on the following line it means that your handler does
722
  // not meet the documented type requirements for a WriteHandler.
723
  BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
724

    
725
  detail::async_result_init<
726
    WriteHandler, void (boost::system::error_code, std::size_t)> init(
727
      BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
728

    
729
  async_write(s, b.data(), completion_condition,
730
    detail::write_streambuf_handler<Allocator, BOOST_ASIO_HANDLER_TYPE(
731
      WriteHandler, void (boost::system::error_code, std::size_t))>(
732
        b, init.handler));
733

    
734
  return init.result.get();
735
}
736

    
737
template <typename AsyncWriteStream, typename Allocator, typename WriteHandler>
738
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
739
    void (boost::system::error_code, std::size_t))
740
async_write(AsyncWriteStream& s,
741
    boost::asio::basic_streambuf<Allocator>& b,
742
    BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
743
{
744
  // If you get an error on the following line it means that your handler does
745
  // not meet the documented type requirements for a WriteHandler.
746
  BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
747

    
748
  detail::async_result_init<
749
    WriteHandler, void (boost::system::error_code, std::size_t)> init(
750
      BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
751

    
752
  async_write(s, b.data(), transfer_all(),
753
    detail::write_streambuf_handler<Allocator, BOOST_ASIO_HANDLER_TYPE(
754
      WriteHandler, void (boost::system::error_code, std::size_t))>(
755
        b, init.handler));
756

    
757
  return init.result.get();
758
}
759

    
760
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
761

    
762
} // namespace asio
763
} // namespace boost
764

    
765
#include <boost/asio/detail/pop_options.hpp>
766

    
767
#endif // BOOST_ASIO_IMPL_WRITE_HPP