]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/impl/buffered_read_stream.hpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / boost / asio / impl / buffered_read_stream.hpp
CommitLineData
7c673cae
FG
1//
2// impl/buffered_read_stream.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4//
f67539c2 5// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7c673cae
FG
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_BUFFERED_READ_STREAM_HPP
12#define BOOST_ASIO_IMPL_BUFFERED_READ_STREAM_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
b32b8144
FG
18#include <boost/asio/associated_allocator.hpp>
19#include <boost/asio/associated_executor.hpp>
7c673cae
FG
20#include <boost/asio/detail/handler_alloc_helpers.hpp>
21#include <boost/asio/detail/handler_cont_helpers.hpp>
22#include <boost/asio/detail/handler_invoke_helpers.hpp>
23#include <boost/asio/detail/handler_type_requirements.hpp>
92f5a8d4
TL
24#include <boost/asio/detail/non_const_lvalue.hpp>
25#include <boost/asio/detail/type_traits.hpp>
7c673cae
FG
26
27#include <boost/asio/detail/push_options.hpp>
28
29namespace boost {
30namespace asio {
31
32template <typename Stream>
33std::size_t buffered_read_stream<Stream>::fill()
34{
35 detail::buffer_resize_guard<detail::buffered_stream_storage>
36 resize_guard(storage_);
37 std::size_t previous_size = storage_.size();
38 storage_.resize(storage_.capacity());
39 storage_.resize(previous_size + next_layer_.read_some(buffer(
40 storage_.data() + previous_size,
41 storage_.size() - previous_size)));
42 resize_guard.commit();
43 return storage_.size() - previous_size;
44}
45
46template <typename Stream>
47std::size_t buffered_read_stream<Stream>::fill(boost::system::error_code& ec)
48{
49 detail::buffer_resize_guard<detail::buffered_stream_storage>
50 resize_guard(storage_);
51 std::size_t previous_size = storage_.size();
52 storage_.resize(storage_.capacity());
53 storage_.resize(previous_size + next_layer_.read_some(buffer(
54 storage_.data() + previous_size,
55 storage_.size() - previous_size),
56 ec));
57 resize_guard.commit();
58 return storage_.size() - previous_size;
59}
60
61namespace detail
62{
63 template <typename ReadHandler>
64 class buffered_fill_handler
65 {
66 public:
67 buffered_fill_handler(detail::buffered_stream_storage& storage,
68 std::size_t previous_size, ReadHandler& handler)
69 : storage_(storage),
70 previous_size_(previous_size),
71 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
72 {
73 }
74
75#if defined(BOOST_ASIO_HAS_MOVE)
76 buffered_fill_handler(const buffered_fill_handler& other)
77 : storage_(other.storage_),
78 previous_size_(other.previous_size_),
79 handler_(other.handler_)
80 {
81 }
82
83 buffered_fill_handler(buffered_fill_handler&& other)
84 : storage_(other.storage_),
85 previous_size_(other.previous_size_),
86 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
87 {
88 }
89#endif // defined(BOOST_ASIO_HAS_MOVE)
90
91 void operator()(const boost::system::error_code& ec,
92 const std::size_t bytes_transferred)
93 {
94 storage_.resize(previous_size_ + bytes_transferred);
95 handler_(ec, bytes_transferred);
96 }
97
98 //private:
99 detail::buffered_stream_storage& storage_;
100 std::size_t previous_size_;
101 ReadHandler handler_;
102 };
103
104 template <typename ReadHandler>
105 inline void* asio_handler_allocate(std::size_t size,
106 buffered_fill_handler<ReadHandler>* this_handler)
107 {
108 return boost_asio_handler_alloc_helpers::allocate(
109 size, this_handler->handler_);
110 }
111
112 template <typename ReadHandler>
113 inline void asio_handler_deallocate(void* pointer, std::size_t size,
114 buffered_fill_handler<ReadHandler>* this_handler)
115 {
116 boost_asio_handler_alloc_helpers::deallocate(
117 pointer, size, this_handler->handler_);
118 }
119
120 template <typename ReadHandler>
121 inline bool asio_handler_is_continuation(
122 buffered_fill_handler<ReadHandler>* this_handler)
123 {
124 return boost_asio_handler_cont_helpers::is_continuation(
125 this_handler->handler_);
126 }
127
128 template <typename Function, typename ReadHandler>
129 inline void asio_handler_invoke(Function& function,
130 buffered_fill_handler<ReadHandler>* this_handler)
131 {
132 boost_asio_handler_invoke_helpers::invoke(
133 function, this_handler->handler_);
134 }
135
136 template <typename Function, typename ReadHandler>
137 inline void asio_handler_invoke(const Function& function,
138 buffered_fill_handler<ReadHandler>* this_handler)
139 {
140 boost_asio_handler_invoke_helpers::invoke(
141 function, this_handler->handler_);
142 }
92f5a8d4
TL
143
144 template <typename Stream>
145 class initiate_async_buffered_fill
146 {
147 public:
148 typedef typename remove_reference<
149 Stream>::type::lowest_layer_type::executor_type executor_type;
150
f67539c2
TL
151 explicit initiate_async_buffered_fill(
152 typename remove_reference<Stream>::type& next_layer)
92f5a8d4
TL
153 : next_layer_(next_layer)
154 {
155 }
156
157 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
158 {
159 return next_layer_.lowest_layer().get_executor();
160 }
161
162 template <typename ReadHandler>
163 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
164 buffered_stream_storage* storage) const
165 {
166 // If you get an error on the following line it means that your handler
167 // does not meet the documented type requirements for a ReadHandler.
168 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
169
170 non_const_lvalue<ReadHandler> handler2(handler);
171 std::size_t previous_size = storage->size();
172 storage->resize(storage->capacity());
173 next_layer_.async_read_some(
174 buffer(
175 storage->data() + previous_size,
176 storage->size() - previous_size),
177 buffered_fill_handler<typename decay<ReadHandler>::type>(
178 *storage, previous_size, handler2.value));
179 }
180
181 private:
f67539c2 182 typename remove_reference<Stream>::type& next_layer_;
92f5a8d4 183 };
7c673cae
FG
184} // namespace detail
185
b32b8144
FG
186#if !defined(GENERATING_DOCUMENTATION)
187
188template <typename ReadHandler, typename Allocator>
189struct associated_allocator<
190 detail::buffered_fill_handler<ReadHandler>, Allocator>
191{
192 typedef typename associated_allocator<ReadHandler, Allocator>::type type;
193
194 static type get(const detail::buffered_fill_handler<ReadHandler>& h,
195 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
196 {
197 return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
198 }
199};
200
201template <typename ReadHandler, typename Executor>
202struct associated_executor<
203 detail::buffered_fill_handler<ReadHandler>, Executor>
204{
205 typedef typename associated_executor<ReadHandler, Executor>::type type;
206
207 static type get(const detail::buffered_fill_handler<ReadHandler>& h,
208 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
209 {
210 return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
211 }
212};
213
214#endif // !defined(GENERATING_DOCUMENTATION)
215
7c673cae 216template <typename Stream>
92f5a8d4
TL
217template <
218 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
219 std::size_t)) ReadHandler>
220BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
7c673cae
FG
221 void (boost::system::error_code, std::size_t))
222buffered_read_stream<Stream>::async_fill(
223 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
224{
92f5a8d4
TL
225 return async_initiate<ReadHandler,
226 void (boost::system::error_code, std::size_t)>(
227 detail::initiate_async_buffered_fill<Stream>(next_layer_),
228 handler, &storage_);
7c673cae
FG
229}
230
231template <typename Stream>
232template <typename MutableBufferSequence>
233std::size_t buffered_read_stream<Stream>::read_some(
234 const MutableBufferSequence& buffers)
235{
b32b8144
FG
236 using boost::asio::buffer_size;
237 if (buffer_size(buffers) == 0)
7c673cae
FG
238 return 0;
239
240 if (storage_.empty())
241 this->fill();
242
243 return this->copy(buffers);
244}
245
246template <typename Stream>
247template <typename MutableBufferSequence>
248std::size_t buffered_read_stream<Stream>::read_some(
249 const MutableBufferSequence& buffers, boost::system::error_code& ec)
250{
251 ec = boost::system::error_code();
252
b32b8144
FG
253 using boost::asio::buffer_size;
254 if (buffer_size(buffers) == 0)
7c673cae
FG
255 return 0;
256
257 if (storage_.empty() && !this->fill(ec))
258 return 0;
259
260 return this->copy(buffers);
261}
262
263namespace detail
264{
265 template <typename MutableBufferSequence, typename ReadHandler>
266 class buffered_read_some_handler
267 {
268 public:
269 buffered_read_some_handler(detail::buffered_stream_storage& storage,
270 const MutableBufferSequence& buffers, ReadHandler& handler)
271 : storage_(storage),
272 buffers_(buffers),
b32b8144 273 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
7c673cae
FG
274 {
275 }
276
277#if defined(BOOST_ASIO_HAS_MOVE)
278 buffered_read_some_handler(const buffered_read_some_handler& other)
279 : storage_(other.storage_),
280 buffers_(other.buffers_),
281 handler_(other.handler_)
282 {
283 }
284
285 buffered_read_some_handler(buffered_read_some_handler&& other)
286 : storage_(other.storage_),
287 buffers_(other.buffers_),
288 handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
289 {
290 }
291#endif // defined(BOOST_ASIO_HAS_MOVE)
292
293 void operator()(const boost::system::error_code& ec, std::size_t)
294 {
295 if (ec || storage_.empty())
296 {
297 const std::size_t length = 0;
298 handler_(ec, length);
299 }
300 else
301 {
302 const std::size_t bytes_copied = boost::asio::buffer_copy(
303 buffers_, storage_.data(), storage_.size());
304 storage_.consume(bytes_copied);
305 handler_(ec, bytes_copied);
306 }
307 }
308
309 //private:
310 detail::buffered_stream_storage& storage_;
311 MutableBufferSequence buffers_;
312 ReadHandler handler_;
313 };
314
315 template <typename MutableBufferSequence, typename ReadHandler>
316 inline void* asio_handler_allocate(std::size_t size,
317 buffered_read_some_handler<
318 MutableBufferSequence, ReadHandler>* this_handler)
319 {
320 return boost_asio_handler_alloc_helpers::allocate(
321 size, this_handler->handler_);
322 }
323
324 template <typename MutableBufferSequence, typename ReadHandler>
325 inline void asio_handler_deallocate(void* pointer, std::size_t size,
326 buffered_read_some_handler<
327 MutableBufferSequence, ReadHandler>* this_handler)
328 {
329 boost_asio_handler_alloc_helpers::deallocate(
330 pointer, size, this_handler->handler_);
331 }
332
333 template <typename MutableBufferSequence, typename ReadHandler>
334 inline bool asio_handler_is_continuation(
335 buffered_read_some_handler<
336 MutableBufferSequence, ReadHandler>* this_handler)
337 {
338 return boost_asio_handler_cont_helpers::is_continuation(
339 this_handler->handler_);
340 }
341
342 template <typename Function, typename MutableBufferSequence,
343 typename ReadHandler>
344 inline void asio_handler_invoke(Function& function,
345 buffered_read_some_handler<
346 MutableBufferSequence, ReadHandler>* this_handler)
347 {
348 boost_asio_handler_invoke_helpers::invoke(
349 function, this_handler->handler_);
350 }
351
352 template <typename Function, typename MutableBufferSequence,
353 typename ReadHandler>
354 inline void asio_handler_invoke(const Function& function,
355 buffered_read_some_handler<
356 MutableBufferSequence, ReadHandler>* this_handler)
357 {
358 boost_asio_handler_invoke_helpers::invoke(
359 function, this_handler->handler_);
360 }
92f5a8d4
TL
361
362 template <typename Stream>
363 class initiate_async_buffered_read_some
364 {
365 public:
366 typedef typename remove_reference<
367 Stream>::type::lowest_layer_type::executor_type executor_type;
368
f67539c2
TL
369 explicit initiate_async_buffered_read_some(
370 typename remove_reference<Stream>::type& next_layer)
92f5a8d4
TL
371 : next_layer_(next_layer)
372 {
373 }
374
375 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
376 {
377 return next_layer_.lowest_layer().get_executor();
378 }
379
380 template <typename ReadHandler, typename MutableBufferSequence>
381 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
382 buffered_stream_storage* storage,
383 const MutableBufferSequence& buffers) const
384 {
385 // If you get an error on the following line it means that your handler
386 // does not meet the documented type requirements for a ReadHandler.
387 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
388
389 using boost::asio::buffer_size;
390 non_const_lvalue<ReadHandler> handler2(handler);
391 if (buffer_size(buffers) == 0 || !storage->empty())
392 {
393 next_layer_.async_read_some(BOOST_ASIO_MUTABLE_BUFFER(0, 0),
394 buffered_read_some_handler<MutableBufferSequence,
395 typename decay<ReadHandler>::type>(
396 *storage, buffers, handler2.value));
397 }
398 else
399 {
400 initiate_async_buffered_fill<Stream>(this->next_layer_)(
401 buffered_read_some_handler<MutableBufferSequence,
402 typename decay<ReadHandler>::type>(
403 *storage, buffers, handler2.value),
404 storage);
405 }
406 }
407
408 private:
f67539c2 409 typename remove_reference<Stream>::type& next_layer_;
92f5a8d4 410 };
7c673cae
FG
411} // namespace detail
412
b32b8144
FG
413#if !defined(GENERATING_DOCUMENTATION)
414
415template <typename MutableBufferSequence,
416 typename ReadHandler, typename Allocator>
417struct associated_allocator<
418 detail::buffered_read_some_handler<MutableBufferSequence, ReadHandler>,
419 Allocator>
420{
421 typedef typename associated_allocator<ReadHandler, Allocator>::type type;
422
423 static type get(
424 const detail::buffered_read_some_handler<
425 MutableBufferSequence, ReadHandler>& h,
426 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
427 {
428 return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
429 }
430};
431
432template <typename MutableBufferSequence,
433 typename ReadHandler, typename Executor>
434struct associated_executor<
435 detail::buffered_read_some_handler<MutableBufferSequence, ReadHandler>,
436 Executor>
437{
438 typedef typename associated_executor<ReadHandler, Executor>::type type;
439
440 static type get(
441 const detail::buffered_read_some_handler<
442 MutableBufferSequence, ReadHandler>& h,
443 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
444 {
445 return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
446 }
447};
448
449#endif // !defined(GENERATING_DOCUMENTATION)
450
7c673cae 451template <typename Stream>
92f5a8d4
TL
452template <typename MutableBufferSequence,
453 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
454 std::size_t)) ReadHandler>
455BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
7c673cae
FG
456 void (boost::system::error_code, std::size_t))
457buffered_read_stream<Stream>::async_read_some(
458 const MutableBufferSequence& buffers,
459 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
460{
92f5a8d4
TL
461 return async_initiate<ReadHandler,
462 void (boost::system::error_code, std::size_t)>(
463 detail::initiate_async_buffered_read_some<Stream>(next_layer_),
464 handler, &storage_, buffers);
7c673cae
FG
465}
466
467template <typename Stream>
468template <typename MutableBufferSequence>
469std::size_t buffered_read_stream<Stream>::peek(
470 const MutableBufferSequence& buffers)
471{
472 if (storage_.empty())
473 this->fill();
474 return this->peek_copy(buffers);
475}
476
477template <typename Stream>
478template <typename MutableBufferSequence>
479std::size_t buffered_read_stream<Stream>::peek(
480 const MutableBufferSequence& buffers, boost::system::error_code& ec)
481{
482 ec = boost::system::error_code();
483 if (storage_.empty() && !this->fill(ec))
484 return 0;
485 return this->peek_copy(buffers);
486}
487
488} // namespace asio
489} // namespace boost
490
491#include <boost/asio/detail/pop_options.hpp>
492
493#endif // BOOST_ASIO_IMPL_BUFFERED_READ_STREAM_HPP