Statistics
| Revision:

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

History | View | Annotate | Download (29 kB)

1
//
2
// impl/write_at.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_AT_HPP
12
#define BOOST_ASIO_IMPL_WRITE_AT_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 SyncRandomAccessWriteDevice, typename ConstBufferSequence,
37
    typename CompletionCondition>
38
std::size_t write_at(SyncRandomAccessWriteDevice& d,
39
    uint64_t offset, const ConstBufferSequence& buffers,
40
    CompletionCondition completion_condition, boost::system::error_code& ec)
41
{
42
  ec = boost::system::error_code();
43
  boost::asio::detail::consuming_buffers<
44
    const_buffer, ConstBufferSequence> tmp(buffers);
45
  std::size_t total_transferred = 0;
46
  tmp.prepare(detail::adapt_completion_condition_result(
47
        completion_condition(ec, total_transferred)));
48
  while (tmp.begin() != tmp.end())
49
  {
50
    std::size_t bytes_transferred = d.write_some_at(
51
        offset + total_transferred, tmp, ec);
52
    tmp.consume(bytes_transferred);
53
    total_transferred += bytes_transferred;
54
    tmp.prepare(detail::adapt_completion_condition_result(
55
          completion_condition(ec, total_transferred)));
56
  }
57
  return total_transferred;
58
}
59

    
60
template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>
61
inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
62
    uint64_t offset, const ConstBufferSequence& buffers)
63
{
64
  boost::system::error_code ec;
65
  std::size_t bytes_transferred = write_at(
66
      d, offset, buffers, transfer_all(), ec);
67
  boost::asio::detail::throw_error(ec, "write_at");
68
  return bytes_transferred;
69
}
70

    
71
template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>
72
inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
73
    uint64_t offset, const ConstBufferSequence& buffers,
74
    boost::system::error_code& ec)
75
{
76
  return write_at(d, offset, buffers, transfer_all(), ec);
77
}
78

    
79
template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
80
    typename CompletionCondition>
81
inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
82
    uint64_t offset, const ConstBufferSequence& buffers,
83
    CompletionCondition completion_condition)
84
{
85
  boost::system::error_code ec;
86
  std::size_t bytes_transferred = write_at(
87
      d, offset, buffers, completion_condition, ec);
88
  boost::asio::detail::throw_error(ec, "write_at");
89
  return bytes_transferred;
90
}
91

    
92
#if !defined(BOOST_ASIO_NO_IOSTREAM)
93

    
94
template <typename SyncRandomAccessWriteDevice, typename Allocator,
95
    typename CompletionCondition>
96
std::size_t write_at(SyncRandomAccessWriteDevice& d,
97
    uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
98
    CompletionCondition completion_condition, boost::system::error_code& ec)
99
{
100
  std::size_t bytes_transferred = write_at(
101
      d, offset, b.data(), completion_condition, ec);
102
  b.consume(bytes_transferred);
103
  return bytes_transferred;
104
}
105

    
106
template <typename SyncRandomAccessWriteDevice, typename Allocator>
107
inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
108
    uint64_t offset, boost::asio::basic_streambuf<Allocator>& b)
109
{
110
  boost::system::error_code ec;
111
  std::size_t bytes_transferred = write_at(d, offset, b, transfer_all(), ec);
112
  boost::asio::detail::throw_error(ec, "write_at");
113
  return bytes_transferred;
114
}
115

    
116
template <typename SyncRandomAccessWriteDevice, typename Allocator>
117
inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
118
    uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
119
    boost::system::error_code& ec)
120
{
121
  return write_at(d, offset, b, transfer_all(), ec);
122
}
123

    
124
template <typename SyncRandomAccessWriteDevice, typename Allocator,
125
    typename CompletionCondition>
126
inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
127
    uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
128
    CompletionCondition completion_condition)
129
{
130
  boost::system::error_code ec;
131
  std::size_t bytes_transferred = write_at(
132
      d, offset, b, completion_condition, ec);
133
  boost::asio::detail::throw_error(ec, "write_at");
134
  return bytes_transferred;
135
}
136

    
137
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
138

    
139
namespace detail
140
{
141
  template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
142
      typename CompletionCondition, typename WriteHandler>
143
  class write_at_op
144
    : detail::base_from_completion_cond<CompletionCondition>
145
  {
146
  public:
147
    write_at_op(AsyncRandomAccessWriteDevice& device,
148
        uint64_t offset, const ConstBufferSequence& buffers,
149
        CompletionCondition completion_condition, WriteHandler& handler)
150
      : detail::base_from_completion_cond<
151
          CompletionCondition>(completion_condition),
152
        device_(device),
153
        offset_(offset),
154
        buffers_(buffers),
155
        start_(0),
156
        total_transferred_(0),
157
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
158
    {
159
    }
160

    
161
#if defined(BOOST_ASIO_HAS_MOVE)
162
    write_at_op(const write_at_op& other)
163
      : detail::base_from_completion_cond<CompletionCondition>(other),
164
        device_(other.device_),
165
        offset_(other.offset_),
166
        buffers_(other.buffers_),
167
        start_(other.start_),
168
        total_transferred_(other.total_transferred_),
169
        handler_(other.handler_)
170
    {
171
    }
172

    
173
    write_at_op(write_at_op&& other)
174
      : detail::base_from_completion_cond<CompletionCondition>(other),
175
        device_(other.device_),
176
        offset_(other.offset_),
177
        buffers_(other.buffers_),
178
        start_(other.start_),
179
        total_transferred_(other.total_transferred_),
180
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
181
    {
182
    }
183
#endif // defined(BOOST_ASIO_HAS_MOVE)
184

    
185
    void operator()(const boost::system::error_code& ec,
186
        std::size_t bytes_transferred, int start = 0)
187
    {
188
      switch (start_ = start)
189
      {
190
        case 1:
191
        buffers_.prepare(this->check_for_completion(ec, total_transferred_));
192
        for (;;)
193
        {
194
          device_.async_write_some_at(
195
              offset_ + total_transferred_, buffers_,
196
              BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
197
          return; default:
198
          total_transferred_ += bytes_transferred;
199
          buffers_.consume(bytes_transferred);
200
          buffers_.prepare(this->check_for_completion(ec, total_transferred_));
201
          if ((!ec && bytes_transferred == 0)
202
              || buffers_.begin() == buffers_.end())
203
            break;
204
        }
205

    
206
        handler_(ec, static_cast<const std::size_t&>(total_transferred_));
207
      }
208
    }
209

    
210
  //private:
211
    AsyncRandomAccessWriteDevice& device_;
212
    uint64_t offset_;
213
    boost::asio::detail::consuming_buffers<
214
      const_buffer, ConstBufferSequence> buffers_;
215
    int start_;
216
    std::size_t total_transferred_;
217
    WriteHandler handler_;
218
  };
219

    
220
  template <typename AsyncRandomAccessWriteDevice,
221
      typename CompletionCondition, typename WriteHandler>
222
  class write_at_op<AsyncRandomAccessWriteDevice,
223
      boost::asio::mutable_buffers_1, CompletionCondition, WriteHandler>
224
    : detail::base_from_completion_cond<CompletionCondition>
225
  {
226
  public:
227
    write_at_op(AsyncRandomAccessWriteDevice& device,
228
        uint64_t offset, const boost::asio::mutable_buffers_1& buffers,
229
        CompletionCondition completion_condition,
230
        WriteHandler& handler)
231
      : detail::base_from_completion_cond<
232
          CompletionCondition>(completion_condition),
233
        device_(device),
234
        offset_(offset),
235
        buffer_(buffers),
236
        start_(0),
237
        total_transferred_(0),
238
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
239
    {
240
    }
241

    
242
#if defined(BOOST_ASIO_HAS_MOVE)
243
    write_at_op(const write_at_op& other)
244
      : detail::base_from_completion_cond<CompletionCondition>(other),
245
        device_(other.device_),
246
        offset_(other.offset_),
247
        buffer_(other.buffer_),
248
        start_(other.start_),
249
        total_transferred_(other.total_transferred_),
250
        handler_(other.handler_)
251
    {
252
    }
253

    
254
    write_at_op(write_at_op&& other)
255
      : detail::base_from_completion_cond<CompletionCondition>(other),
256
        device_(other.device_),
257
        offset_(other.offset_),
258
        buffer_(other.buffer_),
259
        start_(other.start_),
260
        total_transferred_(other.total_transferred_),
261
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
262
    {
263
    }
264
#endif // defined(BOOST_ASIO_HAS_MOVE)
265

    
266
    void operator()(const boost::system::error_code& ec,
267
        std::size_t bytes_transferred, int start = 0)
268
    {
269
      std::size_t n = 0;
270
      switch (start_ = start)
271
      {
272
        case 1:
273
        n = this->check_for_completion(ec, total_transferred_);
274
        for (;;)
275
        {
276
          device_.async_write_some_at(offset_ + total_transferred_,
277
              boost::asio::buffer(buffer_ + total_transferred_, n),
278
              BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
279
          return; default:
280
          total_transferred_ += bytes_transferred;
281
          if ((!ec && bytes_transferred == 0)
282
              || (n = this->check_for_completion(ec, total_transferred_)) == 0
283
              || total_transferred_ == boost::asio::buffer_size(buffer_))
284
            break;
285
        }
286

    
287
        handler_(ec, static_cast<const std::size_t&>(total_transferred_));
288
      }
289
    }
290

    
291
  //private:
292
    AsyncRandomAccessWriteDevice& device_;
293
    uint64_t offset_;
294
    boost::asio::mutable_buffer buffer_;
295
    int start_;
296
    std::size_t total_transferred_;
297
    WriteHandler handler_;
298
  };
299

    
300
  template <typename AsyncRandomAccessWriteDevice,
301
      typename CompletionCondition, typename WriteHandler>
302
  class write_at_op<AsyncRandomAccessWriteDevice, boost::asio::const_buffers_1,
303
      CompletionCondition, WriteHandler>
304
    : detail::base_from_completion_cond<CompletionCondition>
305
  {
306
  public:
307
    write_at_op(AsyncRandomAccessWriteDevice& device,
308
        uint64_t offset, const boost::asio::const_buffers_1& buffers,
309
        CompletionCondition completion_condition,
310
        WriteHandler& handler)
311
      : detail::base_from_completion_cond<
312
          CompletionCondition>(completion_condition),
313
        device_(device),
314
        offset_(offset),
315
        buffer_(buffers),
316
        start_(0),
317
        total_transferred_(0),
318
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
319
    {
320
    }
321

    
322
#if defined(BOOST_ASIO_HAS_MOVE)
323
    write_at_op(const write_at_op& other)
324
      : detail::base_from_completion_cond<CompletionCondition>(other),
325
        device_(other.device_),
326
        offset_(other.offset_),
327
        buffer_(other.buffer_),
328
        start_(other.start_),
329
        total_transferred_(other.total_transferred_),
330
        handler_(other.handler_)
331
    {
332
    }
333

    
334
    write_at_op(write_at_op&& other)
335
      : detail::base_from_completion_cond<CompletionCondition>(other),
336
        device_(other.device_),
337
        offset_(other.offset_),
338
        buffer_(other.buffer_),
339
        start_(other.start_),
340
        total_transferred_(other.total_transferred_),
341
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
342
    {
343
    }
344
#endif // defined(BOOST_ASIO_HAS_MOVE)
345

    
346
    void operator()(const boost::system::error_code& ec,
347
        std::size_t bytes_transferred, int start = 0)
348
    {
349
      std::size_t n = 0;
350
      switch (start_ = start)
351
      {
352
        case 1:
353
        n = this->check_for_completion(ec, total_transferred_);
354
        for (;;)
355
        {
356
          device_.async_write_some_at(offset_ + total_transferred_,
357
              boost::asio::buffer(buffer_ + total_transferred_, n),
358
              BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
359
          return; default:
360
          total_transferred_ += bytes_transferred;
361
          if ((!ec && bytes_transferred == 0)
362
              || (n = this->check_for_completion(ec, total_transferred_)) == 0
363
              || total_transferred_ == boost::asio::buffer_size(buffer_))
364
            break;
365
        }
366

    
367
        handler_(ec, static_cast<const std::size_t&>(total_transferred_));
368
      }
369
    }
370

    
371
  //private:
372
    AsyncRandomAccessWriteDevice& device_;
373
    uint64_t offset_;
374
    boost::asio::const_buffer buffer_;
375
    int start_;
376
    std::size_t total_transferred_;
377
    WriteHandler handler_;
378
  };
379

    
380
  template <typename AsyncRandomAccessWriteDevice, typename Elem,
381
      typename CompletionCondition, typename WriteHandler>
382
  class write_at_op<AsyncRandomAccessWriteDevice, boost::array<Elem, 2>,
383
      CompletionCondition, WriteHandler>
384
    : detail::base_from_completion_cond<CompletionCondition>
385
  {
386
  public:
387
    write_at_op(AsyncRandomAccessWriteDevice& device,
388
        uint64_t offset, const boost::array<Elem, 2>& buffers,
389
        CompletionCondition completion_condition, WriteHandler& handler)
390
      : detail::base_from_completion_cond<
391
          CompletionCondition>(completion_condition),
392
        device_(device),
393
        offset_(offset),
394
        buffers_(buffers),
395
        start_(0),
396
        total_transferred_(0),
397
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
398
    {
399
    }
400

    
401
#if defined(BOOST_ASIO_HAS_MOVE)
402
    write_at_op(const write_at_op& other)
403
      : detail::base_from_completion_cond<CompletionCondition>(other),
404
        device_(other.device_),
405
        offset_(other.offset_),
406
        buffers_(other.buffers_),
407
        start_(other.start_),
408
        total_transferred_(other.total_transferred_),
409
        handler_(other.handler_)
410
    {
411
    }
412

    
413
    write_at_op(write_at_op&& other)
414
      : detail::base_from_completion_cond<CompletionCondition>(other),
415
        device_(other.device_),
416
        offset_(other.offset_),
417
        buffers_(other.buffers_),
418
        start_(other.start_),
419
        total_transferred_(other.total_transferred_),
420
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
421
    {
422
    }
423
#endif // defined(BOOST_ASIO_HAS_MOVE)
424

    
425
    void operator()(const boost::system::error_code& ec,
426
        std::size_t bytes_transferred, int start = 0)
427
    {
428
      typename boost::asio::detail::dependent_type<Elem,
429
          boost::array<boost::asio::const_buffer, 2> >::type bufs = {{
430
        boost::asio::const_buffer(buffers_[0]),
431
        boost::asio::const_buffer(buffers_[1]) }};
432
      std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]);
433
      std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]);
434
      std::size_t n = 0;
435
      switch (start_ = start)
436
      {
437
        case 1:
438
        n = this->check_for_completion(ec, total_transferred_);
439
        for (;;)
440
        {
441
          bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n);
442
          bufs[1] = boost::asio::buffer(
443
              bufs[1] + (total_transferred_ < buffer_size0
444
                ? 0 : total_transferred_ - buffer_size0),
445
              n - boost::asio::buffer_size(bufs[0]));
446
          device_.async_write_some_at(offset_ + total_transferred_,
447
              bufs, BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
448
          return; default:
449
          total_transferred_ += bytes_transferred;
450
          if ((!ec && bytes_transferred == 0)
451
              || (n = this->check_for_completion(ec, total_transferred_)) == 0
452
              || total_transferred_ == buffer_size0 + buffer_size1)
453
            break;
454
        }
455

    
456
        handler_(ec, static_cast<const std::size_t&>(total_transferred_));
457
      }
458
    }
459

    
460
  //private:
461
    AsyncRandomAccessWriteDevice& device_;
462
    uint64_t offset_;
463
    boost::array<Elem, 2> buffers_;
464
    int start_;
465
    std::size_t total_transferred_;
466
    WriteHandler handler_;
467
  };
468

    
469
#if defined(BOOST_ASIO_HAS_STD_ARRAY)
470

    
471
  template <typename AsyncRandomAccessWriteDevice, typename Elem,
472
      typename CompletionCondition, typename WriteHandler>
473
  class write_at_op<AsyncRandomAccessWriteDevice, std::array<Elem, 2>,
474
      CompletionCondition, WriteHandler>
475
    : detail::base_from_completion_cond<CompletionCondition>
476
  {
477
  public:
478
    write_at_op(AsyncRandomAccessWriteDevice& device,
479
        uint64_t offset, const std::array<Elem, 2>& buffers,
480
        CompletionCondition completion_condition, WriteHandler& handler)
481
      : detail::base_from_completion_cond<
482
          CompletionCondition>(completion_condition),
483
        device_(device),
484
        offset_(offset),
485
        buffers_(buffers),
486
        start_(0),
487
        total_transferred_(0),
488
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
489
    {
490
    }
491

    
492
#if defined(BOOST_ASIO_HAS_MOVE)
493
    write_at_op(const write_at_op& other)
494
      : detail::base_from_completion_cond<CompletionCondition>(other),
495
        device_(other.device_),
496
        offset_(other.offset_),
497
        buffers_(other.buffers_),
498
        start_(other.start_),
499
        total_transferred_(other.total_transferred_),
500
        handler_(other.handler_)
501
    {
502
    }
503

    
504
    write_at_op(write_at_op&& other)
505
      : detail::base_from_completion_cond<CompletionCondition>(other),
506
        device_(other.device_),
507
        offset_(other.offset_),
508
        buffers_(other.buffers_),
509
        start_(other.start_),
510
        total_transferred_(other.total_transferred_),
511
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
512
    {
513
    }
514
#endif // defined(BOOST_ASIO_HAS_MOVE)
515

    
516
    void operator()(const boost::system::error_code& ec,
517
        std::size_t bytes_transferred, int start = 0)
518
    {
519
      typename boost::asio::detail::dependent_type<Elem,
520
          std::array<boost::asio::const_buffer, 2> >::type bufs = {{
521
        boost::asio::const_buffer(buffers_[0]),
522
        boost::asio::const_buffer(buffers_[1]) }};
523
      std::size_t buffer_size0 = boost::asio::buffer_size(bufs[0]);
524
      std::size_t buffer_size1 = boost::asio::buffer_size(bufs[1]);
525
      std::size_t n = 0;
526
      switch (start_ = start)
527
      {
528
        case 1:
529
        n = this->check_for_completion(ec, total_transferred_);
530
        for (;;)
531
        {
532
          bufs[0] = boost::asio::buffer(bufs[0] + total_transferred_, n);
533
          bufs[1] = boost::asio::buffer(
534
              bufs[1] + (total_transferred_ < buffer_size0
535
                ? 0 : total_transferred_ - buffer_size0),
536
              n - boost::asio::buffer_size(bufs[0]));
537
          device_.async_write_some_at(offset_ + total_transferred_,
538
              bufs, BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
539
          return; default:
540
          total_transferred_ += bytes_transferred;
541
          if ((!ec && bytes_transferred == 0)
542
              || (n = this->check_for_completion(ec, total_transferred_)) == 0
543
              || total_transferred_ == buffer_size0 + buffer_size1)
544
            break;
545
        }
546

    
547
        handler_(ec, static_cast<const std::size_t&>(total_transferred_));
548
      }
549
    }
550

    
551
  //private:
552
    AsyncRandomAccessWriteDevice& device_;
553
    uint64_t offset_;
554
    std::array<Elem, 2> buffers_;
555
    int start_;
556
    std::size_t total_transferred_;
557
    WriteHandler handler_;
558
  };
559

    
560
#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
561

    
562
  template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
563
      typename CompletionCondition, typename WriteHandler>
564
  inline void* asio_handler_allocate(std::size_t size,
565
      write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
566
        CompletionCondition, WriteHandler>* this_handler)
567
  {
568
    return boost_asio_handler_alloc_helpers::allocate(
569
        size, this_handler->handler_);
570
  }
571

    
572
  template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
573
      typename CompletionCondition, typename WriteHandler>
574
  inline void asio_handler_deallocate(void* pointer, std::size_t size,
575
      write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
576
        CompletionCondition, WriteHandler>* this_handler)
577
  {
578
    boost_asio_handler_alloc_helpers::deallocate(
579
        pointer, size, this_handler->handler_);
580
  }
581

    
582
  template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
583
      typename CompletionCondition, typename WriteHandler>
584
  inline bool asio_handler_is_continuation(
585
      write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
586
        CompletionCondition, WriteHandler>* this_handler)
587
  {
588
    return this_handler->start_ == 0 ? true
589
      : boost_asio_handler_cont_helpers::is_continuation(
590
          this_handler->handler_);
591
  }
592

    
593
  template <typename Function, typename AsyncRandomAccessWriteDevice,
594
      typename ConstBufferSequence, typename CompletionCondition,
595
      typename WriteHandler>
596
  inline void asio_handler_invoke(Function& function,
597
      write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
598
        CompletionCondition, WriteHandler>* this_handler)
599
  {
600
    boost_asio_handler_invoke_helpers::invoke(
601
        function, this_handler->handler_);
602
  }
603

    
604
  template <typename Function, typename AsyncRandomAccessWriteDevice,
605
      typename ConstBufferSequence, typename CompletionCondition,
606
      typename WriteHandler>
607
  inline void asio_handler_invoke(const Function& function,
608
      write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
609
        CompletionCondition, WriteHandler>* this_handler)
610
  {
611
    boost_asio_handler_invoke_helpers::invoke(
612
        function, this_handler->handler_);
613
  }
614

    
615
  template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
616
      typename CompletionCondition, typename WriteHandler>
617
  inline write_at_op<AsyncRandomAccessWriteDevice,
618
      ConstBufferSequence, CompletionCondition, WriteHandler>
619
  make_write_at_op(AsyncRandomAccessWriteDevice& d,
620
      uint64_t offset, const ConstBufferSequence& buffers,
621
      CompletionCondition completion_condition, WriteHandler handler)
622
  {
623
    return write_at_op<AsyncRandomAccessWriteDevice,
624
      ConstBufferSequence, CompletionCondition, WriteHandler>(
625
        d, offset, buffers, completion_condition, handler);
626
  }
627
} // namespace detail
628

    
629
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
630
    typename CompletionCondition, typename WriteHandler>
631
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
632
    void (boost::system::error_code, std::size_t))
633
async_write_at(AsyncRandomAccessWriteDevice& d,
634
    uint64_t offset, const ConstBufferSequence& buffers,
635
    CompletionCondition completion_condition,
636
    BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
637
{
638
  // If you get an error on the following line it means that your handler does
639
  // not meet the documented type requirements for a WriteHandler.
640
  BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
641

    
642
  detail::async_result_init<
643
    WriteHandler, void (boost::system::error_code, std::size_t)> init(
644
      BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
645

    
646
  detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
647
    CompletionCondition, BOOST_ASIO_HANDLER_TYPE(
648
      WriteHandler, void (boost::system::error_code, std::size_t))>(
649
        d, offset, buffers, completion_condition, init.handler)(
650
          boost::system::error_code(), 0, 1);
651

    
652
  return init.result.get();
653
}
654

    
655
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
656
    typename WriteHandler>
657
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
658
    void (boost::system::error_code, std::size_t))
659
async_write_at(AsyncRandomAccessWriteDevice& d,
660
    uint64_t offset, const ConstBufferSequence& buffers,
661
    BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
662
{
663
  // If you get an error on the following line it means that your handler does
664
  // not meet the documented type requirements for a WriteHandler.
665
  BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
666

    
667
  detail::async_result_init<
668
    WriteHandler, void (boost::system::error_code, std::size_t)> init(
669
      BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
670

    
671
  detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
672
    detail::transfer_all_t, BOOST_ASIO_HANDLER_TYPE(
673
      WriteHandler, void (boost::system::error_code, std::size_t))>(
674
        d, offset, buffers, transfer_all(), init.handler)(
675
          boost::system::error_code(), 0, 1);
676

    
677
  return init.result.get();
678
}
679

    
680
#if !defined(BOOST_ASIO_NO_IOSTREAM)
681

    
682
namespace detail
683
{
684
  template <typename Allocator, typename WriteHandler>
685
  class write_at_streambuf_op
686
  {
687
  public:
688
    write_at_streambuf_op(
689
        boost::asio::basic_streambuf<Allocator>& streambuf,
690
        WriteHandler& handler)
691
      : streambuf_(streambuf),
692
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
693
    {
694
    }
695

    
696
#if defined(BOOST_ASIO_HAS_MOVE)
697
    write_at_streambuf_op(const write_at_streambuf_op& other)
698
      : streambuf_(other.streambuf_),
699
        handler_(other.handler_)
700
    {
701
    }
702

    
703
    write_at_streambuf_op(write_at_streambuf_op&& other)
704
      : streambuf_(other.streambuf_),
705
        handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
706
    {
707
    }
708
#endif // defined(BOOST_ASIO_HAS_MOVE)
709

    
710
    void operator()(const boost::system::error_code& ec,
711
        const std::size_t bytes_transferred)
712
    {
713
      streambuf_.consume(bytes_transferred);
714
      handler_(ec, bytes_transferred);
715
    }
716

    
717
  //private:
718
    boost::asio::basic_streambuf<Allocator>& streambuf_;
719
    WriteHandler handler_;
720
  };
721

    
722
  template <typename Allocator, typename WriteHandler>
723
  inline void* asio_handler_allocate(std::size_t size,
724
      write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
725
  {
726
    return boost_asio_handler_alloc_helpers::allocate(
727
        size, this_handler->handler_);
728
  }
729

    
730
  template <typename Allocator, typename WriteHandler>
731
  inline void asio_handler_deallocate(void* pointer, std::size_t size,
732
      write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
733
  {
734
    boost_asio_handler_alloc_helpers::deallocate(
735
        pointer, size, this_handler->handler_);
736
  }
737

    
738
  template <typename Allocator, typename WriteHandler>
739
  inline bool asio_handler_is_continuation(
740
      write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
741
  {
742
    return boost_asio_handler_cont_helpers::is_continuation(
743
        this_handler->handler_);
744
  }
745

    
746
  template <typename Function, typename Allocator, typename WriteHandler>
747
  inline void asio_handler_invoke(Function& function,
748
      write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
749
  {
750
    boost_asio_handler_invoke_helpers::invoke(
751
        function, this_handler->handler_);
752
  }
753

    
754
  template <typename Function, typename Allocator, typename WriteHandler>
755
  inline void asio_handler_invoke(const Function& function,
756
      write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
757
  {
758
    boost_asio_handler_invoke_helpers::invoke(
759
        function, this_handler->handler_);
760
  }
761

    
762
  template <typename Allocator, typename WriteHandler>
763
  inline write_at_streambuf_op<Allocator, WriteHandler>
764
  make_write_at_streambuf_op(
765
      boost::asio::basic_streambuf<Allocator>& b, WriteHandler handler)
766
  {
767
    return write_at_streambuf_op<Allocator, WriteHandler>(b, handler);
768
  }
769
} // namespace detail
770

    
771
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
772
    typename CompletionCondition, typename WriteHandler>
773
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
774
    void (boost::system::error_code, std::size_t))
775
async_write_at(AsyncRandomAccessWriteDevice& d,
776
    uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
777
    CompletionCondition completion_condition,
778
    BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
779
{
780
  // If you get an error on the following line it means that your handler does
781
  // not meet the documented type requirements for a WriteHandler.
782
  BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
783

    
784
  detail::async_result_init<
785
    WriteHandler, void (boost::system::error_code, std::size_t)> init(
786
      BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
787

    
788
  async_write_at(d, offset, b.data(), completion_condition,
789
    detail::write_at_streambuf_op<Allocator, BOOST_ASIO_HANDLER_TYPE(
790
      WriteHandler, void (boost::system::error_code, std::size_t))>(
791
        b, init.handler));
792

    
793
  return init.result.get();
794
}
795

    
796
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
797
    typename WriteHandler>
798
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
799
    void (boost::system::error_code, std::size_t))
800
async_write_at(AsyncRandomAccessWriteDevice& d,
801
    uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
802
    BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
803
{
804
  // If you get an error on the following line it means that your handler does
805
  // not meet the documented type requirements for a WriteHandler.
806
  BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
807

    
808
  detail::async_result_init<
809
    WriteHandler, void (boost::system::error_code, std::size_t)> init(
810
      BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
811

    
812
  async_write_at(d, offset, b.data(), transfer_all(),
813
    detail::write_at_streambuf_op<Allocator, BOOST_ASIO_HANDLER_TYPE(
814
      WriteHandler, void (boost::system::error_code, std::size_t))>(
815
        b, init.handler));
816

    
817
  return init.result.get();
818
}
819

    
820
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
821

    
822
} // namespace asio
823
} // namespace boost
824

    
825
#include <boost/asio/detail/pop_options.hpp>
826

    
827
#endif // BOOST_ASIO_IMPL_WRITE_AT_HPP