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