]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | // |
2 | // impl/read.hpp | |
3 | // ~~~~~~~~~~~~~ | |
4 | // | |
1e59de90 | 5 | // Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
b32b8144 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_READ_HPP | |
12 | #define BOOST_ASIO_IMPL_READ_HPP | |
13 | ||
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) | |
15 | # pragma once | |
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) | |
17 | ||
18 | #include <algorithm> | |
1e59de90 | 19 | #include <boost/asio/associator.hpp> |
b32b8144 FG |
20 | #include <boost/asio/buffer.hpp> |
21 | #include <boost/asio/completion_condition.hpp> | |
22 | #include <boost/asio/detail/array_fwd.hpp> | |
1e59de90 | 23 | #include <boost/asio/detail/base_from_cancellation_state.hpp> |
b32b8144 FG |
24 | #include <boost/asio/detail/base_from_completion_cond.hpp> |
25 | #include <boost/asio/detail/bind_handler.hpp> | |
26 | #include <boost/asio/detail/consuming_buffers.hpp> | |
27 | #include <boost/asio/detail/dependent_type.hpp> | |
28 | #include <boost/asio/detail/handler_alloc_helpers.hpp> | |
29 | #include <boost/asio/detail/handler_cont_helpers.hpp> | |
30 | #include <boost/asio/detail/handler_invoke_helpers.hpp> | |
20effc67 | 31 | #include <boost/asio/detail/handler_tracking.hpp> |
b32b8144 | 32 | #include <boost/asio/detail/handler_type_requirements.hpp> |
92f5a8d4 | 33 | #include <boost/asio/detail/non_const_lvalue.hpp> |
b32b8144 FG |
34 | #include <boost/asio/detail/throw_error.hpp> |
35 | #include <boost/asio/error.hpp> | |
36 | ||
37 | #include <boost/asio/detail/push_options.hpp> | |
38 | ||
39 | namespace boost { | |
40 | namespace asio { | |
41 | ||
42 | namespace detail | |
43 | { | |
44 | template <typename SyncReadStream, typename MutableBufferSequence, | |
45 | typename MutableBufferIterator, typename CompletionCondition> | |
46 | std::size_t read_buffer_sequence(SyncReadStream& s, | |
47 | const MutableBufferSequence& buffers, const MutableBufferIterator&, | |
48 | CompletionCondition completion_condition, boost::system::error_code& ec) | |
49 | { | |
50 | ec = boost::system::error_code(); | |
51 | boost::asio::detail::consuming_buffers<mutable_buffer, | |
52 | MutableBufferSequence, MutableBufferIterator> tmp(buffers); | |
53 | while (!tmp.empty()) | |
54 | { | |
55 | if (std::size_t max_size = detail::adapt_completion_condition_result( | |
56 | completion_condition(ec, tmp.total_consumed()))) | |
57 | tmp.consume(s.read_some(tmp.prepare(max_size), ec)); | |
58 | else | |
59 | break; | |
60 | } | |
20effc67 | 61 | return tmp.total_consumed(); |
b32b8144 FG |
62 | } |
63 | } // namespace detail | |
64 | ||
65 | template <typename SyncReadStream, typename MutableBufferSequence, | |
66 | typename CompletionCondition> | |
67 | std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, | |
68 | CompletionCondition completion_condition, boost::system::error_code& ec, | |
1e59de90 | 69 | typename constraint< |
b32b8144 | 70 | is_mutable_buffer_sequence<MutableBufferSequence>::value |
1e59de90 | 71 | >::type) |
b32b8144 FG |
72 | { |
73 | return detail::read_buffer_sequence(s, buffers, | |
92f5a8d4 TL |
74 | boost::asio::buffer_sequence_begin(buffers), |
75 | BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); | |
b32b8144 FG |
76 | } |
77 | ||
78 | template <typename SyncReadStream, typename MutableBufferSequence> | |
79 | inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, | |
1e59de90 | 80 | typename constraint< |
b32b8144 | 81 | is_mutable_buffer_sequence<MutableBufferSequence>::value |
1e59de90 | 82 | >::type) |
b32b8144 FG |
83 | { |
84 | boost::system::error_code ec; | |
85 | std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec); | |
86 | boost::asio::detail::throw_error(ec, "read"); | |
87 | return bytes_transferred; | |
88 | } | |
89 | ||
90 | template <typename SyncReadStream, typename MutableBufferSequence> | |
91 | inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, | |
92 | boost::system::error_code& ec, | |
1e59de90 | 93 | typename constraint< |
b32b8144 | 94 | is_mutable_buffer_sequence<MutableBufferSequence>::value |
1e59de90 | 95 | >::type) |
b32b8144 FG |
96 | { |
97 | return read(s, buffers, transfer_all(), ec); | |
98 | } | |
99 | ||
100 | template <typename SyncReadStream, typename MutableBufferSequence, | |
101 | typename CompletionCondition> | |
102 | inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, | |
103 | CompletionCondition completion_condition, | |
1e59de90 | 104 | typename constraint< |
b32b8144 | 105 | is_mutable_buffer_sequence<MutableBufferSequence>::value |
1e59de90 | 106 | >::type) |
b32b8144 FG |
107 | { |
108 | boost::system::error_code ec; | |
92f5a8d4 TL |
109 | std::size_t bytes_transferred = read(s, buffers, |
110 | BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); | |
b32b8144 FG |
111 | boost::asio::detail::throw_error(ec, "read"); |
112 | return bytes_transferred; | |
113 | } | |
114 | ||
92f5a8d4 TL |
115 | #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) |
116 | ||
117 | template <typename SyncReadStream, typename DynamicBuffer_v1, | |
b32b8144 FG |
118 | typename CompletionCondition> |
119 | std::size_t read(SyncReadStream& s, | |
92f5a8d4 | 120 | BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, |
b32b8144 | 121 | CompletionCondition completion_condition, boost::system::error_code& ec, |
1e59de90 | 122 | typename constraint< |
92f5a8d4 | 123 | is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value |
1e59de90 TL |
124 | >::type, |
125 | typename constraint< | |
126 | !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value | |
127 | >::type) | |
b32b8144 | 128 | { |
92f5a8d4 TL |
129 | typename decay<DynamicBuffer_v1>::type b( |
130 | BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers)); | |
b32b8144 FG |
131 | |
132 | ec = boost::system::error_code(); | |
133 | std::size_t total_transferred = 0; | |
134 | std::size_t max_size = detail::adapt_completion_condition_result( | |
135 | completion_condition(ec, total_transferred)); | |
136 | std::size_t bytes_available = std::min<std::size_t>( | |
137 | std::max<std::size_t>(512, b.capacity() - b.size()), | |
138 | std::min<std::size_t>(max_size, b.max_size() - b.size())); | |
139 | while (bytes_available > 0) | |
140 | { | |
141 | std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec); | |
142 | b.commit(bytes_transferred); | |
143 | total_transferred += bytes_transferred; | |
144 | max_size = detail::adapt_completion_condition_result( | |
145 | completion_condition(ec, total_transferred)); | |
146 | bytes_available = std::min<std::size_t>( | |
147 | std::max<std::size_t>(512, b.capacity() - b.size()), | |
148 | std::min<std::size_t>(max_size, b.max_size() - b.size())); | |
149 | } | |
150 | return total_transferred; | |
151 | } | |
152 | ||
92f5a8d4 | 153 | template <typename SyncReadStream, typename DynamicBuffer_v1> |
b32b8144 | 154 | inline std::size_t read(SyncReadStream& s, |
92f5a8d4 | 155 | BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, |
1e59de90 | 156 | typename constraint< |
92f5a8d4 | 157 | is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value |
1e59de90 TL |
158 | >::type, |
159 | typename constraint< | |
160 | !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value | |
161 | >::type) | |
b32b8144 FG |
162 | { |
163 | boost::system::error_code ec; | |
164 | std::size_t bytes_transferred = read(s, | |
92f5a8d4 | 165 | BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec); |
b32b8144 FG |
166 | boost::asio::detail::throw_error(ec, "read"); |
167 | return bytes_transferred; | |
168 | } | |
169 | ||
92f5a8d4 | 170 | template <typename SyncReadStream, typename DynamicBuffer_v1> |
b32b8144 | 171 | inline std::size_t read(SyncReadStream& s, |
92f5a8d4 | 172 | BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, |
b32b8144 | 173 | boost::system::error_code& ec, |
1e59de90 | 174 | typename constraint< |
92f5a8d4 | 175 | is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value |
1e59de90 TL |
176 | >::type, |
177 | typename constraint< | |
178 | !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value | |
179 | >::type) | |
b32b8144 | 180 | { |
92f5a8d4 | 181 | return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), |
b32b8144 FG |
182 | transfer_all(), ec); |
183 | } | |
184 | ||
92f5a8d4 | 185 | template <typename SyncReadStream, typename DynamicBuffer_v1, |
b32b8144 FG |
186 | typename CompletionCondition> |
187 | inline std::size_t read(SyncReadStream& s, | |
92f5a8d4 | 188 | BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, |
b32b8144 | 189 | CompletionCondition completion_condition, |
1e59de90 | 190 | typename constraint< |
92f5a8d4 | 191 | is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value |
1e59de90 TL |
192 | >::type, |
193 | typename constraint< | |
194 | !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value | |
195 | >::type) | |
b32b8144 FG |
196 | { |
197 | boost::system::error_code ec; | |
198 | std::size_t bytes_transferred = read(s, | |
92f5a8d4 TL |
199 | BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), |
200 | BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); | |
b32b8144 FG |
201 | boost::asio::detail::throw_error(ec, "read"); |
202 | return bytes_transferred; | |
203 | } | |
204 | ||
205 | #if !defined(BOOST_ASIO_NO_EXTENSIONS) | |
206 | #if !defined(BOOST_ASIO_NO_IOSTREAM) | |
207 | ||
208 | template <typename SyncReadStream, typename Allocator, | |
209 | typename CompletionCondition> | |
210 | inline std::size_t read(SyncReadStream& s, | |
211 | boost::asio::basic_streambuf<Allocator>& b, | |
212 | CompletionCondition completion_condition, boost::system::error_code& ec) | |
213 | { | |
92f5a8d4 TL |
214 | return read(s, basic_streambuf_ref<Allocator>(b), |
215 | BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); | |
b32b8144 FG |
216 | } |
217 | ||
218 | template <typename SyncReadStream, typename Allocator> | |
219 | inline std::size_t read(SyncReadStream& s, | |
220 | boost::asio::basic_streambuf<Allocator>& b) | |
221 | { | |
222 | return read(s, basic_streambuf_ref<Allocator>(b)); | |
223 | } | |
224 | ||
225 | template <typename SyncReadStream, typename Allocator> | |
226 | inline std::size_t read(SyncReadStream& s, | |
227 | boost::asio::basic_streambuf<Allocator>& b, | |
228 | boost::system::error_code& ec) | |
229 | { | |
230 | return read(s, basic_streambuf_ref<Allocator>(b), ec); | |
231 | } | |
232 | ||
233 | template <typename SyncReadStream, typename Allocator, | |
234 | typename CompletionCondition> | |
235 | inline std::size_t read(SyncReadStream& s, | |
236 | boost::asio::basic_streambuf<Allocator>& b, | |
237 | CompletionCondition completion_condition) | |
238 | { | |
92f5a8d4 TL |
239 | return read(s, basic_streambuf_ref<Allocator>(b), |
240 | BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); | |
b32b8144 FG |
241 | } |
242 | ||
243 | #endif // !defined(BOOST_ASIO_NO_IOSTREAM) | |
244 | #endif // !defined(BOOST_ASIO_NO_EXTENSIONS) | |
92f5a8d4 TL |
245 | #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) |
246 | ||
247 | template <typename SyncReadStream, typename DynamicBuffer_v2, | |
248 | typename CompletionCondition> | |
249 | std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, | |
250 | CompletionCondition completion_condition, boost::system::error_code& ec, | |
1e59de90 | 251 | typename constraint< |
92f5a8d4 | 252 | is_dynamic_buffer_v2<DynamicBuffer_v2>::value |
1e59de90 | 253 | >::type) |
92f5a8d4 TL |
254 | { |
255 | DynamicBuffer_v2& b = buffers; | |
256 | ||
257 | ec = boost::system::error_code(); | |
258 | std::size_t total_transferred = 0; | |
259 | std::size_t max_size = detail::adapt_completion_condition_result( | |
260 | completion_condition(ec, total_transferred)); | |
261 | std::size_t bytes_available = std::min<std::size_t>( | |
262 | std::max<std::size_t>(512, b.capacity() - b.size()), | |
263 | std::min<std::size_t>(max_size, b.max_size() - b.size())); | |
264 | while (bytes_available > 0) | |
265 | { | |
266 | std::size_t pos = b.size(); | |
267 | b.grow(bytes_available); | |
268 | std::size_t bytes_transferred = s.read_some( | |
269 | b.data(pos, bytes_available), ec); | |
270 | b.shrink(bytes_available - bytes_transferred); | |
271 | total_transferred += bytes_transferred; | |
272 | max_size = detail::adapt_completion_condition_result( | |
273 | completion_condition(ec, total_transferred)); | |
274 | bytes_available = std::min<std::size_t>( | |
275 | std::max<std::size_t>(512, b.capacity() - b.size()), | |
276 | std::min<std::size_t>(max_size, b.max_size() - b.size())); | |
277 | } | |
278 | return total_transferred; | |
279 | } | |
280 | ||
281 | template <typename SyncReadStream, typename DynamicBuffer_v2> | |
282 | inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, | |
1e59de90 | 283 | typename constraint< |
92f5a8d4 | 284 | is_dynamic_buffer_v2<DynamicBuffer_v2>::value |
1e59de90 | 285 | >::type) |
92f5a8d4 TL |
286 | { |
287 | boost::system::error_code ec; | |
288 | std::size_t bytes_transferred = read(s, | |
289 | BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec); | |
290 | boost::asio::detail::throw_error(ec, "read"); | |
291 | return bytes_transferred; | |
292 | } | |
293 | ||
294 | template <typename SyncReadStream, typename DynamicBuffer_v2> | |
295 | inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, | |
296 | boost::system::error_code& ec, | |
1e59de90 | 297 | typename constraint< |
92f5a8d4 | 298 | is_dynamic_buffer_v2<DynamicBuffer_v2>::value |
1e59de90 | 299 | >::type) |
92f5a8d4 TL |
300 | { |
301 | return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), | |
302 | transfer_all(), ec); | |
303 | } | |
304 | ||
305 | template <typename SyncReadStream, typename DynamicBuffer_v2, | |
306 | typename CompletionCondition> | |
307 | inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, | |
308 | CompletionCondition completion_condition, | |
1e59de90 | 309 | typename constraint< |
92f5a8d4 | 310 | is_dynamic_buffer_v2<DynamicBuffer_v2>::value |
1e59de90 | 311 | >::type) |
92f5a8d4 TL |
312 | { |
313 | boost::system::error_code ec; | |
314 | std::size_t bytes_transferred = read(s, | |
315 | BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), | |
316 | BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); | |
317 | boost::asio::detail::throw_error(ec, "read"); | |
318 | return bytes_transferred; | |
319 | } | |
b32b8144 FG |
320 | |
321 | namespace detail | |
322 | { | |
323 | template <typename AsyncReadStream, typename MutableBufferSequence, | |
324 | typename MutableBufferIterator, typename CompletionCondition, | |
325 | typename ReadHandler> | |
326 | class read_op | |
1e59de90 TL |
327 | : public base_from_cancellation_state<ReadHandler>, |
328 | base_from_completion_cond<CompletionCondition> | |
b32b8144 FG |
329 | { |
330 | public: | |
331 | read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers, | |
92f5a8d4 | 332 | CompletionCondition& completion_condition, ReadHandler& handler) |
1e59de90 TL |
333 | : base_from_cancellation_state<ReadHandler>( |
334 | handler, enable_partial_cancellation()), | |
335 | base_from_completion_cond<CompletionCondition>(completion_condition), | |
b32b8144 FG |
336 | stream_(stream), |
337 | buffers_(buffers), | |
338 | start_(0), | |
339 | handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) | |
340 | { | |
341 | } | |
342 | ||
343 | #if defined(BOOST_ASIO_HAS_MOVE) | |
344 | read_op(const read_op& other) | |
1e59de90 TL |
345 | : base_from_cancellation_state<ReadHandler>(other), |
346 | base_from_completion_cond<CompletionCondition>(other), | |
b32b8144 FG |
347 | stream_(other.stream_), |
348 | buffers_(other.buffers_), | |
349 | start_(other.start_), | |
350 | handler_(other.handler_) | |
351 | { | |
352 | } | |
353 | ||
354 | read_op(read_op&& other) | |
1e59de90 TL |
355 | : base_from_cancellation_state<ReadHandler>( |
356 | BOOST_ASIO_MOVE_CAST(base_from_cancellation_state< | |
357 | ReadHandler>)(other)), | |
358 | base_from_completion_cond<CompletionCondition>( | |
359 | BOOST_ASIO_MOVE_CAST(base_from_completion_cond< | |
92f5a8d4 | 360 | CompletionCondition>)(other)), |
b32b8144 | 361 | stream_(other.stream_), |
92f5a8d4 | 362 | buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)), |
b32b8144 FG |
363 | start_(other.start_), |
364 | handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) | |
365 | { | |
366 | } | |
367 | #endif // defined(BOOST_ASIO_HAS_MOVE) | |
368 | ||
1e59de90 | 369 | void operator()(boost::system::error_code ec, |
b32b8144 FG |
370 | std::size_t bytes_transferred, int start = 0) |
371 | { | |
372 | std::size_t max_size; | |
373 | switch (start_ = start) | |
374 | { | |
375 | case 1: | |
376 | max_size = this->check_for_completion(ec, buffers_.total_consumed()); | |
1e59de90 | 377 | for (;;) |
b32b8144 | 378 | { |
20effc67 TL |
379 | { |
380 | BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read")); | |
381 | stream_.async_read_some(buffers_.prepare(max_size), | |
382 | BOOST_ASIO_MOVE_CAST(read_op)(*this)); | |
383 | } | |
b32b8144 FG |
384 | return; default: |
385 | buffers_.consume(bytes_transferred); | |
386 | if ((!ec && bytes_transferred == 0) || buffers_.empty()) | |
387 | break; | |
388 | max_size = this->check_for_completion(ec, buffers_.total_consumed()); | |
1e59de90 TL |
389 | if (max_size == 0) |
390 | break; | |
391 | if (this->cancelled() != cancellation_type::none) | |
392 | { | |
393 | ec = error::operation_aborted; | |
394 | break; | |
395 | } | |
396 | } | |
b32b8144 | 397 | |
1e59de90 TL |
398 | BOOST_ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)( |
399 | static_cast<const boost::system::error_code&>(ec), | |
400 | static_cast<const std::size_t&>(buffers_.total_consumed())); | |
b32b8144 FG |
401 | } |
402 | } | |
403 | ||
404 | //private: | |
92f5a8d4 TL |
405 | typedef boost::asio::detail::consuming_buffers<mutable_buffer, |
406 | MutableBufferSequence, MutableBufferIterator> buffers_type; | |
407 | ||
b32b8144 | 408 | AsyncReadStream& stream_; |
92f5a8d4 | 409 | buffers_type buffers_; |
b32b8144 FG |
410 | int start_; |
411 | ReadHandler handler_; | |
412 | }; | |
413 | ||
414 | template <typename AsyncReadStream, typename MutableBufferSequence, | |
415 | typename MutableBufferIterator, typename CompletionCondition, | |
416 | typename ReadHandler> | |
20effc67 TL |
417 | inline asio_handler_allocate_is_deprecated |
418 | asio_handler_allocate(std::size_t size, | |
b32b8144 FG |
419 | read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator, |
420 | CompletionCondition, ReadHandler>* this_handler) | |
421 | { | |
20effc67 TL |
422 | #if defined(BOOST_ASIO_NO_DEPRECATED) |
423 | boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_); | |
424 | return asio_handler_allocate_is_no_longer_used(); | |
425 | #else // defined(BOOST_ASIO_NO_DEPRECATED) | |
b32b8144 FG |
426 | return boost_asio_handler_alloc_helpers::allocate( |
427 | size, this_handler->handler_); | |
20effc67 | 428 | #endif // defined(BOOST_ASIO_NO_DEPRECATED) |
b32b8144 FG |
429 | } |
430 | ||
431 | template <typename AsyncReadStream, typename MutableBufferSequence, | |
432 | typename MutableBufferIterator, typename CompletionCondition, | |
433 | typename ReadHandler> | |
20effc67 TL |
434 | inline asio_handler_deallocate_is_deprecated |
435 | asio_handler_deallocate(void* pointer, std::size_t size, | |
b32b8144 FG |
436 | read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator, |
437 | CompletionCondition, ReadHandler>* this_handler) | |
438 | { | |
439 | boost_asio_handler_alloc_helpers::deallocate( | |
440 | pointer, size, this_handler->handler_); | |
20effc67 TL |
441 | #if defined(BOOST_ASIO_NO_DEPRECATED) |
442 | return asio_handler_deallocate_is_no_longer_used(); | |
443 | #endif // defined(BOOST_ASIO_NO_DEPRECATED) | |
b32b8144 FG |
444 | } |
445 | ||
446 | template <typename AsyncReadStream, typename MutableBufferSequence, | |
447 | typename MutableBufferIterator, typename CompletionCondition, | |
448 | typename ReadHandler> | |
449 | inline bool asio_handler_is_continuation( | |
450 | read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator, | |
451 | CompletionCondition, ReadHandler>* this_handler) | |
452 | { | |
453 | return this_handler->start_ == 0 ? true | |
454 | : boost_asio_handler_cont_helpers::is_continuation( | |
455 | this_handler->handler_); | |
456 | } | |
457 | ||
458 | template <typename Function, typename AsyncReadStream, | |
459 | typename MutableBufferSequence, typename MutableBufferIterator, | |
460 | typename CompletionCondition, typename ReadHandler> | |
20effc67 TL |
461 | inline asio_handler_invoke_is_deprecated |
462 | asio_handler_invoke(Function& function, | |
b32b8144 FG |
463 | read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator, |
464 | CompletionCondition, ReadHandler>* this_handler) | |
465 | { | |
466 | boost_asio_handler_invoke_helpers::invoke( | |
467 | function, this_handler->handler_); | |
20effc67 TL |
468 | #if defined(BOOST_ASIO_NO_DEPRECATED) |
469 | return asio_handler_invoke_is_no_longer_used(); | |
470 | #endif // defined(BOOST_ASIO_NO_DEPRECATED) | |
b32b8144 FG |
471 | } |
472 | ||
473 | template <typename Function, typename AsyncReadStream, | |
474 | typename MutableBufferSequence, typename MutableBufferIterator, | |
475 | typename CompletionCondition, typename ReadHandler> | |
20effc67 TL |
476 | inline asio_handler_invoke_is_deprecated |
477 | asio_handler_invoke(const Function& function, | |
b32b8144 FG |
478 | read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator, |
479 | CompletionCondition, ReadHandler>* this_handler) | |
480 | { | |
481 | boost_asio_handler_invoke_helpers::invoke( | |
482 | function, this_handler->handler_); | |
20effc67 TL |
483 | #if defined(BOOST_ASIO_NO_DEPRECATED) |
484 | return asio_handler_invoke_is_no_longer_used(); | |
485 | #endif // defined(BOOST_ASIO_NO_DEPRECATED) | |
b32b8144 FG |
486 | } |
487 | ||
488 | template <typename AsyncReadStream, typename MutableBufferSequence, | |
489 | typename MutableBufferIterator, typename CompletionCondition, | |
490 | typename ReadHandler> | |
491 | inline void start_read_buffer_sequence_op(AsyncReadStream& stream, | |
492 | const MutableBufferSequence& buffers, const MutableBufferIterator&, | |
92f5a8d4 | 493 | CompletionCondition& completion_condition, ReadHandler& handler) |
b32b8144 FG |
494 | { |
495 | detail::read_op<AsyncReadStream, MutableBufferSequence, | |
496 | MutableBufferIterator, CompletionCondition, ReadHandler>( | |
497 | stream, buffers, completion_condition, handler)( | |
498 | boost::system::error_code(), 0, 1); | |
499 | } | |
92f5a8d4 TL |
500 | |
501 | template <typename AsyncReadStream> | |
502 | class initiate_async_read_buffer_sequence | |
503 | { | |
504 | public: | |
505 | typedef typename AsyncReadStream::executor_type executor_type; | |
506 | ||
507 | explicit initiate_async_read_buffer_sequence(AsyncReadStream& stream) | |
508 | : stream_(stream) | |
509 | { | |
510 | } | |
511 | ||
512 | executor_type get_executor() const BOOST_ASIO_NOEXCEPT | |
513 | { | |
514 | return stream_.get_executor(); | |
515 | } | |
516 | ||
517 | template <typename ReadHandler, typename MutableBufferSequence, | |
518 | typename CompletionCondition> | |
519 | void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, | |
520 | const MutableBufferSequence& buffers, | |
521 | BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const | |
522 | { | |
523 | // If you get an error on the following line it means that your handler | |
524 | // does not meet the documented type requirements for a ReadHandler. | |
525 | BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; | |
526 | ||
527 | non_const_lvalue<ReadHandler> handler2(handler); | |
528 | non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); | |
529 | start_read_buffer_sequence_op(stream_, buffers, | |
530 | boost::asio::buffer_sequence_begin(buffers), | |
531 | completion_cond2.value, handler2.value); | |
532 | } | |
533 | ||
534 | private: | |
535 | AsyncReadStream& stream_; | |
536 | }; | |
b32b8144 FG |
537 | } // namespace detail |
538 | ||
539 | #if !defined(GENERATING_DOCUMENTATION) | |
540 | ||
1e59de90 TL |
541 | template <template <typename, typename> class Associator, |
542 | typename AsyncReadStream, typename MutableBufferSequence, | |
b32b8144 | 543 | typename MutableBufferIterator, typename CompletionCondition, |
1e59de90 TL |
544 | typename ReadHandler, typename DefaultCandidate> |
545 | struct associator<Associator, | |
b32b8144 FG |
546 | detail::read_op<AsyncReadStream, MutableBufferSequence, |
547 | MutableBufferIterator, CompletionCondition, ReadHandler>, | |
1e59de90 TL |
548 | DefaultCandidate> |
549 | : Associator<ReadHandler, DefaultCandidate> | |
b32b8144 | 550 | { |
1e59de90 | 551 | static typename Associator<ReadHandler, DefaultCandidate>::type get( |
b32b8144 FG |
552 | const detail::read_op<AsyncReadStream, MutableBufferSequence, |
553 | MutableBufferIterator, CompletionCondition, ReadHandler>& h, | |
1e59de90 | 554 | const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT |
b32b8144 | 555 | { |
1e59de90 | 556 | return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); |
b32b8144 FG |
557 | } |
558 | }; | |
559 | ||
560 | #endif // !defined(GENERATING_DOCUMENTATION) | |
561 | ||
92f5a8d4 TL |
562 | template <typename AsyncReadStream, |
563 | typename MutableBufferSequence, typename CompletionCondition, | |
564 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
1e59de90 TL |
565 | std::size_t)) ReadToken> |
566 | inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken, | |
b32b8144 FG |
567 | void (boost::system::error_code, std::size_t)) |
568 | async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, | |
569 | CompletionCondition completion_condition, | |
1e59de90 TL |
570 | BOOST_ASIO_MOVE_ARG(ReadToken) token, |
571 | typename constraint< | |
b32b8144 | 572 | is_mutable_buffer_sequence<MutableBufferSequence>::value |
1e59de90 | 573 | >::type) |
b32b8144 | 574 | { |
1e59de90 | 575 | return async_initiate<ReadToken, |
92f5a8d4 | 576 | void (boost::system::error_code, std::size_t)>( |
1e59de90 | 577 | detail::initiate_async_read_buffer_sequence<AsyncReadStream>(s), token, |
92f5a8d4 | 578 | buffers, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); |
b32b8144 FG |
579 | } |
580 | ||
581 | template <typename AsyncReadStream, typename MutableBufferSequence, | |
92f5a8d4 | 582 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, |
1e59de90 TL |
583 | std::size_t)) ReadToken> |
584 | inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken, | |
b32b8144 FG |
585 | void (boost::system::error_code, std::size_t)) |
586 | async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, | |
1e59de90 TL |
587 | BOOST_ASIO_MOVE_ARG(ReadToken) token, |
588 | typename constraint< | |
b32b8144 | 589 | is_mutable_buffer_sequence<MutableBufferSequence>::value |
1e59de90 | 590 | >::type) |
b32b8144 | 591 | { |
1e59de90 | 592 | return async_initiate<ReadToken, |
92f5a8d4 TL |
593 | void (boost::system::error_code, std::size_t)>( |
594 | detail::initiate_async_read_buffer_sequence<AsyncReadStream>(s), | |
1e59de90 | 595 | token, buffers, transfer_all()); |
b32b8144 FG |
596 | } |
597 | ||
92f5a8d4 TL |
598 | #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) |
599 | ||
b32b8144 FG |
600 | namespace detail |
601 | { | |
92f5a8d4 | 602 | template <typename AsyncReadStream, typename DynamicBuffer_v1, |
b32b8144 | 603 | typename CompletionCondition, typename ReadHandler> |
92f5a8d4 | 604 | class read_dynbuf_v1_op |
1e59de90 TL |
605 | : public base_from_cancellation_state<ReadHandler>, |
606 | base_from_completion_cond<CompletionCondition> | |
b32b8144 FG |
607 | { |
608 | public: | |
609 | template <typename BufferSequence> | |
92f5a8d4 | 610 | read_dynbuf_v1_op(AsyncReadStream& stream, |
b32b8144 | 611 | BOOST_ASIO_MOVE_ARG(BufferSequence) buffers, |
92f5a8d4 | 612 | CompletionCondition& completion_condition, ReadHandler& handler) |
1e59de90 TL |
613 | : base_from_cancellation_state<ReadHandler>( |
614 | handler, enable_partial_cancellation()), | |
615 | base_from_completion_cond<CompletionCondition>(completion_condition), | |
b32b8144 FG |
616 | stream_(stream), |
617 | buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)), | |
618 | start_(0), | |
619 | total_transferred_(0), | |
620 | handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) | |
621 | { | |
622 | } | |
623 | ||
624 | #if defined(BOOST_ASIO_HAS_MOVE) | |
92f5a8d4 | 625 | read_dynbuf_v1_op(const read_dynbuf_v1_op& other) |
1e59de90 TL |
626 | : base_from_cancellation_state<ReadHandler>(other), |
627 | base_from_completion_cond<CompletionCondition>(other), | |
b32b8144 FG |
628 | stream_(other.stream_), |
629 | buffers_(other.buffers_), | |
630 | start_(other.start_), | |
631 | total_transferred_(other.total_transferred_), | |
632 | handler_(other.handler_) | |
633 | { | |
634 | } | |
635 | ||
92f5a8d4 | 636 | read_dynbuf_v1_op(read_dynbuf_v1_op&& other) |
1e59de90 TL |
637 | : base_from_cancellation_state<ReadHandler>( |
638 | BOOST_ASIO_MOVE_CAST(base_from_cancellation_state< | |
639 | ReadHandler>)(other)), | |
640 | base_from_completion_cond<CompletionCondition>( | |
641 | BOOST_ASIO_MOVE_CAST(base_from_completion_cond< | |
92f5a8d4 | 642 | CompletionCondition>)(other)), |
b32b8144 | 643 | stream_(other.stream_), |
92f5a8d4 | 644 | buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)), |
b32b8144 FG |
645 | start_(other.start_), |
646 | total_transferred_(other.total_transferred_), | |
647 | handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) | |
648 | { | |
649 | } | |
650 | #endif // defined(BOOST_ASIO_HAS_MOVE) | |
651 | ||
1e59de90 | 652 | void operator()(boost::system::error_code ec, |
b32b8144 FG |
653 | std::size_t bytes_transferred, int start = 0) |
654 | { | |
655 | std::size_t max_size, bytes_available; | |
656 | switch (start_ = start) | |
657 | { | |
658 | case 1: | |
659 | max_size = this->check_for_completion(ec, total_transferred_); | |
660 | bytes_available = std::min<std::size_t>( | |
661 | std::max<std::size_t>(512, | |
662 | buffers_.capacity() - buffers_.size()), | |
663 | std::min<std::size_t>(max_size, | |
664 | buffers_.max_size() - buffers_.size())); | |
665 | for (;;) | |
666 | { | |
20effc67 TL |
667 | { |
668 | BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read")); | |
669 | stream_.async_read_some(buffers_.prepare(bytes_available), | |
670 | BOOST_ASIO_MOVE_CAST(read_dynbuf_v1_op)(*this)); | |
671 | } | |
b32b8144 FG |
672 | return; default: |
673 | total_transferred_ += bytes_transferred; | |
674 | buffers_.commit(bytes_transferred); | |
675 | max_size = this->check_for_completion(ec, total_transferred_); | |
676 | bytes_available = std::min<std::size_t>( | |
677 | std::max<std::size_t>(512, | |
678 | buffers_.capacity() - buffers_.size()), | |
679 | std::min<std::size_t>(max_size, | |
680 | buffers_.max_size() - buffers_.size())); | |
681 | if ((!ec && bytes_transferred == 0) || bytes_available == 0) | |
682 | break; | |
1e59de90 TL |
683 | if (this->cancelled() != cancellation_type::none) |
684 | { | |
685 | ec = error::operation_aborted; | |
686 | break; | |
687 | } | |
b32b8144 FG |
688 | } |
689 | ||
1e59de90 TL |
690 | BOOST_ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)( |
691 | static_cast<const boost::system::error_code&>(ec), | |
692 | static_cast<const std::size_t&>(total_transferred_)); | |
b32b8144 FG |
693 | } |
694 | } | |
695 | ||
696 | //private: | |
697 | AsyncReadStream& stream_; | |
92f5a8d4 | 698 | DynamicBuffer_v1 buffers_; |
b32b8144 FG |
699 | int start_; |
700 | std::size_t total_transferred_; | |
701 | ReadHandler handler_; | |
702 | }; | |
703 | ||
92f5a8d4 | 704 | template <typename AsyncReadStream, typename DynamicBuffer_v1, |
b32b8144 | 705 | typename CompletionCondition, typename ReadHandler> |
20effc67 TL |
706 | inline asio_handler_allocate_is_deprecated |
707 | asio_handler_allocate(std::size_t size, | |
92f5a8d4 | 708 | read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1, |
b32b8144 FG |
709 | CompletionCondition, ReadHandler>* this_handler) |
710 | { | |
20effc67 TL |
711 | #if defined(BOOST_ASIO_NO_DEPRECATED) |
712 | boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_); | |
713 | return asio_handler_allocate_is_no_longer_used(); | |
714 | #else // defined(BOOST_ASIO_NO_DEPRECATED) | |
b32b8144 FG |
715 | return boost_asio_handler_alloc_helpers::allocate( |
716 | size, this_handler->handler_); | |
20effc67 | 717 | #endif // defined(BOOST_ASIO_NO_DEPRECATED) |
b32b8144 FG |
718 | } |
719 | ||
92f5a8d4 | 720 | template <typename AsyncReadStream, typename DynamicBuffer_v1, |
b32b8144 | 721 | typename CompletionCondition, typename ReadHandler> |
20effc67 TL |
722 | inline asio_handler_deallocate_is_deprecated |
723 | asio_handler_deallocate(void* pointer, std::size_t size, | |
92f5a8d4 | 724 | read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1, |
b32b8144 FG |
725 | CompletionCondition, ReadHandler>* this_handler) |
726 | { | |
727 | boost_asio_handler_alloc_helpers::deallocate( | |
728 | pointer, size, this_handler->handler_); | |
20effc67 TL |
729 | #if defined(BOOST_ASIO_NO_DEPRECATED) |
730 | return asio_handler_deallocate_is_no_longer_used(); | |
731 | #endif // defined(BOOST_ASIO_NO_DEPRECATED) | |
b32b8144 FG |
732 | } |
733 | ||
92f5a8d4 | 734 | template <typename AsyncReadStream, typename DynamicBuffer_v1, |
b32b8144 FG |
735 | typename CompletionCondition, typename ReadHandler> |
736 | inline bool asio_handler_is_continuation( | |
92f5a8d4 | 737 | read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1, |
b32b8144 FG |
738 | CompletionCondition, ReadHandler>* this_handler) |
739 | { | |
740 | return this_handler->start_ == 0 ? true | |
741 | : boost_asio_handler_cont_helpers::is_continuation( | |
742 | this_handler->handler_); | |
743 | } | |
744 | ||
745 | template <typename Function, typename AsyncReadStream, | |
92f5a8d4 | 746 | typename DynamicBuffer_v1, typename CompletionCondition, |
b32b8144 | 747 | typename ReadHandler> |
20effc67 TL |
748 | inline asio_handler_invoke_is_deprecated |
749 | asio_handler_invoke(Function& function, | |
92f5a8d4 | 750 | read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1, |
b32b8144 FG |
751 | CompletionCondition, ReadHandler>* this_handler) |
752 | { | |
753 | boost_asio_handler_invoke_helpers::invoke( | |
754 | function, this_handler->handler_); | |
20effc67 TL |
755 | #if defined(BOOST_ASIO_NO_DEPRECATED) |
756 | return asio_handler_invoke_is_no_longer_used(); | |
757 | #endif // defined(BOOST_ASIO_NO_DEPRECATED) | |
b32b8144 FG |
758 | } |
759 | ||
760 | template <typename Function, typename AsyncReadStream, | |
92f5a8d4 | 761 | typename DynamicBuffer_v1, typename CompletionCondition, |
b32b8144 | 762 | typename ReadHandler> |
20effc67 TL |
763 | inline asio_handler_invoke_is_deprecated |
764 | asio_handler_invoke(const Function& function, | |
92f5a8d4 | 765 | read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1, |
b32b8144 FG |
766 | CompletionCondition, ReadHandler>* this_handler) |
767 | { | |
768 | boost_asio_handler_invoke_helpers::invoke( | |
769 | function, this_handler->handler_); | |
20effc67 TL |
770 | #if defined(BOOST_ASIO_NO_DEPRECATED) |
771 | return asio_handler_invoke_is_no_longer_used(); | |
772 | #endif // defined(BOOST_ASIO_NO_DEPRECATED) | |
b32b8144 | 773 | } |
92f5a8d4 TL |
774 | |
775 | template <typename AsyncReadStream> | |
776 | class initiate_async_read_dynbuf_v1 | |
777 | { | |
778 | public: | |
779 | typedef typename AsyncReadStream::executor_type executor_type; | |
780 | ||
781 | explicit initiate_async_read_dynbuf_v1(AsyncReadStream& stream) | |
782 | : stream_(stream) | |
783 | { | |
784 | } | |
785 | ||
786 | executor_type get_executor() const BOOST_ASIO_NOEXCEPT | |
787 | { | |
788 | return stream_.get_executor(); | |
789 | } | |
790 | ||
791 | template <typename ReadHandler, typename DynamicBuffer_v1, | |
792 | typename CompletionCondition> | |
793 | void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, | |
794 | BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, | |
795 | BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const | |
796 | { | |
797 | // If you get an error on the following line it means that your handler | |
798 | // does not meet the documented type requirements for a ReadHandler. | |
799 | BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; | |
800 | ||
801 | non_const_lvalue<ReadHandler> handler2(handler); | |
802 | non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); | |
803 | read_dynbuf_v1_op<AsyncReadStream, typename decay<DynamicBuffer_v1>::type, | |
804 | CompletionCondition, typename decay<ReadHandler>::type>( | |
805 | stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), | |
806 | completion_cond2.value, handler2.value)( | |
807 | boost::system::error_code(), 0, 1); | |
808 | } | |
809 | ||
810 | private: | |
811 | AsyncReadStream& stream_; | |
812 | }; | |
b32b8144 FG |
813 | } // namespace detail |
814 | ||
815 | #if !defined(GENERATING_DOCUMENTATION) | |
816 | ||
1e59de90 TL |
817 | template <template <typename, typename> class Associator, |
818 | typename AsyncReadStream, typename DynamicBuffer_v1, | |
819 | typename CompletionCondition, typename ReadHandler, | |
820 | typename DefaultCandidate> | |
821 | struct associator<Associator, | |
92f5a8d4 TL |
822 | detail::read_dynbuf_v1_op<AsyncReadStream, |
823 | DynamicBuffer_v1, CompletionCondition, ReadHandler>, | |
1e59de90 TL |
824 | DefaultCandidate> |
825 | : Associator<ReadHandler, DefaultCandidate> | |
b32b8144 | 826 | { |
1e59de90 | 827 | static typename Associator<ReadHandler, DefaultCandidate>::type get( |
92f5a8d4 TL |
828 | const detail::read_dynbuf_v1_op<AsyncReadStream, |
829 | DynamicBuffer_v1, CompletionCondition, ReadHandler>& h, | |
1e59de90 | 830 | const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT |
b32b8144 | 831 | { |
1e59de90 | 832 | return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); |
b32b8144 FG |
833 | } |
834 | }; | |
835 | ||
836 | #endif // !defined(GENERATING_DOCUMENTATION) | |
837 | ||
92f5a8d4 TL |
838 | template <typename AsyncReadStream, typename DynamicBuffer_v1, |
839 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
1e59de90 TL |
840 | std::size_t)) ReadToken> |
841 | inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken, | |
b32b8144 FG |
842 | void (boost::system::error_code, std::size_t)) |
843 | async_read(AsyncReadStream& s, | |
92f5a8d4 | 844 | BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, |
1e59de90 TL |
845 | BOOST_ASIO_MOVE_ARG(ReadToken) token, |
846 | typename constraint< | |
92f5a8d4 | 847 | is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value |
1e59de90 TL |
848 | >::type, |
849 | typename constraint< | |
850 | !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value | |
851 | >::type) | |
b32b8144 FG |
852 | { |
853 | return async_read(s, | |
92f5a8d4 | 854 | BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), |
1e59de90 | 855 | transfer_all(), BOOST_ASIO_MOVE_CAST(ReadToken)(token)); |
b32b8144 FG |
856 | } |
857 | ||
92f5a8d4 TL |
858 | template <typename AsyncReadStream, |
859 | typename DynamicBuffer_v1, typename CompletionCondition, | |
860 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
1e59de90 TL |
861 | std::size_t)) ReadToken> |
862 | inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken, | |
b32b8144 FG |
863 | void (boost::system::error_code, std::size_t)) |
864 | async_read(AsyncReadStream& s, | |
92f5a8d4 | 865 | BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, |
b32b8144 | 866 | CompletionCondition completion_condition, |
1e59de90 TL |
867 | BOOST_ASIO_MOVE_ARG(ReadToken) token, |
868 | typename constraint< | |
92f5a8d4 | 869 | is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value |
1e59de90 TL |
870 | >::type, |
871 | typename constraint< | |
872 | !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value | |
873 | >::type) | |
b32b8144 | 874 | { |
1e59de90 | 875 | return async_initiate<ReadToken, |
92f5a8d4 TL |
876 | void (boost::system::error_code, std::size_t)>( |
877 | detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s), | |
1e59de90 | 878 | token, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), |
92f5a8d4 | 879 | BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); |
b32b8144 FG |
880 | } |
881 | ||
882 | #if !defined(BOOST_ASIO_NO_EXTENSIONS) | |
883 | #if !defined(BOOST_ASIO_NO_IOSTREAM) | |
884 | ||
92f5a8d4 TL |
885 | template <typename AsyncReadStream, typename Allocator, |
886 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
1e59de90 TL |
887 | std::size_t)) ReadToken> |
888 | inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken, | |
b32b8144 FG |
889 | void (boost::system::error_code, std::size_t)) |
890 | async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b, | |
1e59de90 | 891 | BOOST_ASIO_MOVE_ARG(ReadToken) token) |
b32b8144 FG |
892 | { |
893 | return async_read(s, basic_streambuf_ref<Allocator>(b), | |
1e59de90 | 894 | BOOST_ASIO_MOVE_CAST(ReadToken)(token)); |
b32b8144 FG |
895 | } |
896 | ||
92f5a8d4 TL |
897 | template <typename AsyncReadStream, |
898 | typename Allocator, typename CompletionCondition, | |
899 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
1e59de90 TL |
900 | std::size_t)) ReadToken> |
901 | inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken, | |
b32b8144 FG |
902 | void (boost::system::error_code, std::size_t)) |
903 | async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b, | |
904 | CompletionCondition completion_condition, | |
1e59de90 | 905 | BOOST_ASIO_MOVE_ARG(ReadToken) token) |
b32b8144 FG |
906 | { |
907 | return async_read(s, basic_streambuf_ref<Allocator>(b), | |
92f5a8d4 | 908 | BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), |
1e59de90 | 909 | BOOST_ASIO_MOVE_CAST(ReadToken)(token)); |
b32b8144 FG |
910 | } |
911 | ||
912 | #endif // !defined(BOOST_ASIO_NO_IOSTREAM) | |
913 | #endif // !defined(BOOST_ASIO_NO_EXTENSIONS) | |
92f5a8d4 TL |
914 | #endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1) |
915 | ||
916 | namespace detail | |
917 | { | |
918 | template <typename AsyncReadStream, typename DynamicBuffer_v2, | |
919 | typename CompletionCondition, typename ReadHandler> | |
920 | class read_dynbuf_v2_op | |
1e59de90 TL |
921 | : public base_from_cancellation_state<ReadHandler>, |
922 | base_from_completion_cond<CompletionCondition> | |
92f5a8d4 TL |
923 | { |
924 | public: | |
925 | template <typename BufferSequence> | |
926 | read_dynbuf_v2_op(AsyncReadStream& stream, | |
927 | BOOST_ASIO_MOVE_ARG(BufferSequence) buffers, | |
928 | CompletionCondition& completion_condition, ReadHandler& handler) | |
1e59de90 TL |
929 | : base_from_cancellation_state<ReadHandler>( |
930 | handler, enable_partial_cancellation()), | |
931 | base_from_completion_cond<CompletionCondition>(completion_condition), | |
92f5a8d4 TL |
932 | stream_(stream), |
933 | buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)), | |
934 | start_(0), | |
935 | total_transferred_(0), | |
936 | bytes_available_(0), | |
937 | handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) | |
938 | { | |
939 | } | |
940 | ||
941 | #if defined(BOOST_ASIO_HAS_MOVE) | |
942 | read_dynbuf_v2_op(const read_dynbuf_v2_op& other) | |
1e59de90 TL |
943 | : base_from_cancellation_state<ReadHandler>(other), |
944 | base_from_completion_cond<CompletionCondition>(other), | |
92f5a8d4 TL |
945 | stream_(other.stream_), |
946 | buffers_(other.buffers_), | |
947 | start_(other.start_), | |
948 | total_transferred_(other.total_transferred_), | |
949 | bytes_available_(other.bytes_available_), | |
950 | handler_(other.handler_) | |
951 | { | |
952 | } | |
953 | ||
954 | read_dynbuf_v2_op(read_dynbuf_v2_op&& other) | |
1e59de90 TL |
955 | : base_from_cancellation_state<ReadHandler>( |
956 | BOOST_ASIO_MOVE_CAST(base_from_cancellation_state< | |
957 | ReadHandler>)(other)), | |
958 | base_from_completion_cond<CompletionCondition>( | |
959 | BOOST_ASIO_MOVE_CAST(base_from_completion_cond< | |
92f5a8d4 TL |
960 | CompletionCondition>)(other)), |
961 | stream_(other.stream_), | |
962 | buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)), | |
963 | start_(other.start_), | |
964 | total_transferred_(other.total_transferred_), | |
965 | bytes_available_(other.bytes_available_), | |
966 | handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_)) | |
967 | { | |
968 | } | |
969 | #endif // defined(BOOST_ASIO_HAS_MOVE) | |
970 | ||
1e59de90 | 971 | void operator()(boost::system::error_code ec, |
92f5a8d4 TL |
972 | std::size_t bytes_transferred, int start = 0) |
973 | { | |
974 | std::size_t max_size, pos; | |
975 | switch (start_ = start) | |
976 | { | |
977 | case 1: | |
978 | max_size = this->check_for_completion(ec, total_transferred_); | |
979 | bytes_available_ = std::min<std::size_t>( | |
980 | std::max<std::size_t>(512, | |
981 | buffers_.capacity() - buffers_.size()), | |
982 | std::min<std::size_t>(max_size, | |
983 | buffers_.max_size() - buffers_.size())); | |
984 | for (;;) | |
985 | { | |
986 | pos = buffers_.size(); | |
987 | buffers_.grow(bytes_available_); | |
20effc67 TL |
988 | { |
989 | BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read")); | |
990 | stream_.async_read_some(buffers_.data(pos, bytes_available_), | |
991 | BOOST_ASIO_MOVE_CAST(read_dynbuf_v2_op)(*this)); | |
992 | } | |
92f5a8d4 TL |
993 | return; default: |
994 | total_transferred_ += bytes_transferred; | |
995 | buffers_.shrink(bytes_available_ - bytes_transferred); | |
996 | max_size = this->check_for_completion(ec, total_transferred_); | |
997 | bytes_available_ = std::min<std::size_t>( | |
998 | std::max<std::size_t>(512, | |
999 | buffers_.capacity() - buffers_.size()), | |
1000 | std::min<std::size_t>(max_size, | |
1001 | buffers_.max_size() - buffers_.size())); | |
1002 | if ((!ec && bytes_transferred == 0) || bytes_available_ == 0) | |
1003 | break; | |
1e59de90 TL |
1004 | if (this->cancelled() != cancellation_type::none) |
1005 | { | |
1006 | ec = error::operation_aborted; | |
1007 | break; | |
1008 | } | |
92f5a8d4 TL |
1009 | } |
1010 | ||
1e59de90 TL |
1011 | BOOST_ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)( |
1012 | static_cast<const boost::system::error_code&>(ec), | |
1013 | static_cast<const std::size_t&>(total_transferred_)); | |
92f5a8d4 TL |
1014 | } |
1015 | } | |
1016 | ||
1017 | //private: | |
1018 | AsyncReadStream& stream_; | |
1019 | DynamicBuffer_v2 buffers_; | |
1020 | int start_; | |
1021 | std::size_t total_transferred_; | |
1022 | std::size_t bytes_available_; | |
1023 | ReadHandler handler_; | |
1024 | }; | |
1025 | ||
1026 | template <typename AsyncReadStream, typename DynamicBuffer_v2, | |
1027 | typename CompletionCondition, typename ReadHandler> | |
20effc67 TL |
1028 | inline asio_handler_allocate_is_deprecated |
1029 | asio_handler_allocate(std::size_t size, | |
92f5a8d4 TL |
1030 | read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2, |
1031 | CompletionCondition, ReadHandler>* this_handler) | |
1032 | { | |
20effc67 TL |
1033 | #if defined(BOOST_ASIO_NO_DEPRECATED) |
1034 | boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_); | |
1035 | return asio_handler_allocate_is_no_longer_used(); | |
1036 | #else // defined(BOOST_ASIO_NO_DEPRECATED) | |
92f5a8d4 TL |
1037 | return boost_asio_handler_alloc_helpers::allocate( |
1038 | size, this_handler->handler_); | |
20effc67 | 1039 | #endif // defined(BOOST_ASIO_NO_DEPRECATED) |
92f5a8d4 TL |
1040 | } |
1041 | ||
1042 | template <typename AsyncReadStream, typename DynamicBuffer_v2, | |
1043 | typename CompletionCondition, typename ReadHandler> | |
20effc67 TL |
1044 | inline asio_handler_deallocate_is_deprecated |
1045 | asio_handler_deallocate(void* pointer, std::size_t size, | |
92f5a8d4 TL |
1046 | read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2, |
1047 | CompletionCondition, ReadHandler>* this_handler) | |
1048 | { | |
1049 | boost_asio_handler_alloc_helpers::deallocate( | |
1050 | pointer, size, this_handler->handler_); | |
20effc67 TL |
1051 | #if defined(BOOST_ASIO_NO_DEPRECATED) |
1052 | return asio_handler_deallocate_is_no_longer_used(); | |
1053 | #endif // defined(BOOST_ASIO_NO_DEPRECATED) | |
92f5a8d4 TL |
1054 | } |
1055 | ||
1056 | template <typename AsyncReadStream, typename DynamicBuffer_v2, | |
1057 | typename CompletionCondition, typename ReadHandler> | |
1058 | inline bool asio_handler_is_continuation( | |
1059 | read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2, | |
1060 | CompletionCondition, ReadHandler>* this_handler) | |
1061 | { | |
1062 | return this_handler->start_ == 0 ? true | |
1063 | : boost_asio_handler_cont_helpers::is_continuation( | |
1064 | this_handler->handler_); | |
1065 | } | |
1066 | ||
1067 | template <typename Function, typename AsyncReadStream, | |
1068 | typename DynamicBuffer_v2, typename CompletionCondition, | |
1069 | typename ReadHandler> | |
20effc67 TL |
1070 | inline asio_handler_invoke_is_deprecated |
1071 | asio_handler_invoke(Function& function, | |
92f5a8d4 TL |
1072 | read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2, |
1073 | CompletionCondition, ReadHandler>* this_handler) | |
1074 | { | |
1075 | boost_asio_handler_invoke_helpers::invoke( | |
1076 | function, this_handler->handler_); | |
20effc67 TL |
1077 | #if defined(BOOST_ASIO_NO_DEPRECATED) |
1078 | return asio_handler_invoke_is_no_longer_used(); | |
1079 | #endif // defined(BOOST_ASIO_NO_DEPRECATED) | |
92f5a8d4 TL |
1080 | } |
1081 | ||
1082 | template <typename Function, typename AsyncReadStream, | |
1083 | typename DynamicBuffer_v2, typename CompletionCondition, | |
1084 | typename ReadHandler> | |
20effc67 TL |
1085 | inline asio_handler_invoke_is_deprecated |
1086 | asio_handler_invoke(const Function& function, | |
92f5a8d4 TL |
1087 | read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2, |
1088 | CompletionCondition, ReadHandler>* this_handler) | |
1089 | { | |
1090 | boost_asio_handler_invoke_helpers::invoke( | |
1091 | function, this_handler->handler_); | |
20effc67 TL |
1092 | #if defined(BOOST_ASIO_NO_DEPRECATED) |
1093 | return asio_handler_invoke_is_no_longer_used(); | |
1094 | #endif // defined(BOOST_ASIO_NO_DEPRECATED) | |
92f5a8d4 TL |
1095 | } |
1096 | ||
1097 | template <typename AsyncReadStream> | |
1098 | class initiate_async_read_dynbuf_v2 | |
1099 | { | |
1100 | public: | |
1101 | typedef typename AsyncReadStream::executor_type executor_type; | |
1102 | ||
1103 | explicit initiate_async_read_dynbuf_v2(AsyncReadStream& stream) | |
1104 | : stream_(stream) | |
1105 | { | |
1106 | } | |
1107 | ||
1108 | executor_type get_executor() const BOOST_ASIO_NOEXCEPT | |
1109 | { | |
1110 | return stream_.get_executor(); | |
1111 | } | |
1112 | ||
1113 | template <typename ReadHandler, typename DynamicBuffer_v2, | |
1114 | typename CompletionCondition> | |
1115 | void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, | |
1116 | BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, | |
1117 | BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const | |
1118 | { | |
1119 | // If you get an error on the following line it means that your handler | |
1120 | // does not meet the documented type requirements for a ReadHandler. | |
1121 | BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; | |
1122 | ||
1123 | non_const_lvalue<ReadHandler> handler2(handler); | |
1124 | non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); | |
1125 | read_dynbuf_v2_op<AsyncReadStream, typename decay<DynamicBuffer_v2>::type, | |
1126 | CompletionCondition, typename decay<ReadHandler>::type>( | |
1127 | stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), | |
1128 | completion_cond2.value, handler2.value)( | |
1129 | boost::system::error_code(), 0, 1); | |
1130 | } | |
1131 | ||
1132 | private: | |
1133 | AsyncReadStream& stream_; | |
1134 | }; | |
1135 | } // namespace detail | |
1136 | ||
1137 | #if !defined(GENERATING_DOCUMENTATION) | |
1138 | ||
1e59de90 TL |
1139 | template <template <typename, typename> class Associator, |
1140 | typename AsyncReadStream, typename DynamicBuffer_v2, | |
1141 | typename CompletionCondition, typename ReadHandler, | |
1142 | typename DefaultCandidate> | |
1143 | struct associator<Associator, | |
92f5a8d4 TL |
1144 | detail::read_dynbuf_v2_op<AsyncReadStream, |
1145 | DynamicBuffer_v2, CompletionCondition, ReadHandler>, | |
1e59de90 TL |
1146 | DefaultCandidate> |
1147 | : Associator<ReadHandler, DefaultCandidate> | |
92f5a8d4 | 1148 | { |
1e59de90 | 1149 | static typename Associator<ReadHandler, DefaultCandidate>::type get( |
92f5a8d4 TL |
1150 | const detail::read_dynbuf_v2_op<AsyncReadStream, |
1151 | DynamicBuffer_v2, CompletionCondition, ReadHandler>& h, | |
1e59de90 | 1152 | const DefaultCandidate& c = DefaultCandidate()) BOOST_ASIO_NOEXCEPT |
92f5a8d4 | 1153 | { |
1e59de90 | 1154 | return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); |
92f5a8d4 TL |
1155 | } |
1156 | }; | |
1157 | ||
1158 | #endif // !defined(GENERATING_DOCUMENTATION) | |
1159 | ||
1160 | template <typename AsyncReadStream, typename DynamicBuffer_v2, | |
1161 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
1e59de90 TL |
1162 | std::size_t)) ReadToken> |
1163 | inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken, | |
92f5a8d4 TL |
1164 | void (boost::system::error_code, std::size_t)) |
1165 | async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers, | |
1e59de90 TL |
1166 | BOOST_ASIO_MOVE_ARG(ReadToken) token, |
1167 | typename constraint< | |
92f5a8d4 | 1168 | is_dynamic_buffer_v2<DynamicBuffer_v2>::value |
1e59de90 | 1169 | >::type) |
92f5a8d4 TL |
1170 | { |
1171 | return async_read(s, | |
1172 | BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), | |
1e59de90 | 1173 | transfer_all(), BOOST_ASIO_MOVE_CAST(ReadToken)(token)); |
92f5a8d4 TL |
1174 | } |
1175 | ||
1176 | template <typename AsyncReadStream, | |
1177 | typename DynamicBuffer_v2, typename CompletionCondition, | |
1178 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
1e59de90 TL |
1179 | std::size_t)) ReadToken> |
1180 | inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken, | |
92f5a8d4 TL |
1181 | void (boost::system::error_code, std::size_t)) |
1182 | async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers, | |
1183 | CompletionCondition completion_condition, | |
1e59de90 TL |
1184 | BOOST_ASIO_MOVE_ARG(ReadToken) token, |
1185 | typename constraint< | |
92f5a8d4 | 1186 | is_dynamic_buffer_v2<DynamicBuffer_v2>::value |
1e59de90 | 1187 | >::type) |
92f5a8d4 | 1188 | { |
1e59de90 | 1189 | return async_initiate<ReadToken, |
92f5a8d4 TL |
1190 | void (boost::system::error_code, std::size_t)>( |
1191 | detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s), | |
1e59de90 | 1192 | token, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), |
92f5a8d4 TL |
1193 | BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); |
1194 | } | |
b32b8144 FG |
1195 | |
1196 | } // namespace asio | |
1197 | } // namespace boost | |
1198 | ||
1199 | #include <boost/asio/detail/pop_options.hpp> | |
1200 | ||
1201 | #endif // BOOST_ASIO_IMPL_READ_HPP |