5
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7
// Distributed under the Boost Software License, Version 1.0. (See accompanying
8
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11
#ifndef ASIO_WRITE_AT_IPP
12
#define ASIO_WRITE_AT_IPP
14
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
16
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18
#include "asio/detail/push_options.hpp"
20
#include "asio/buffer.hpp"
21
#include "asio/completion_condition.hpp"
22
#include "asio/detail/bind_handler.hpp"
23
#include "asio/detail/consuming_buffers.hpp"
24
#include "asio/detail/handler_alloc_helpers.hpp"
25
#include "asio/detail/handler_invoke_helpers.hpp"
26
#include "asio/detail/throw_error.hpp"
30
template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
31
typename CompletionCondition>
32
std::size_t write_at(SyncRandomAccessWriteDevice& d,
33
boost::uint64_t offset, const ConstBufferSequence& buffers,
34
CompletionCondition completion_condition, asio::error_code& ec)
36
asio::detail::consuming_buffers<
37
const_buffer, ConstBufferSequence> tmp(buffers);
38
std::size_t total_transferred = 0;
39
while (tmp.begin() != tmp.end())
41
std::size_t bytes_transferred = d.write_some_at(
42
offset + total_transferred, tmp, ec);
43
tmp.consume(bytes_transferred);
44
total_transferred += bytes_transferred;
45
if (completion_condition(ec, total_transferred))
46
return total_transferred;
48
ec = asio::error_code();
49
return total_transferred;
52
template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>
53
inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
54
boost::uint64_t offset, const ConstBufferSequence& buffers)
57
std::size_t bytes_transferred = write_at(
58
d, offset, buffers, transfer_all(), ec);
59
asio::detail::throw_error(ec);
60
return bytes_transferred;
63
template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
64
typename CompletionCondition>
65
inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
66
boost::uint64_t offset, const ConstBufferSequence& buffers,
67
CompletionCondition completion_condition)
70
std::size_t bytes_transferred = write_at(
71
d, offset, buffers, completion_condition, ec);
72
asio::detail::throw_error(ec);
73
return bytes_transferred;
76
template <typename SyncRandomAccessWriteDevice, typename Allocator,
77
typename CompletionCondition>
78
std::size_t write_at(SyncRandomAccessWriteDevice& d,
79
boost::uint64_t offset, asio::basic_streambuf<Allocator>& b,
80
CompletionCondition completion_condition, asio::error_code& ec)
82
std::size_t bytes_transferred = write_at(
83
d, offset, b.data(), completion_condition, ec);
84
b.consume(bytes_transferred);
85
return bytes_transferred;
88
template <typename SyncRandomAccessWriteDevice, typename Allocator>
89
inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
90
boost::uint64_t offset, asio::basic_streambuf<Allocator>& b)
93
std::size_t bytes_transferred = write_at(d, offset, b, transfer_all(), ec);
94
asio::detail::throw_error(ec);
95
return bytes_transferred;
98
template <typename SyncRandomAccessWriteDevice, typename Allocator,
99
typename CompletionCondition>
100
inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
101
boost::uint64_t offset, asio::basic_streambuf<Allocator>& b,
102
CompletionCondition completion_condition)
105
std::size_t bytes_transferred = write_at(
106
d, offset, b, completion_condition, ec);
107
asio::detail::throw_error(ec);
108
return bytes_transferred;
113
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
114
typename CompletionCondition, typename WriteHandler>
115
class write_at_handler
118
typedef asio::detail::consuming_buffers<
119
const_buffer, ConstBufferSequence> buffers_type;
121
write_at_handler(AsyncRandomAccessWriteDevice& stream,
122
boost::uint64_t offset, const buffers_type& buffers,
123
CompletionCondition completion_condition, WriteHandler handler)
127
total_transferred_(0),
128
completion_condition_(completion_condition),
133
void operator()(const asio::error_code& ec,
134
std::size_t bytes_transferred)
136
total_transferred_ += bytes_transferred;
137
buffers_.consume(bytes_transferred);
138
if (completion_condition_(ec, total_transferred_)
139
|| buffers_.begin() == buffers_.end())
141
handler_(ec, total_transferred_);
145
stream_.async_write_some_at(
146
offset_ + total_transferred_, buffers_, *this);
151
AsyncRandomAccessWriteDevice& stream_;
152
buffers_type buffers_;
153
boost::uint64_t offset_;
154
std::size_t total_transferred_;
155
CompletionCondition completion_condition_;
156
WriteHandler handler_;
159
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
160
typename CompletionCondition, typename WriteHandler>
161
inline void* asio_handler_allocate(std::size_t size,
162
write_at_handler<AsyncRandomAccessWriteDevice, ConstBufferSequence,
163
CompletionCondition, WriteHandler>* this_handler)
165
return asio_handler_alloc_helpers::allocate(
166
size, &this_handler->handler_);
169
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
170
typename CompletionCondition, typename WriteHandler>
171
inline void asio_handler_deallocate(void* pointer, std::size_t size,
172
write_at_handler<AsyncRandomAccessWriteDevice, ConstBufferSequence,
173
CompletionCondition, WriteHandler>* this_handler)
175
asio_handler_alloc_helpers::deallocate(
176
pointer, size, &this_handler->handler_);
179
template <typename Function, typename AsyncRandomAccessWriteDevice,
180
typename ConstBufferSequence, typename CompletionCondition,
181
typename WriteHandler>
182
inline void asio_handler_invoke(const Function& function,
183
write_at_handler<AsyncRandomAccessWriteDevice, ConstBufferSequence,
184
CompletionCondition, WriteHandler>* this_handler)
186
asio_handler_invoke_helpers::invoke(
187
function, &this_handler->handler_);
189
} // namespace detail
191
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
192
typename CompletionCondition, typename WriteHandler>
193
inline void async_write_at(AsyncRandomAccessWriteDevice& d,
194
boost::uint64_t offset, const ConstBufferSequence& buffers,
195
CompletionCondition completion_condition, WriteHandler handler)
197
asio::detail::consuming_buffers<
198
const_buffer, ConstBufferSequence> tmp(buffers);
199
d.async_write_some_at(offset, tmp,
200
detail::write_at_handler<AsyncRandomAccessWriteDevice,
201
ConstBufferSequence, CompletionCondition, WriteHandler>(
202
d, offset, tmp, completion_condition, handler));
205
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
206
typename WriteHandler>
207
inline void async_write_at(AsyncRandomAccessWriteDevice& d,
208
boost::uint64_t offset, const ConstBufferSequence& buffers,
209
WriteHandler handler)
211
async_write_at(d, offset, buffers, transfer_all(), handler);
216
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
217
typename WriteHandler>
218
class write_at_streambuf_handler
221
write_at_streambuf_handler(
222
asio::basic_streambuf<Allocator>& streambuf,
223
WriteHandler handler)
224
: streambuf_(streambuf),
229
void operator()(const asio::error_code& ec,
230
std::size_t bytes_transferred)
232
streambuf_.consume(bytes_transferred);
233
handler_(ec, bytes_transferred);
237
asio::basic_streambuf<Allocator>& streambuf_;
238
WriteHandler handler_;
241
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
242
typename WriteHandler>
243
inline void* asio_handler_allocate(std::size_t size,
244
write_at_streambuf_handler<AsyncRandomAccessWriteDevice,
245
Allocator, WriteHandler>* this_handler)
247
return asio_handler_alloc_helpers::allocate(
248
size, &this_handler->handler_);
251
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
252
typename WriteHandler>
253
inline void asio_handler_deallocate(void* pointer, std::size_t size,
254
write_at_streambuf_handler<AsyncRandomAccessWriteDevice,
255
Allocator, WriteHandler>* this_handler)
257
asio_handler_alloc_helpers::deallocate(
258
pointer, size, &this_handler->handler_);
261
template <typename Function, typename AsyncRandomAccessWriteDevice,
262
typename Allocator, typename WriteHandler>
263
inline void asio_handler_invoke(const Function& function,
264
write_at_streambuf_handler<AsyncRandomAccessWriteDevice,
265
Allocator, WriteHandler>* this_handler)
267
asio_handler_invoke_helpers::invoke(
268
function, &this_handler->handler_);
270
} // namespace detail
272
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
273
typename CompletionCondition, typename WriteHandler>
274
inline void async_write_at(AsyncRandomAccessWriteDevice& d,
275
boost::uint64_t offset, asio::basic_streambuf<Allocator>& b,
276
CompletionCondition completion_condition, WriteHandler handler)
278
async_write_at(d, offset, b.data(), completion_condition,
279
detail::write_at_streambuf_handler<
280
AsyncRandomAccessWriteDevice, Allocator, WriteHandler>(b, handler));
283
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
284
typename WriteHandler>
285
inline void async_write_at(AsyncRandomAccessWriteDevice& d,
286
boost::uint64_t offset, asio::basic_streambuf<Allocator>& b,
287
WriteHandler handler)
289
async_write_at(d, offset, b, transfer_all(), handler);
294
#include "asio/detail/pop_options.hpp"
296
#endif // ASIO_WRITE_AT_IPP