]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/impl/write_at.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / asio / impl / write_at.hpp
1 //
2 // impl/write_at.hpp
3 // ~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 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/associated_allocator.hpp>
19 #include <boost/asio/associated_executor.hpp>
20 #include <boost/asio/buffer.hpp>
21 #include <boost/asio/completion_condition.hpp>
22 #include <boost/asio/detail/array_fwd.hpp>
23 #include <boost/asio/detail/base_from_completion_cond.hpp>
24 #include <boost/asio/detail/bind_handler.hpp>
25 #include <boost/asio/detail/consuming_buffers.hpp>
26 #include <boost/asio/detail/dependent_type.hpp>
27 #include <boost/asio/detail/handler_alloc_helpers.hpp>
28 #include <boost/asio/detail/handler_cont_helpers.hpp>
29 #include <boost/asio/detail/handler_invoke_helpers.hpp>
30 #include <boost/asio/detail/handler_type_requirements.hpp>
31 #include <boost/asio/detail/throw_error.hpp>
32
33 #include <boost/asio/detail/push_options.hpp>
34
35 namespace boost {
36 namespace asio {
37
38 namespace detail
39 {
40 template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
41 typename ConstBufferIterator, typename CompletionCondition>
42 std::size_t write_at_buffer_sequence(SyncRandomAccessWriteDevice& d,
43 uint64_t offset, const ConstBufferSequence& buffers,
44 const ConstBufferIterator&, CompletionCondition completion_condition,
45 boost::system::error_code& ec)
46 {
47 ec = boost::system::error_code();
48 boost::asio::detail::consuming_buffers<const_buffer,
49 ConstBufferSequence, ConstBufferIterator> tmp(buffers);
50 while (!tmp.empty())
51 {
52 if (std::size_t max_size = detail::adapt_completion_condition_result(
53 completion_condition(ec, tmp.total_consumed())))
54 {
55 tmp.consume(d.write_some_at(offset + tmp.total_consumed(),
56 tmp.prepare(max_size), ec));
57 }
58 else
59 break;
60 }
61 return tmp.total_consumed();;
62 }
63 } // namespace detail
64
65 template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
66 typename CompletionCondition>
67 std::size_t write_at(SyncRandomAccessWriteDevice& d,
68 uint64_t offset, const ConstBufferSequence& buffers,
69 CompletionCondition completion_condition, boost::system::error_code& ec)
70 {
71 return detail::write_at_buffer_sequence(d, offset, buffers,
72 boost::asio::buffer_sequence_begin(buffers), completion_condition, ec);
73 }
74
75 template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>
76 inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
77 uint64_t offset, const ConstBufferSequence& buffers)
78 {
79 boost::system::error_code ec;
80 std::size_t bytes_transferred = write_at(
81 d, offset, buffers, transfer_all(), ec);
82 boost::asio::detail::throw_error(ec, "write_at");
83 return bytes_transferred;
84 }
85
86 template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>
87 inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
88 uint64_t offset, const ConstBufferSequence& buffers,
89 boost::system::error_code& ec)
90 {
91 return write_at(d, offset, buffers, transfer_all(), ec);
92 }
93
94 template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
95 typename CompletionCondition>
96 inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
97 uint64_t offset, const ConstBufferSequence& buffers,
98 CompletionCondition completion_condition)
99 {
100 boost::system::error_code ec;
101 std::size_t bytes_transferred = write_at(
102 d, offset, buffers, completion_condition, ec);
103 boost::asio::detail::throw_error(ec, "write_at");
104 return bytes_transferred;
105 }
106
107 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
108 #if !defined(BOOST_ASIO_NO_IOSTREAM)
109
110 template <typename SyncRandomAccessWriteDevice, typename Allocator,
111 typename CompletionCondition>
112 std::size_t write_at(SyncRandomAccessWriteDevice& d,
113 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
114 CompletionCondition completion_condition, boost::system::error_code& ec)
115 {
116 std::size_t bytes_transferred = write_at(
117 d, offset, b.data(), completion_condition, ec);
118 b.consume(bytes_transferred);
119 return bytes_transferred;
120 }
121
122 template <typename SyncRandomAccessWriteDevice, typename Allocator>
123 inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
124 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b)
125 {
126 boost::system::error_code ec;
127 std::size_t bytes_transferred = write_at(d, offset, b, transfer_all(), ec);
128 boost::asio::detail::throw_error(ec, "write_at");
129 return bytes_transferred;
130 }
131
132 template <typename SyncRandomAccessWriteDevice, typename Allocator>
133 inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
134 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
135 boost::system::error_code& ec)
136 {
137 return write_at(d, offset, b, transfer_all(), ec);
138 }
139
140 template <typename SyncRandomAccessWriteDevice, typename Allocator,
141 typename CompletionCondition>
142 inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
143 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
144 CompletionCondition completion_condition)
145 {
146 boost::system::error_code ec;
147 std::size_t bytes_transferred = write_at(
148 d, offset, b, completion_condition, ec);
149 boost::asio::detail::throw_error(ec, "write_at");
150 return bytes_transferred;
151 }
152
153 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
154 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
155
156 namespace detail
157 {
158 template <typename AsyncRandomAccessWriteDevice,
159 typename ConstBufferSequence, typename ConstBufferIterator,
160 typename CompletionCondition, typename WriteHandler>
161 class write_at_op
162 : detail::base_from_completion_cond<CompletionCondition>
163 {
164 public:
165 write_at_op(AsyncRandomAccessWriteDevice& device,
166 uint64_t offset, const ConstBufferSequence& buffers,
167 CompletionCondition completion_condition, WriteHandler& handler)
168 : detail::base_from_completion_cond<
169 CompletionCondition>(completion_condition),
170 device_(device),
171 offset_(offset),
172 buffers_(buffers),
173 start_(0),
174 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
175 {
176 }
177
178 #if defined(BOOST_ASIO_HAS_MOVE)
179 write_at_op(const write_at_op& other)
180 : detail::base_from_completion_cond<CompletionCondition>(other),
181 device_(other.device_),
182 offset_(other.offset_),
183 buffers_(other.buffers_),
184 start_(other.start_),
185 handler_(other.handler_)
186 {
187 }
188
189 write_at_op(write_at_op&& other)
190 : detail::base_from_completion_cond<CompletionCondition>(other),
191 device_(other.device_),
192 offset_(other.offset_),
193 buffers_(other.buffers_),
194 start_(other.start_),
195 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
196 {
197 }
198 #endif // defined(BOOST_ASIO_HAS_MOVE)
199
200 void operator()(const boost::system::error_code& ec,
201 std::size_t bytes_transferred, int start = 0)
202 {
203 std::size_t max_size;
204 switch (start_ = start)
205 {
206 case 1:
207 max_size = this->check_for_completion(ec, buffers_.total_consumed());
208 do
209 {
210 device_.async_write_some_at(
211 offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),
212 BOOST_ASIO_MOVE_CAST(write_at_op)(*this));
213 return; default:
214 buffers_.consume(bytes_transferred);
215 if ((!ec && bytes_transferred == 0) || buffers_.empty())
216 break;
217 max_size = this->check_for_completion(ec, buffers_.total_consumed());
218 } while (max_size > 0);
219
220 handler_(ec, buffers_.total_consumed());
221 }
222 }
223
224 //private:
225 AsyncRandomAccessWriteDevice& device_;
226 uint64_t offset_;
227 boost::asio::detail::consuming_buffers<const_buffer,
228 ConstBufferSequence, ConstBufferIterator> buffers_;
229 int start_;
230 WriteHandler handler_;
231 };
232
233 template <typename AsyncRandomAccessWriteDevice,
234 typename ConstBufferSequence, typename ConstBufferIterator,
235 typename CompletionCondition, typename WriteHandler>
236 inline void* asio_handler_allocate(std::size_t size,
237 write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
238 ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)
239 {
240 return boost_asio_handler_alloc_helpers::allocate(
241 size, this_handler->handler_);
242 }
243
244 template <typename AsyncRandomAccessWriteDevice,
245 typename ConstBufferSequence, typename ConstBufferIterator,
246 typename CompletionCondition, typename WriteHandler>
247 inline void asio_handler_deallocate(void* pointer, std::size_t size,
248 write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
249 ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)
250 {
251 boost_asio_handler_alloc_helpers::deallocate(
252 pointer, size, this_handler->handler_);
253 }
254
255 template <typename AsyncRandomAccessWriteDevice,
256 typename ConstBufferSequence, typename ConstBufferIterator,
257 typename CompletionCondition, typename WriteHandler>
258 inline bool asio_handler_is_continuation(
259 write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
260 ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)
261 {
262 return this_handler->start_ == 0 ? true
263 : boost_asio_handler_cont_helpers::is_continuation(
264 this_handler->handler_);
265 }
266
267 template <typename Function, typename AsyncRandomAccessWriteDevice,
268 typename ConstBufferSequence, typename ConstBufferIterator,
269 typename CompletionCondition, typename WriteHandler>
270 inline void asio_handler_invoke(Function& function,
271 write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
272 ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)
273 {
274 boost_asio_handler_invoke_helpers::invoke(
275 function, this_handler->handler_);
276 }
277
278 template <typename Function, typename AsyncRandomAccessWriteDevice,
279 typename ConstBufferSequence, typename ConstBufferIterator,
280 typename CompletionCondition, typename WriteHandler>
281 inline void asio_handler_invoke(const Function& function,
282 write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
283 ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)
284 {
285 boost_asio_handler_invoke_helpers::invoke(
286 function, this_handler->handler_);
287 }
288
289 template <typename AsyncRandomAccessWriteDevice,
290 typename ConstBufferSequence, typename ConstBufferIterator,
291 typename CompletionCondition, typename WriteHandler>
292 inline void start_write_at_buffer_sequence_op(AsyncRandomAccessWriteDevice& d,
293 uint64_t offset, const ConstBufferSequence& buffers,
294 const ConstBufferIterator&, CompletionCondition completion_condition,
295 WriteHandler& handler)
296 {
297 detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
298 ConstBufferIterator, CompletionCondition, WriteHandler>(
299 d, offset, buffers, completion_condition, handler)(
300 boost::system::error_code(), 0, 1);
301 }
302 } // namespace detail
303
304 #if !defined(GENERATING_DOCUMENTATION)
305
306 template <typename AsyncRandomAccessWriteDevice,
307 typename ConstBufferSequence, typename ConstBufferIterator,
308 typename CompletionCondition, typename WriteHandler, typename Allocator>
309 struct associated_allocator<
310 detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
311 ConstBufferIterator, CompletionCondition, WriteHandler>,
312 Allocator>
313 {
314 typedef typename associated_allocator<WriteHandler, Allocator>::type type;
315
316 static type get(
317 const detail::write_at_op<AsyncRandomAccessWriteDevice,
318 ConstBufferSequence, ConstBufferIterator,
319 CompletionCondition, WriteHandler>& h,
320 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
321 {
322 return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
323 }
324 };
325
326 template <typename AsyncRandomAccessWriteDevice,
327 typename ConstBufferSequence, typename ConstBufferIterator,
328 typename CompletionCondition, typename WriteHandler, typename Executor>
329 struct associated_executor<
330 detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
331 ConstBufferIterator, CompletionCondition, WriteHandler>,
332 Executor>
333 {
334 typedef typename associated_executor<WriteHandler, Executor>::type type;
335
336 static type get(
337 const detail::write_at_op<AsyncRandomAccessWriteDevice,
338 ConstBufferSequence, ConstBufferIterator,
339 CompletionCondition, WriteHandler>& h,
340 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
341 {
342 return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
343 }
344 };
345
346 #endif // !defined(GENERATING_DOCUMENTATION)
347
348 template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
349 typename CompletionCondition, typename WriteHandler>
350 inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
351 void (boost::system::error_code, std::size_t))
352 async_write_at(AsyncRandomAccessWriteDevice& d,
353 uint64_t offset, const ConstBufferSequence& buffers,
354 CompletionCondition completion_condition,
355 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
356 {
357 // If you get an error on the following line it means that your handler does
358 // not meet the documented type requirements for a WriteHandler.
359 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
360
361 async_completion<WriteHandler,
362 void (boost::system::error_code, std::size_t)> init(handler);
363
364 detail::start_write_at_buffer_sequence_op(d, offset, buffers,
365 boost::asio::buffer_sequence_begin(buffers), completion_condition,
366 init.completion_handler);
367
368 return init.result.get();
369 }
370
371 template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
372 typename WriteHandler>
373 inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
374 void (boost::system::error_code, std::size_t))
375 async_write_at(AsyncRandomAccessWriteDevice& d,
376 uint64_t offset, const ConstBufferSequence& buffers,
377 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
378 {
379 // If you get an error on the following line it means that your handler does
380 // not meet the documented type requirements for a WriteHandler.
381 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
382
383 async_completion<WriteHandler,
384 void (boost::system::error_code, std::size_t)> init(handler);
385
386 detail::start_write_at_buffer_sequence_op(d, offset, buffers,
387 boost::asio::buffer_sequence_begin(buffers), transfer_all(),
388 init.completion_handler);
389
390 return init.result.get();
391 }
392
393 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
394 #if !defined(BOOST_ASIO_NO_IOSTREAM)
395
396 namespace detail
397 {
398 template <typename Allocator, typename WriteHandler>
399 class write_at_streambuf_op
400 {
401 public:
402 write_at_streambuf_op(
403 boost::asio::basic_streambuf<Allocator>& streambuf,
404 WriteHandler& handler)
405 : streambuf_(streambuf),
406 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
407 {
408 }
409
410 #if defined(BOOST_ASIO_HAS_MOVE)
411 write_at_streambuf_op(const write_at_streambuf_op& other)
412 : streambuf_(other.streambuf_),
413 handler_(other.handler_)
414 {
415 }
416
417 write_at_streambuf_op(write_at_streambuf_op&& other)
418 : streambuf_(other.streambuf_),
419 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
420 {
421 }
422 #endif // defined(BOOST_ASIO_HAS_MOVE)
423
424 void operator()(const boost::system::error_code& ec,
425 const std::size_t bytes_transferred)
426 {
427 streambuf_.consume(bytes_transferred);
428 handler_(ec, bytes_transferred);
429 }
430
431 //private:
432 boost::asio::basic_streambuf<Allocator>& streambuf_;
433 WriteHandler handler_;
434 };
435
436 template <typename Allocator, typename WriteHandler>
437 inline void* asio_handler_allocate(std::size_t size,
438 write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
439 {
440 return boost_asio_handler_alloc_helpers::allocate(
441 size, this_handler->handler_);
442 }
443
444 template <typename Allocator, typename WriteHandler>
445 inline void asio_handler_deallocate(void* pointer, std::size_t size,
446 write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
447 {
448 boost_asio_handler_alloc_helpers::deallocate(
449 pointer, size, this_handler->handler_);
450 }
451
452 template <typename Allocator, typename WriteHandler>
453 inline bool asio_handler_is_continuation(
454 write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
455 {
456 return boost_asio_handler_cont_helpers::is_continuation(
457 this_handler->handler_);
458 }
459
460 template <typename Function, typename Allocator, typename WriteHandler>
461 inline void asio_handler_invoke(Function& function,
462 write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
463 {
464 boost_asio_handler_invoke_helpers::invoke(
465 function, this_handler->handler_);
466 }
467
468 template <typename Function, typename Allocator, typename WriteHandler>
469 inline void asio_handler_invoke(const Function& function,
470 write_at_streambuf_op<Allocator, WriteHandler>* this_handler)
471 {
472 boost_asio_handler_invoke_helpers::invoke(
473 function, this_handler->handler_);
474 }
475
476 template <typename Allocator, typename WriteHandler>
477 inline write_at_streambuf_op<Allocator, WriteHandler>
478 make_write_at_streambuf_op(
479 boost::asio::basic_streambuf<Allocator>& b, WriteHandler handler)
480 {
481 return write_at_streambuf_op<Allocator, WriteHandler>(b, handler);
482 }
483 } // namespace detail
484
485 #if !defined(GENERATING_DOCUMENTATION)
486
487 template <typename Allocator, typename WriteHandler, typename Allocator1>
488 struct associated_allocator<
489 detail::write_at_streambuf_op<Allocator, WriteHandler>,
490 Allocator1>
491 {
492 typedef typename associated_allocator<WriteHandler, Allocator1>::type type;
493
494 static type get(
495 const detail::write_at_streambuf_op<Allocator, WriteHandler>& h,
496 const Allocator1& a = Allocator1()) BOOST_ASIO_NOEXCEPT
497 {
498 return associated_allocator<WriteHandler, Allocator1>::get(h.handler_, a);
499 }
500 };
501
502 template <typename Executor, typename WriteHandler, typename Executor1>
503 struct associated_executor<
504 detail::write_at_streambuf_op<Executor, WriteHandler>,
505 Executor1>
506 {
507 typedef typename associated_executor<WriteHandler, Executor1>::type type;
508
509 static type get(
510 const detail::write_at_streambuf_op<Executor, WriteHandler>& h,
511 const Executor1& ex = Executor1()) BOOST_ASIO_NOEXCEPT
512 {
513 return associated_executor<WriteHandler, Executor1>::get(h.handler_, ex);
514 }
515 };
516
517 #endif // !defined(GENERATING_DOCUMENTATION)
518
519 template <typename AsyncRandomAccessWriteDevice, typename Allocator,
520 typename CompletionCondition, typename WriteHandler>
521 inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
522 void (boost::system::error_code, std::size_t))
523 async_write_at(AsyncRandomAccessWriteDevice& d,
524 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
525 CompletionCondition completion_condition,
526 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
527 {
528 // If you get an error on the following line it means that your handler does
529 // not meet the documented type requirements for a WriteHandler.
530 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
531
532 async_completion<WriteHandler,
533 void (boost::system::error_code, std::size_t)> init(handler);
534
535 async_write_at(d, offset, b.data(), completion_condition,
536 detail::write_at_streambuf_op<Allocator, BOOST_ASIO_HANDLER_TYPE(
537 WriteHandler, void (boost::system::error_code, std::size_t))>(
538 b, init.completion_handler));
539
540 return init.result.get();
541 }
542
543 template <typename AsyncRandomAccessWriteDevice, typename Allocator,
544 typename WriteHandler>
545 inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
546 void (boost::system::error_code, std::size_t))
547 async_write_at(AsyncRandomAccessWriteDevice& d,
548 uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
549 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
550 {
551 // If you get an error on the following line it means that your handler does
552 // not meet the documented type requirements for a WriteHandler.
553 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
554
555 async_completion<WriteHandler,
556 void (boost::system::error_code, std::size_t)> init(handler);
557
558 async_write_at(d, offset, b.data(), transfer_all(),
559 detail::write_at_streambuf_op<Allocator, BOOST_ASIO_HANDLER_TYPE(
560 WriteHandler, void (boost::system::error_code, std::size_t))>(
561 b, init.completion_handler));
562
563 return init.result.get();
564 }
565
566 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
567 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
568
569 } // namespace asio
570 } // namespace boost
571
572 #include <boost/asio/detail/pop_options.hpp>
573
574 #endif // BOOST_ASIO_IMPL_WRITE_AT_HPP