1//
2// read_until.cpp
3// ~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2024 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// Disable autolinking for unit tests.
12#if !defined(BOOST_ALL_NO_LIB)
13#define BOOST_ALL_NO_LIB 1
14#endif // !defined(BOOST_ALL_NO_LIB)
15
16// Test that header file is self-contained.
17#include <boost/asio/read_until.hpp>
18
19#include <cstring>
20#include <functional>
21#include "archetypes/async_result.hpp"
22#include <boost/asio/io_context.hpp>
23#include <boost/asio/post.hpp>
24#include <boost/asio/streambuf.hpp>
25#include "unit_test.hpp"
26
27class test_stream
28{
29public:
30 typedef boost::asio::io_context::executor_type executor_type;
31
32 test_stream(boost::asio::io_context& io_context)
33 : io_context_(io_context),
34 length_(0),
35 position_(0),
36 next_read_length_(0)
37 {
38 }
39
40 executor_type get_executor() noexcept
41 {
42 return io_context_.get_executor();
43 }
44
45 void reset(const void* data, size_t length)
46 {
47 using namespace std; // For memcpy.
48
49 BOOST_ASIO_CHECK(length <= max_length);
50
51 memcpy(dest: data_, src: data, n: length);
52 length_ = length;
53 position_ = 0;
54 next_read_length_ = length;
55 }
56
57 void next_read_length(size_t length)
58 {
59 next_read_length_ = length;
60 }
61
62 template <typename Mutable_Buffers>
63 size_t read_some(const Mutable_Buffers& buffers)
64 {
65 size_t n = boost::asio::buffer_copy(buffers,
66 boost::asio::buffer(data&: data_, max_size_in_bytes: length_) + position_,
67 next_read_length_);
68 position_ += n;
69 return n;
70 }
71
72 template <typename Mutable_Buffers>
73 size_t read_some(const Mutable_Buffers& buffers,
74 boost::system::error_code& ec)
75 {
76 ec = boost::system::error_code();
77 return read_some(buffers);
78 }
79
80 template <typename Mutable_Buffers, typename Handler>
81 void async_read_some(const Mutable_Buffers& buffers, Handler handler)
82 {
83 size_t bytes_transferred = read_some(buffers);
84 boost::asio::post(get_executor(),
85 boost::asio::detail::bind_handler(
86 static_cast<Handler&&>(handler),
87 boost::system::error_code(), bytes_transferred));
88 }
89
90private:
91 boost::asio::io_context& io_context_;
92 enum { max_length = 8192 };
93 char data_[max_length];
94 size_t length_;
95 size_t position_;
96 size_t next_read_length_;
97};
98
99static const char read_data[]
100 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
101
102void test_dynamic_string_read_until_char()
103{
104 boost::asio::io_context ioc;
105 test_stream s(ioc);
106 std::string data1, data2;
107 boost::asio::dynamic_string_buffer<char, std::string::traits_type,
108 std::string::allocator_type> sb1 = boost::asio::dynamic_buffer(data&: data1);
109 boost::asio::dynamic_string_buffer<char, std::string::traits_type,
110 std::string::allocator_type> sb2 = boost::asio::dynamic_buffer(data&: data2, max_size: 25);
111 boost::system::error_code ec;
112
113 s.reset(data: read_data, length: sizeof(read_data));
114 sb1.consume(n: sb1.size());
115 std::size_t length = boost::asio::read_until(s, buffers: sb1, delim: 'Z');
116 BOOST_ASIO_CHECK(length == 26);
117
118 s.reset(data: read_data, length: sizeof(read_data));
119 s.next_read_length(length: 1);
120 sb1.consume(n: sb1.size());
121 length = boost::asio::read_until(s, buffers: sb1, delim: 'Z');
122 BOOST_ASIO_CHECK(length == 26);
123
124 s.reset(data: read_data, length: sizeof(read_data));
125 s.next_read_length(length: 10);
126 sb1.consume(n: sb1.size());
127 length = boost::asio::read_until(s, buffers: sb1, delim: 'Z');
128 BOOST_ASIO_CHECK(length == 26);
129
130 s.reset(data: read_data, length: sizeof(read_data));
131 sb1.consume(n: sb1.size());
132 length = boost::asio::read_until(s, buffers: sb1, delim: 'Z', ec);
133 BOOST_ASIO_CHECK(!ec);
134 BOOST_ASIO_CHECK(length == 26);
135
136 s.reset(data: read_data, length: sizeof(read_data));
137 s.next_read_length(length: 1);
138 sb1.consume(n: sb1.size());
139 length = boost::asio::read_until(s, buffers: sb1, delim: 'Z', ec);
140 BOOST_ASIO_CHECK(!ec);
141 BOOST_ASIO_CHECK(length == 26);
142
143 s.reset(data: read_data, length: sizeof(read_data));
144 s.next_read_length(length: 10);
145 sb1.consume(n: sb1.size());
146 length = boost::asio::read_until(s, buffers: sb1, delim: 'Z', ec);
147 BOOST_ASIO_CHECK(!ec);
148 BOOST_ASIO_CHECK(length == 26);
149
150 s.reset(data: read_data, length: sizeof(read_data));
151 sb2.consume(n: sb2.size());
152 length = boost::asio::read_until(s, buffers: sb2, delim: 'Z', ec);
153 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
154 BOOST_ASIO_CHECK(length == 0);
155
156 s.reset(data: read_data, length: sizeof(read_data));
157 s.next_read_length(length: 1);
158 sb2.consume(n: sb2.size());
159 length = boost::asio::read_until(s, buffers: sb2, delim: 'Z', ec);
160 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
161 BOOST_ASIO_CHECK(length == 0);
162
163 s.reset(data: read_data, length: sizeof(read_data));
164 s.next_read_length(length: 10);
165 sb2.consume(n: sb2.size());
166 length = boost::asio::read_until(s, buffers: sb2, delim: 'Z', ec);
167 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
168 BOOST_ASIO_CHECK(length == 0);
169
170 s.reset(data: read_data, length: sizeof(read_data));
171 sb2.consume(n: sb2.size());
172 length = boost::asio::read_until(s, buffers: sb2, delim: 'Y', ec);
173 BOOST_ASIO_CHECK(!ec);
174 BOOST_ASIO_CHECK(length == 25);
175
176 s.reset(data: read_data, length: sizeof(read_data));
177 s.next_read_length(length: 1);
178 sb2.consume(n: sb2.size());
179 length = boost::asio::read_until(s, buffers: sb2, delim: 'Y', ec);
180 BOOST_ASIO_CHECK(!ec);
181 BOOST_ASIO_CHECK(length == 25);
182
183 s.reset(data: read_data, length: sizeof(read_data));
184 s.next_read_length(length: 10);
185 sb2.consume(n: sb2.size());
186 length = boost::asio::read_until(s, buffers: sb2, delim: 'Y', ec);
187 BOOST_ASIO_CHECK(!ec);
188 BOOST_ASIO_CHECK(length == 25);
189}
190
191void test_streambuf_read_until_char()
192{
193#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
194 boost::asio::io_context ioc;
195 test_stream s(ioc);
196 boost::asio::streambuf sb1;
197 boost::asio::streambuf sb2(25);
198 boost::system::error_code ec;
199
200 s.reset(data: read_data, length: sizeof(read_data));
201 sb1.consume(n: sb1.size());
202 std::size_t length = boost::asio::read_until(s, b&: sb1, delim: 'Z');
203 BOOST_ASIO_CHECK(length == 26);
204
205 s.reset(data: read_data, length: sizeof(read_data));
206 s.next_read_length(length: 1);
207 sb1.consume(n: sb1.size());
208 length = boost::asio::read_until(s, b&: sb1, delim: 'Z');
209 BOOST_ASIO_CHECK(length == 26);
210
211 s.reset(data: read_data, length: sizeof(read_data));
212 s.next_read_length(length: 10);
213 sb1.consume(n: sb1.size());
214 length = boost::asio::read_until(s, b&: sb1, delim: 'Z');
215 BOOST_ASIO_CHECK(length == 26);
216
217 s.reset(data: read_data, length: sizeof(read_data));
218 sb1.consume(n: sb1.size());
219 length = boost::asio::read_until(s, b&: sb1, delim: 'Z', ec);
220 BOOST_ASIO_CHECK(!ec);
221 BOOST_ASIO_CHECK(length == 26);
222
223 s.reset(data: read_data, length: sizeof(read_data));
224 s.next_read_length(length: 1);
225 sb1.consume(n: sb1.size());
226 length = boost::asio::read_until(s, b&: sb1, delim: 'Z', ec);
227 BOOST_ASIO_CHECK(!ec);
228 BOOST_ASIO_CHECK(length == 26);
229
230 s.reset(data: read_data, length: sizeof(read_data));
231 s.next_read_length(length: 10);
232 sb1.consume(n: sb1.size());
233 length = boost::asio::read_until(s, b&: sb1, delim: 'Z', ec);
234 BOOST_ASIO_CHECK(!ec);
235 BOOST_ASIO_CHECK(length == 26);
236
237 s.reset(data: read_data, length: sizeof(read_data));
238 sb2.consume(n: sb2.size());
239 length = boost::asio::read_until(s, b&: sb2, delim: 'Z', ec);
240 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
241 BOOST_ASIO_CHECK(length == 0);
242
243 s.reset(data: read_data, length: sizeof(read_data));
244 s.next_read_length(length: 1);
245 sb2.consume(n: sb2.size());
246 length = boost::asio::read_until(s, b&: sb2, delim: 'Z', ec);
247 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
248 BOOST_ASIO_CHECK(length == 0);
249
250 s.reset(data: read_data, length: sizeof(read_data));
251 s.next_read_length(length: 10);
252 sb2.consume(n: sb2.size());
253 length = boost::asio::read_until(s, b&: sb2, delim: 'Z', ec);
254 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
255 BOOST_ASIO_CHECK(length == 0);
256
257 s.reset(data: read_data, length: sizeof(read_data));
258 sb2.consume(n: sb2.size());
259 length = boost::asio::read_until(s, b&: sb2, delim: 'Y', ec);
260 BOOST_ASIO_CHECK(!ec);
261 BOOST_ASIO_CHECK(length == 25);
262
263 s.reset(data: read_data, length: sizeof(read_data));
264 s.next_read_length(length: 1);
265 sb2.consume(n: sb2.size());
266 length = boost::asio::read_until(s, b&: sb2, delim: 'Y', ec);
267 BOOST_ASIO_CHECK(!ec);
268 BOOST_ASIO_CHECK(length == 25);
269
270 s.reset(data: read_data, length: sizeof(read_data));
271 s.next_read_length(length: 10);
272 sb2.consume(n: sb2.size());
273 length = boost::asio::read_until(s, b&: sb2, delim: 'Y', ec);
274 BOOST_ASIO_CHECK(!ec);
275 BOOST_ASIO_CHECK(length == 25);
276#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
277}
278
279void test_dynamic_string_read_until_string()
280{
281 boost::asio::io_context ioc;
282 test_stream s(ioc);
283 std::string data1, data2;
284 boost::asio::dynamic_string_buffer<char, std::string::traits_type,
285 std::string::allocator_type> sb1 = boost::asio::dynamic_buffer(data&: data1);
286 boost::asio::dynamic_string_buffer<char, std::string::traits_type,
287 std::string::allocator_type> sb2 = boost::asio::dynamic_buffer(data&: data2, max_size: 25);
288 boost::system::error_code ec;
289
290 s.reset(data: read_data, length: sizeof(read_data));
291 sb1.consume(n: sb1.size());
292 std::size_t length = boost::asio::read_until(s, buffers: sb1, delim: "XYZ");
293 BOOST_ASIO_CHECK(length == 26);
294
295 s.reset(data: read_data, length: sizeof(read_data));
296 s.next_read_length(length: 1);
297 sb1.consume(n: sb1.size());
298 length = boost::asio::read_until(s, buffers: sb1, delim: "XYZ");
299 BOOST_ASIO_CHECK(length == 26);
300
301 s.reset(data: read_data, length: sizeof(read_data));
302 s.next_read_length(length: 10);
303 sb1.consume(n: sb1.size());
304 length = boost::asio::read_until(s, buffers: sb1, delim: "XYZ");
305 BOOST_ASIO_CHECK(length == 26);
306
307 s.reset(data: read_data, length: sizeof(read_data));
308 sb1.consume(n: sb1.size());
309 length = boost::asio::read_until(s, buffers: sb1, delim: "XYZ", ec);
310 BOOST_ASIO_CHECK(!ec);
311 BOOST_ASIO_CHECK(length == 26);
312
313 s.reset(data: read_data, length: sizeof(read_data));
314 s.next_read_length(length: 1);
315 sb1.consume(n: sb1.size());
316 length = boost::asio::read_until(s, buffers: sb1, delim: "XYZ", ec);
317 BOOST_ASIO_CHECK(!ec);
318 BOOST_ASIO_CHECK(length == 26);
319
320 s.reset(data: read_data, length: sizeof(read_data));
321 s.next_read_length(length: 10);
322 sb1.consume(n: sb1.size());
323 length = boost::asio::read_until(s, buffers: sb1, delim: "XYZ", ec);
324 BOOST_ASIO_CHECK(!ec);
325 BOOST_ASIO_CHECK(length == 26);
326
327 s.reset(data: read_data, length: sizeof(read_data));
328 sb2.consume(n: sb2.size());
329 length = boost::asio::read_until(s, buffers: sb2, delim: "XYZ", ec);
330 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
331 BOOST_ASIO_CHECK(length == 0);
332
333 s.reset(data: read_data, length: sizeof(read_data));
334 s.next_read_length(length: 1);
335 sb2.consume(n: sb2.size());
336 length = boost::asio::read_until(s, buffers: sb2, delim: "XYZ", ec);
337 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
338 BOOST_ASIO_CHECK(length == 0);
339
340 s.reset(data: read_data, length: sizeof(read_data));
341 s.next_read_length(length: 10);
342 sb2.consume(n: sb2.size());
343 length = boost::asio::read_until(s, buffers: sb2, delim: "XYZ", ec);
344 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
345 BOOST_ASIO_CHECK(length == 0);
346
347 s.reset(data: read_data, length: sizeof(read_data));
348 sb2.consume(n: sb2.size());
349 length = boost::asio::read_until(s, buffers: sb2, delim: "WXY", ec);
350 BOOST_ASIO_CHECK(!ec);
351 BOOST_ASIO_CHECK(length == 25);
352
353 s.reset(data: read_data, length: sizeof(read_data));
354 s.next_read_length(length: 1);
355 sb2.consume(n: sb2.size());
356 length = boost::asio::read_until(s, buffers: sb2, delim: "WXY", ec);
357 BOOST_ASIO_CHECK(!ec);
358 BOOST_ASIO_CHECK(length == 25);
359
360 s.reset(data: read_data, length: sizeof(read_data));
361 s.next_read_length(length: 10);
362 sb2.consume(n: sb2.size());
363 length = boost::asio::read_until(s, buffers: sb2, delim: "WXY", ec);
364 BOOST_ASIO_CHECK(!ec);
365 BOOST_ASIO_CHECK(length == 25);
366}
367
368void test_streambuf_read_until_string()
369{
370#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
371 boost::asio::io_context ioc;
372 test_stream s(ioc);
373 boost::asio::streambuf sb1;
374 boost::asio::streambuf sb2(25);
375 boost::system::error_code ec;
376
377 s.reset(data: read_data, length: sizeof(read_data));
378 sb1.consume(n: sb1.size());
379 std::size_t length = boost::asio::read_until(s, b&: sb1, delim: "XYZ");
380 BOOST_ASIO_CHECK(length == 26);
381
382 s.reset(data: read_data, length: sizeof(read_data));
383 s.next_read_length(length: 1);
384 sb1.consume(n: sb1.size());
385 length = boost::asio::read_until(s, b&: sb1, delim: "XYZ");
386 BOOST_ASIO_CHECK(length == 26);
387
388 s.reset(data: read_data, length: sizeof(read_data));
389 s.next_read_length(length: 10);
390 sb1.consume(n: sb1.size());
391 length = boost::asio::read_until(s, b&: sb1, delim: "XYZ");
392 BOOST_ASIO_CHECK(length == 26);
393
394 s.reset(data: read_data, length: sizeof(read_data));
395 sb1.consume(n: sb1.size());
396 length = boost::asio::read_until(s, b&: sb1, delim: "XYZ", ec);
397 BOOST_ASIO_CHECK(!ec);
398 BOOST_ASIO_CHECK(length == 26);
399
400 s.reset(data: read_data, length: sizeof(read_data));
401 s.next_read_length(length: 1);
402 sb1.consume(n: sb1.size());
403 length = boost::asio::read_until(s, b&: sb1, delim: "XYZ", ec);
404 BOOST_ASIO_CHECK(!ec);
405 BOOST_ASIO_CHECK(length == 26);
406
407 s.reset(data: read_data, length: sizeof(read_data));
408 s.next_read_length(length: 10);
409 sb1.consume(n: sb1.size());
410 length = boost::asio::read_until(s, b&: sb1, delim: "XYZ", ec);
411 BOOST_ASIO_CHECK(!ec);
412 BOOST_ASIO_CHECK(length == 26);
413
414 s.reset(data: read_data, length: sizeof(read_data));
415 sb2.consume(n: sb2.size());
416 length = boost::asio::read_until(s, b&: sb2, delim: "XYZ", ec);
417 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
418 BOOST_ASIO_CHECK(length == 0);
419
420 s.reset(data: read_data, length: sizeof(read_data));
421 s.next_read_length(length: 1);
422 sb2.consume(n: sb2.size());
423 length = boost::asio::read_until(s, b&: sb2, delim: "XYZ", ec);
424 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
425 BOOST_ASIO_CHECK(length == 0);
426
427 s.reset(data: read_data, length: sizeof(read_data));
428 s.next_read_length(length: 10);
429 sb2.consume(n: sb2.size());
430 length = boost::asio::read_until(s, b&: sb2, delim: "XYZ", ec);
431 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
432 BOOST_ASIO_CHECK(length == 0);
433
434 s.reset(data: read_data, length: sizeof(read_data));
435 sb2.consume(n: sb2.size());
436 length = boost::asio::read_until(s, b&: sb2, delim: "WXY", ec);
437 BOOST_ASIO_CHECK(!ec);
438 BOOST_ASIO_CHECK(length == 25);
439
440 s.reset(data: read_data, length: sizeof(read_data));
441 s.next_read_length(length: 1);
442 sb2.consume(n: sb2.size());
443 length = boost::asio::read_until(s, b&: sb2, delim: "WXY", ec);
444 BOOST_ASIO_CHECK(!ec);
445 BOOST_ASIO_CHECK(length == 25);
446
447 s.reset(data: read_data, length: sizeof(read_data));
448 s.next_read_length(length: 10);
449 sb2.consume(n: sb2.size());
450 length = boost::asio::read_until(s, b&: sb2, delim: "WXY", ec);
451 BOOST_ASIO_CHECK(!ec);
452 BOOST_ASIO_CHECK(length == 25);
453#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
454}
455
456class match_char
457{
458public:
459 explicit match_char(char c) : c_(c) {}
460
461 template <typename Iterator>
462 std::pair<Iterator, bool> operator()(
463 Iterator begin, Iterator end) const
464 {
465 Iterator i = begin;
466 while (i != end)
467 if (c_ == *i++)
468 return std::make_pair(i, true);
469 return std::make_pair(i, false);
470 }
471
472private:
473 char c_;
474};
475
476namespace boost {
477namespace asio {
478 template <> struct is_match_condition<match_char>
479 {
480 enum { value = true };
481 };
482} // namespace asio
483} // namespace boost
484
485void test_dynamic_string_read_until_match_condition()
486{
487 boost::asio::io_context ioc;
488 test_stream s(ioc);
489 std::string data1, data2;
490 boost::asio::dynamic_string_buffer<char, std::string::traits_type,
491 std::string::allocator_type> sb1 = boost::asio::dynamic_buffer(data&: data1);
492 boost::asio::dynamic_string_buffer<char, std::string::traits_type,
493 std::string::allocator_type> sb2 = boost::asio::dynamic_buffer(data&: data2, max_size: 25);
494 boost::system::error_code ec;
495
496 s.reset(data: read_data, length: sizeof(read_data));
497 sb1.consume(n: sb1.size());
498 std::size_t length = boost::asio::read_until(s, buffers: sb1, match_condition: match_char('Z'));
499 BOOST_ASIO_CHECK(length == 26);
500
501 s.reset(data: read_data, length: sizeof(read_data));
502 s.next_read_length(length: 1);
503 sb1.consume(n: sb1.size());
504 length = boost::asio::read_until(s, buffers: sb1, match_condition: match_char('Z'));
505 BOOST_ASIO_CHECK(length == 26);
506
507 s.reset(data: read_data, length: sizeof(read_data));
508 s.next_read_length(length: 10);
509 sb1.consume(n: sb1.size());
510 length = boost::asio::read_until(s, buffers: sb1, match_condition: match_char('Z'));
511 BOOST_ASIO_CHECK(length == 26);
512
513 s.reset(data: read_data, length: sizeof(read_data));
514 sb1.consume(n: sb1.size());
515 length = boost::asio::read_until(s, buffers: sb1, match_condition: match_char('Z'), ec);
516 BOOST_ASIO_CHECK(!ec);
517 BOOST_ASIO_CHECK(length == 26);
518
519 s.reset(data: read_data, length: sizeof(read_data));
520 s.next_read_length(length: 1);
521 sb1.consume(n: sb1.size());
522 length = boost::asio::read_until(s, buffers: sb1, match_condition: match_char('Z'), ec);
523 BOOST_ASIO_CHECK(!ec);
524 BOOST_ASIO_CHECK(length == 26);
525
526 s.reset(data: read_data, length: sizeof(read_data));
527 s.next_read_length(length: 10);
528 sb1.consume(n: sb1.size());
529 length = boost::asio::read_until(s, buffers: sb1, match_condition: match_char('Z'), ec);
530 BOOST_ASIO_CHECK(!ec);
531 BOOST_ASIO_CHECK(length == 26);
532
533 s.reset(data: read_data, length: sizeof(read_data));
534 sb2.consume(n: sb2.size());
535 length = boost::asio::read_until(s, buffers: sb2, match_condition: match_char('Z'), ec);
536 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
537 BOOST_ASIO_CHECK(length == 0);
538
539 s.reset(data: read_data, length: sizeof(read_data));
540 s.next_read_length(length: 1);
541 sb2.consume(n: sb2.size());
542 length = boost::asio::read_until(s, buffers: sb2, match_condition: match_char('Z'), ec);
543 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
544 BOOST_ASIO_CHECK(length == 0);
545
546 s.reset(data: read_data, length: sizeof(read_data));
547 s.next_read_length(length: 10);
548 sb2.consume(n: sb2.size());
549 length = boost::asio::read_until(s, buffers: sb2, match_condition: match_char('Z'), ec);
550 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
551 BOOST_ASIO_CHECK(length == 0);
552
553 s.reset(data: read_data, length: sizeof(read_data));
554 sb2.consume(n: sb2.size());
555 length = boost::asio::read_until(s, buffers: sb2, match_condition: match_char('Y'), ec);
556 BOOST_ASIO_CHECK(!ec);
557 BOOST_ASIO_CHECK(length == 25);
558
559 s.reset(data: read_data, length: sizeof(read_data));
560 s.next_read_length(length: 1);
561 sb2.consume(n: sb2.size());
562 length = boost::asio::read_until(s, buffers: sb2, match_condition: match_char('Y'), ec);
563 BOOST_ASIO_CHECK(!ec);
564 BOOST_ASIO_CHECK(length == 25);
565
566 s.reset(data: read_data, length: sizeof(read_data));
567 s.next_read_length(length: 10);
568 sb2.consume(n: sb2.size());
569 length = boost::asio::read_until(s, buffers: sb2, match_condition: match_char('Y'), ec);
570 BOOST_ASIO_CHECK(!ec);
571 BOOST_ASIO_CHECK(length == 25);
572}
573
574void test_streambuf_read_until_match_condition()
575{
576#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
577 boost::asio::io_context ioc;
578 test_stream s(ioc);
579 boost::asio::streambuf sb1;
580 boost::asio::streambuf sb2(25);
581 boost::system::error_code ec;
582
583 s.reset(data: read_data, length: sizeof(read_data));
584 sb1.consume(n: sb1.size());
585 std::size_t length = boost::asio::read_until(s, b&: sb1, match_condition: match_char('Z'));
586 BOOST_ASIO_CHECK(length == 26);
587
588 s.reset(data: read_data, length: sizeof(read_data));
589 s.next_read_length(length: 1);
590 sb1.consume(n: sb1.size());
591 length = boost::asio::read_until(s, b&: sb1, match_condition: match_char('Z'));
592 BOOST_ASIO_CHECK(length == 26);
593
594 s.reset(data: read_data, length: sizeof(read_data));
595 s.next_read_length(length: 10);
596 sb1.consume(n: sb1.size());
597 length = boost::asio::read_until(s, b&: sb1, match_condition: match_char('Z'));
598 BOOST_ASIO_CHECK(length == 26);
599
600 s.reset(data: read_data, length: sizeof(read_data));
601 sb1.consume(n: sb1.size());
602 length = boost::asio::read_until(s, b&: sb1, match_condition: match_char('Z'), ec);
603 BOOST_ASIO_CHECK(!ec);
604 BOOST_ASIO_CHECK(length == 26);
605
606 s.reset(data: read_data, length: sizeof(read_data));
607 s.next_read_length(length: 1);
608 sb1.consume(n: sb1.size());
609 length = boost::asio::read_until(s, b&: sb1, match_condition: match_char('Z'), ec);
610 BOOST_ASIO_CHECK(!ec);
611 BOOST_ASIO_CHECK(length == 26);
612
613 s.reset(data: read_data, length: sizeof(read_data));
614 s.next_read_length(length: 10);
615 sb1.consume(n: sb1.size());
616 length = boost::asio::read_until(s, b&: sb1, match_condition: match_char('Z'), ec);
617 BOOST_ASIO_CHECK(!ec);
618 BOOST_ASIO_CHECK(length == 26);
619
620 s.reset(data: read_data, length: sizeof(read_data));
621 sb2.consume(n: sb2.size());
622 length = boost::asio::read_until(s, b&: sb2, match_condition: match_char('Z'), ec);
623 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
624 BOOST_ASIO_CHECK(length == 0);
625
626 s.reset(data: read_data, length: sizeof(read_data));
627 s.next_read_length(length: 1);
628 sb2.consume(n: sb2.size());
629 length = boost::asio::read_until(s, b&: sb2, match_condition: match_char('Z'), ec);
630 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
631 BOOST_ASIO_CHECK(length == 0);
632
633 s.reset(data: read_data, length: sizeof(read_data));
634 s.next_read_length(length: 10);
635 sb2.consume(n: sb2.size());
636 length = boost::asio::read_until(s, b&: sb2, match_condition: match_char('Z'), ec);
637 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
638 BOOST_ASIO_CHECK(length == 0);
639
640 s.reset(data: read_data, length: sizeof(read_data));
641 sb2.consume(n: sb2.size());
642 length = boost::asio::read_until(s, b&: sb2, match_condition: match_char('Y'), ec);
643 BOOST_ASIO_CHECK(!ec);
644 BOOST_ASIO_CHECK(length == 25);
645
646 s.reset(data: read_data, length: sizeof(read_data));
647 s.next_read_length(length: 1);
648 sb2.consume(n: sb2.size());
649 length = boost::asio::read_until(s, b&: sb2, match_condition: match_char('Y'), ec);
650 BOOST_ASIO_CHECK(!ec);
651 BOOST_ASIO_CHECK(length == 25);
652
653 s.reset(data: read_data, length: sizeof(read_data));
654 s.next_read_length(length: 10);
655 sb2.consume(n: sb2.size());
656 length = boost::asio::read_until(s, b&: sb2, match_condition: match_char('Y'), ec);
657 BOOST_ASIO_CHECK(!ec);
658 BOOST_ASIO_CHECK(length == 25);
659#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
660}
661
662void async_read_handler(
663 const boost::system::error_code& err, boost::system::error_code* err_out,
664 std::size_t bytes_transferred, std::size_t* bytes_out, bool* called)
665{
666 *err_out = err;
667 *bytes_out = bytes_transferred;
668 *called = true;
669}
670
671void test_dynamic_string_async_read_until_char()
672{
673 namespace bindns = std;
674 using bindns::placeholders::_1;
675 using bindns::placeholders::_2;
676
677 boost::asio::io_context ioc;
678 test_stream s(ioc);
679 std::string data1, data2;
680 boost::asio::dynamic_string_buffer<char, std::string::traits_type,
681 std::string::allocator_type> sb1 = boost::asio::dynamic_buffer(data&: data1);
682 boost::asio::dynamic_string_buffer<char, std::string::traits_type,
683 std::string::allocator_type> sb2 = boost::asio::dynamic_buffer(data&: data2, max_size: 25);
684 boost::system::error_code ec;
685 std::size_t length;
686 bool called;
687
688 s.reset(data: read_data, length: sizeof(read_data));
689 ec = boost::system::error_code();
690 length = 0;
691 called = false;
692 sb1.consume(n: sb1.size());
693 boost::asio::async_read_until(s, buffers: sb1, delim: 'Z',
694 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
695 args: _2, args: &length, args: &called));
696 ioc.restart();
697 ioc.run();
698 BOOST_ASIO_CHECK(called);
699 BOOST_ASIO_CHECK(!ec);
700 BOOST_ASIO_CHECK(length == 26);
701
702 s.reset(data: read_data, length: sizeof(read_data));
703 s.next_read_length(length: 1);
704 ec = boost::system::error_code();
705 length = 0;
706 called = false;
707 sb1.consume(n: sb1.size());
708 boost::asio::async_read_until(s, buffers: sb1, delim: 'Z',
709 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
710 args: _2, args: &length, args: &called));
711 ioc.restart();
712 ioc.run();
713 BOOST_ASIO_CHECK(called);
714 BOOST_ASIO_CHECK(!ec);
715 BOOST_ASIO_CHECK(length == 26);
716
717 s.reset(data: read_data, length: sizeof(read_data));
718 s.next_read_length(length: 10);
719 ec = boost::system::error_code();
720 length = 0;
721 called = false;
722 sb1.consume(n: sb1.size());
723 boost::asio::async_read_until(s, buffers: sb1, delim: 'Z',
724 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
725 args: _2, args: &length, args: &called));
726 ioc.restart();
727 ioc.run();
728 BOOST_ASIO_CHECK(called);
729 BOOST_ASIO_CHECK(!ec);
730 BOOST_ASIO_CHECK(length == 26);
731
732 s.reset(data: read_data, length: sizeof(read_data));
733 ec = boost::system::error_code();
734 length = 0;
735 called = false;
736 sb2.consume(n: sb2.size());
737 boost::asio::async_read_until(s, buffers: sb2, delim: 'Z',
738 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
739 args: _2, args: &length, args: &called));
740 ioc.restart();
741 ioc.run();
742 BOOST_ASIO_CHECK(called);
743 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
744 BOOST_ASIO_CHECK(length == 0);
745
746 s.reset(data: read_data, length: sizeof(read_data));
747 s.next_read_length(length: 1);
748 ec = boost::system::error_code();
749 length = 0;
750 called = false;
751 sb2.consume(n: sb2.size());
752 boost::asio::async_read_until(s, buffers: sb2, delim: 'Z',
753 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
754 args: _2, args: &length, args: &called));
755 ioc.restart();
756 ioc.run();
757 BOOST_ASIO_CHECK(called);
758 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
759 BOOST_ASIO_CHECK(length == 0);
760
761 s.reset(data: read_data, length: sizeof(read_data));
762 s.next_read_length(length: 10);
763 ec = boost::system::error_code();
764 length = 0;
765 called = false;
766 sb2.consume(n: sb2.size());
767 boost::asio::async_read_until(s, buffers: sb2, delim: 'Z',
768 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
769 args: _2, args: &length, args: &called));
770 ioc.restart();
771 ioc.run();
772 BOOST_ASIO_CHECK(called);
773 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
774 BOOST_ASIO_CHECK(length == 0);
775
776 s.reset(data: read_data, length: sizeof(read_data));
777 ec = boost::system::error_code();
778 length = 0;
779 called = false;
780 sb2.consume(n: sb2.size());
781 boost::asio::async_read_until(s, buffers: sb2, delim: 'Y',
782 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
783 args: _2, args: &length, args: &called));
784 ioc.restart();
785 ioc.run();
786 BOOST_ASIO_CHECK(called);
787 BOOST_ASIO_CHECK(!ec);
788 BOOST_ASIO_CHECK(length == 25);
789
790 s.reset(data: read_data, length: sizeof(read_data));
791 s.next_read_length(length: 1);
792 ec = boost::system::error_code();
793 length = 0;
794 called = false;
795 sb2.consume(n: sb2.size());
796 boost::asio::async_read_until(s, buffers: sb2, delim: 'Y',
797 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
798 args: _2, args: &length, args: &called));
799 ioc.restart();
800 ioc.run();
801 BOOST_ASIO_CHECK(called);
802 BOOST_ASIO_CHECK(!ec);
803 BOOST_ASIO_CHECK(length == 25);
804
805 s.reset(data: read_data, length: sizeof(read_data));
806 s.next_read_length(length: 10);
807 ec = boost::system::error_code();
808 length = 0;
809 called = false;
810 sb2.consume(n: sb2.size());
811 boost::asio::async_read_until(s, buffers: sb2, delim: 'Y',
812 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
813 args: _2, args: &length, args: &called));
814 ioc.restart();
815 ioc.run();
816 BOOST_ASIO_CHECK(called);
817 BOOST_ASIO_CHECK(!ec);
818 BOOST_ASIO_CHECK(length == 25);
819
820 s.reset(data: read_data, length: sizeof(read_data));
821 sb2.consume(n: sb2.size());
822 int i = boost::asio::async_read_until(s, buffers: sb2, delim: 'Y',
823 token: archetypes::lazy_handler());
824 BOOST_ASIO_CHECK(i == 42);
825 ioc.restart();
826 ioc.run();
827}
828
829void test_streambuf_async_read_until_char()
830{
831#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
832 namespace bindns = std;
833 using bindns::placeholders::_1;
834 using bindns::placeholders::_2;
835
836 boost::asio::io_context ioc;
837 test_stream s(ioc);
838 boost::asio::streambuf sb1;
839 boost::asio::streambuf sb2(25);
840 boost::system::error_code ec;
841 std::size_t length;
842 bool called;
843
844 s.reset(data: read_data, length: sizeof(read_data));
845 ec = boost::system::error_code();
846 length = 0;
847 called = false;
848 sb1.consume(n: sb1.size());
849 boost::asio::async_read_until(s, b&: sb1, delim: 'Z',
850 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
851 args: _2, args: &length, args: &called));
852 ioc.restart();
853 ioc.run();
854 BOOST_ASIO_CHECK(called);
855 BOOST_ASIO_CHECK(!ec);
856 BOOST_ASIO_CHECK(length == 26);
857
858 s.reset(data: read_data, length: sizeof(read_data));
859 s.next_read_length(length: 1);
860 ec = boost::system::error_code();
861 length = 0;
862 called = false;
863 sb1.consume(n: sb1.size());
864 boost::asio::async_read_until(s, b&: sb1, delim: 'Z',
865 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
866 args: _2, args: &length, args: &called));
867 ioc.restart();
868 ioc.run();
869 BOOST_ASIO_CHECK(called);
870 BOOST_ASIO_CHECK(!ec);
871 BOOST_ASIO_CHECK(length == 26);
872
873 s.reset(data: read_data, length: sizeof(read_data));
874 s.next_read_length(length: 10);
875 ec = boost::system::error_code();
876 length = 0;
877 called = false;
878 sb1.consume(n: sb1.size());
879 boost::asio::async_read_until(s, b&: sb1, delim: 'Z',
880 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
881 args: _2, args: &length, args: &called));
882 ioc.restart();
883 ioc.run();
884 BOOST_ASIO_CHECK(called);
885 BOOST_ASIO_CHECK(!ec);
886 BOOST_ASIO_CHECK(length == 26);
887
888 s.reset(data: read_data, length: sizeof(read_data));
889 ec = boost::system::error_code();
890 length = 0;
891 called = false;
892 sb2.consume(n: sb2.size());
893 boost::asio::async_read_until(s, b&: sb2, delim: 'Z',
894 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
895 args: _2, args: &length, args: &called));
896 ioc.restart();
897 ioc.run();
898 BOOST_ASIO_CHECK(called);
899 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
900 BOOST_ASIO_CHECK(length == 0);
901
902 s.reset(data: read_data, length: sizeof(read_data));
903 s.next_read_length(length: 1);
904 ec = boost::system::error_code();
905 length = 0;
906 called = false;
907 sb2.consume(n: sb2.size());
908 boost::asio::async_read_until(s, b&: sb2, delim: 'Z',
909 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
910 args: _2, args: &length, args: &called));
911 ioc.restart();
912 ioc.run();
913 BOOST_ASIO_CHECK(called);
914 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
915 BOOST_ASIO_CHECK(length == 0);
916
917 s.reset(data: read_data, length: sizeof(read_data));
918 s.next_read_length(length: 10);
919 ec = boost::system::error_code();
920 length = 0;
921 called = false;
922 sb2.consume(n: sb2.size());
923 boost::asio::async_read_until(s, b&: sb2, delim: 'Z',
924 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
925 args: _2, args: &length, args: &called));
926 ioc.restart();
927 ioc.run();
928 BOOST_ASIO_CHECK(called);
929 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
930 BOOST_ASIO_CHECK(length == 0);
931
932 s.reset(data: read_data, length: sizeof(read_data));
933 ec = boost::system::error_code();
934 length = 0;
935 called = false;
936 sb2.consume(n: sb2.size());
937 boost::asio::async_read_until(s, b&: sb2, delim: 'Y',
938 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
939 args: _2, args: &length, args: &called));
940 ioc.restart();
941 ioc.run();
942 BOOST_ASIO_CHECK(called);
943 BOOST_ASIO_CHECK(!ec);
944 BOOST_ASIO_CHECK(length == 25);
945
946 s.reset(data: read_data, length: sizeof(read_data));
947 s.next_read_length(length: 1);
948 ec = boost::system::error_code();
949 length = 0;
950 called = false;
951 sb2.consume(n: sb2.size());
952 boost::asio::async_read_until(s, b&: sb2, delim: 'Y',
953 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
954 args: _2, args: &length, args: &called));
955 ioc.restart();
956 ioc.run();
957 BOOST_ASIO_CHECK(called);
958 BOOST_ASIO_CHECK(!ec);
959 BOOST_ASIO_CHECK(length == 25);
960
961 s.reset(data: read_data, length: sizeof(read_data));
962 s.next_read_length(length: 10);
963 ec = boost::system::error_code();
964 length = 0;
965 called = false;
966 sb2.consume(n: sb2.size());
967 boost::asio::async_read_until(s, b&: sb2, delim: 'Y',
968 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
969 args: _2, args: &length, args: &called));
970 ioc.restart();
971 ioc.run();
972 BOOST_ASIO_CHECK(called);
973 BOOST_ASIO_CHECK(!ec);
974 BOOST_ASIO_CHECK(length == 25);
975
976 s.reset(data: read_data, length: sizeof(read_data));
977 sb2.consume(n: sb2.size());
978 int i = boost::asio::async_read_until(s, b&: sb2, delim: 'Y',
979 token: archetypes::lazy_handler());
980 BOOST_ASIO_CHECK(i == 42);
981 ioc.restart();
982 ioc.run();
983#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
984}
985
986void test_dynamic_string_async_read_until_string()
987{
988 namespace bindns = std;
989 using bindns::placeholders::_1;
990 using bindns::placeholders::_2;
991
992 boost::asio::io_context ioc;
993 test_stream s(ioc);
994 std::string data1, data2;
995 boost::asio::dynamic_string_buffer<char, std::string::traits_type,
996 std::string::allocator_type> sb1 = boost::asio::dynamic_buffer(data&: data1);
997 boost::asio::dynamic_string_buffer<char, std::string::traits_type,
998 std::string::allocator_type> sb2 = boost::asio::dynamic_buffer(data&: data2, max_size: 25);
999 boost::system::error_code ec;
1000 std::size_t length;
1001 bool called;
1002
1003 s.reset(data: read_data, length: sizeof(read_data));
1004 ec = boost::system::error_code();
1005 length = 0;
1006 called = false;
1007 sb1.consume(n: sb1.size());
1008 boost::asio::async_read_until(s, buffers: sb1, delim: "XYZ",
1009 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1010 args: _2, args: &length, args: &called));
1011 ioc.restart();
1012 ioc.run();
1013 BOOST_ASIO_CHECK(called);
1014 BOOST_ASIO_CHECK(!ec);
1015 BOOST_ASIO_CHECK(length == 26);
1016
1017 s.reset(data: read_data, length: sizeof(read_data));
1018 s.next_read_length(length: 1);
1019 ec = boost::system::error_code();
1020 length = 0;
1021 called = false;
1022 sb1.consume(n: sb1.size());
1023 boost::asio::async_read_until(s, buffers: sb1, delim: "XYZ",
1024 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1025 args: _2, args: &length, args: &called));
1026 ioc.restart();
1027 ioc.run();
1028 BOOST_ASIO_CHECK(called);
1029 BOOST_ASIO_CHECK(!ec);
1030 BOOST_ASIO_CHECK(length == 26);
1031
1032 s.reset(data: read_data, length: sizeof(read_data));
1033 s.next_read_length(length: 10);
1034 ec = boost::system::error_code();
1035 length = 0;
1036 called = false;
1037 sb1.consume(n: sb1.size());
1038 boost::asio::async_read_until(s, buffers: sb1, delim: "XYZ",
1039 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1040 args: _2, args: &length, args: &called));
1041 ioc.restart();
1042 ioc.run();
1043 BOOST_ASIO_CHECK(called);
1044 BOOST_ASIO_CHECK(!ec);
1045 BOOST_ASIO_CHECK(length == 26);
1046
1047 s.reset(data: read_data, length: sizeof(read_data));
1048 ec = boost::system::error_code();
1049 length = 0;
1050 called = false;
1051 sb2.consume(n: sb2.size());
1052 boost::asio::async_read_until(s, buffers: sb2, delim: "XYZ",
1053 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1054 args: _2, args: &length, args: &called));
1055 ioc.restart();
1056 ioc.run();
1057 BOOST_ASIO_CHECK(called);
1058 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1059 BOOST_ASIO_CHECK(length == 0);
1060
1061 s.reset(data: read_data, length: sizeof(read_data));
1062 s.next_read_length(length: 1);
1063 ec = boost::system::error_code();
1064 length = 0;
1065 called = false;
1066 sb2.consume(n: sb2.size());
1067 boost::asio::async_read_until(s, buffers: sb2, delim: "XYZ",
1068 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1069 args: _2, args: &length, args: &called));
1070 ioc.restart();
1071 ioc.run();
1072 BOOST_ASIO_CHECK(called);
1073 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1074 BOOST_ASIO_CHECK(length == 0);
1075
1076 s.reset(data: read_data, length: sizeof(read_data));
1077 s.next_read_length(length: 10);
1078 ec = boost::system::error_code();
1079 length = 0;
1080 called = false;
1081 sb2.consume(n: sb2.size());
1082 boost::asio::async_read_until(s, buffers: sb2, delim: "XYZ",
1083 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1084 args: _2, args: &length, args: &called));
1085 ioc.restart();
1086 ioc.run();
1087 BOOST_ASIO_CHECK(called);
1088 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1089 BOOST_ASIO_CHECK(length == 0);
1090
1091 s.reset(data: read_data, length: sizeof(read_data));
1092 ec = boost::system::error_code();
1093 length = 0;
1094 called = false;
1095 sb2.consume(n: sb2.size());
1096 boost::asio::async_read_until(s, buffers: sb2, delim: "WXY",
1097 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1098 args: _2, args: &length, args: &called));
1099 ioc.restart();
1100 ioc.run();
1101 BOOST_ASIO_CHECK(called);
1102 BOOST_ASIO_CHECK(!ec);
1103 BOOST_ASIO_CHECK(length == 25);
1104
1105 s.reset(data: read_data, length: sizeof(read_data));
1106 s.next_read_length(length: 1);
1107 ec = boost::system::error_code();
1108 length = 0;
1109 called = false;
1110 sb2.consume(n: sb2.size());
1111 boost::asio::async_read_until(s, buffers: sb2, delim: "WXY",
1112 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1113 args: _2, args: &length, args: &called));
1114 ioc.restart();
1115 ioc.run();
1116 BOOST_ASIO_CHECK(called);
1117 BOOST_ASIO_CHECK(!ec);
1118 BOOST_ASIO_CHECK(length == 25);
1119
1120 s.reset(data: read_data, length: sizeof(read_data));
1121 s.next_read_length(length: 10);
1122 ec = boost::system::error_code();
1123 length = 0;
1124 called = false;
1125 sb2.consume(n: sb2.size());
1126 boost::asio::async_read_until(s, buffers: sb2, delim: "WXY",
1127 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1128 args: _2, args: &length, args: &called));
1129 ioc.restart();
1130 ioc.run();
1131 BOOST_ASIO_CHECK(called);
1132 BOOST_ASIO_CHECK(!ec);
1133 BOOST_ASIO_CHECK(length == 25);
1134
1135 s.reset(data: read_data, length: sizeof(read_data));
1136 sb2.consume(n: sb2.size());
1137 int i = boost::asio::async_read_until(s, buffers: sb2, delim: "WXY",
1138 token: archetypes::lazy_handler());
1139 BOOST_ASIO_CHECK(i == 42);
1140 ioc.restart();
1141 ioc.run();
1142}
1143
1144void test_streambuf_async_read_until_string()
1145{
1146#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1147 namespace bindns = std;
1148 using bindns::placeholders::_1;
1149 using bindns::placeholders::_2;
1150
1151 boost::asio::io_context ioc;
1152 test_stream s(ioc);
1153 boost::asio::streambuf sb1;
1154 boost::asio::streambuf sb2(25);
1155 boost::system::error_code ec;
1156 std::size_t length;
1157 bool called;
1158
1159 s.reset(data: read_data, length: sizeof(read_data));
1160 ec = boost::system::error_code();
1161 length = 0;
1162 called = false;
1163 sb1.consume(n: sb1.size());
1164 boost::asio::async_read_until(s, b&: sb1, delim: "XYZ",
1165 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1166 args: _2, args: &length, args: &called));
1167 ioc.restart();
1168 ioc.run();
1169 BOOST_ASIO_CHECK(called);
1170 BOOST_ASIO_CHECK(!ec);
1171 BOOST_ASIO_CHECK(length == 26);
1172
1173 s.reset(data: read_data, length: sizeof(read_data));
1174 s.next_read_length(length: 1);
1175 ec = boost::system::error_code();
1176 length = 0;
1177 called = false;
1178 sb1.consume(n: sb1.size());
1179 boost::asio::async_read_until(s, b&: sb1, delim: "XYZ",
1180 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1181 args: _2, args: &length, args: &called));
1182 ioc.restart();
1183 ioc.run();
1184 BOOST_ASIO_CHECK(called);
1185 BOOST_ASIO_CHECK(!ec);
1186 BOOST_ASIO_CHECK(length == 26);
1187
1188 s.reset(data: read_data, length: sizeof(read_data));
1189 s.next_read_length(length: 10);
1190 ec = boost::system::error_code();
1191 length = 0;
1192 called = false;
1193 sb1.consume(n: sb1.size());
1194 boost::asio::async_read_until(s, b&: sb1, delim: "XYZ",
1195 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1196 args: _2, args: &length, args: &called));
1197 ioc.restart();
1198 ioc.run();
1199 BOOST_ASIO_CHECK(called);
1200 BOOST_ASIO_CHECK(!ec);
1201 BOOST_ASIO_CHECK(length == 26);
1202
1203 s.reset(data: read_data, length: sizeof(read_data));
1204 ec = boost::system::error_code();
1205 length = 0;
1206 called = false;
1207 sb2.consume(n: sb2.size());
1208 boost::asio::async_read_until(s, b&: sb2, delim: "XYZ",
1209 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1210 args: _2, args: &length, args: &called));
1211 ioc.restart();
1212 ioc.run();
1213 BOOST_ASIO_CHECK(called);
1214 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1215 BOOST_ASIO_CHECK(length == 0);
1216
1217 s.reset(data: read_data, length: sizeof(read_data));
1218 s.next_read_length(length: 1);
1219 ec = boost::system::error_code();
1220 length = 0;
1221 called = false;
1222 sb2.consume(n: sb2.size());
1223 boost::asio::async_read_until(s, b&: sb2, delim: "XYZ",
1224 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1225 args: _2, args: &length, args: &called));
1226 ioc.restart();
1227 ioc.run();
1228 BOOST_ASIO_CHECK(called);
1229 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1230 BOOST_ASIO_CHECK(length == 0);
1231
1232 s.reset(data: read_data, length: sizeof(read_data));
1233 s.next_read_length(length: 10);
1234 ec = boost::system::error_code();
1235 length = 0;
1236 called = false;
1237 sb2.consume(n: sb2.size());
1238 boost::asio::async_read_until(s, b&: sb2, delim: "XYZ",
1239 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1240 args: _2, args: &length, args: &called));
1241 ioc.restart();
1242 ioc.run();
1243 BOOST_ASIO_CHECK(called);
1244 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1245 BOOST_ASIO_CHECK(length == 0);
1246
1247 s.reset(data: read_data, length: sizeof(read_data));
1248 ec = boost::system::error_code();
1249 length = 0;
1250 called = false;
1251 sb2.consume(n: sb2.size());
1252 boost::asio::async_read_until(s, b&: sb2, delim: "WXY",
1253 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1254 args: _2, args: &length, args: &called));
1255 ioc.restart();
1256 ioc.run();
1257 BOOST_ASIO_CHECK(called);
1258 BOOST_ASIO_CHECK(!ec);
1259 BOOST_ASIO_CHECK(length == 25);
1260
1261 s.reset(data: read_data, length: sizeof(read_data));
1262 s.next_read_length(length: 1);
1263 ec = boost::system::error_code();
1264 length = 0;
1265 called = false;
1266 sb2.consume(n: sb2.size());
1267 boost::asio::async_read_until(s, b&: sb2, delim: "WXY",
1268 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1269 args: _2, args: &length, args: &called));
1270 ioc.restart();
1271 ioc.run();
1272 BOOST_ASIO_CHECK(called);
1273 BOOST_ASIO_CHECK(!ec);
1274 BOOST_ASIO_CHECK(length == 25);
1275
1276 s.reset(data: read_data, length: sizeof(read_data));
1277 s.next_read_length(length: 10);
1278 ec = boost::system::error_code();
1279 length = 0;
1280 called = false;
1281 sb2.consume(n: sb2.size());
1282 boost::asio::async_read_until(s, b&: sb2, delim: "WXY",
1283 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1284 args: _2, args: &length, args: &called));
1285 ioc.restart();
1286 ioc.run();
1287 BOOST_ASIO_CHECK(called);
1288 BOOST_ASIO_CHECK(!ec);
1289 BOOST_ASIO_CHECK(length == 25);
1290
1291 s.reset(data: read_data, length: sizeof(read_data));
1292 sb2.consume(n: sb2.size());
1293 int i = boost::asio::async_read_until(s, b&: sb2, delim: "WXY",
1294 token: archetypes::lazy_handler());
1295 BOOST_ASIO_CHECK(i == 42);
1296 ioc.restart();
1297 ioc.run();
1298#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1299}
1300
1301void test_dynamic_string_async_read_until_match_condition()
1302{
1303 namespace bindns = std;
1304 using bindns::placeholders::_1;
1305 using bindns::placeholders::_2;
1306
1307 boost::asio::io_context ioc;
1308 test_stream s(ioc);
1309 std::string data1, data2;
1310 boost::asio::dynamic_string_buffer<char, std::string::traits_type,
1311 std::string::allocator_type> sb1 = boost::asio::dynamic_buffer(data&: data1);
1312 boost::asio::dynamic_string_buffer<char, std::string::traits_type,
1313 std::string::allocator_type> sb2 = boost::asio::dynamic_buffer(data&: data2, max_size: 25);
1314 boost::system::error_code ec;
1315 std::size_t length;
1316 bool called;
1317
1318 s.reset(data: read_data, length: sizeof(read_data));
1319 ec = boost::system::error_code();
1320 length = 0;
1321 called = false;
1322 sb1.consume(n: sb1.size());
1323 boost::asio::async_read_until(s, buffers: sb1, match_condition: match_char('Z'),
1324 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1325 args: _2, args: &length, args: &called));
1326 ioc.restart();
1327 ioc.run();
1328 BOOST_ASIO_CHECK(called);
1329 BOOST_ASIO_CHECK(!ec);
1330 BOOST_ASIO_CHECK(length == 26);
1331
1332 s.reset(data: read_data, length: sizeof(read_data));
1333 s.next_read_length(length: 1);
1334 ec = boost::system::error_code();
1335 length = 0;
1336 called = false;
1337 sb1.consume(n: sb1.size());
1338 boost::asio::async_read_until(s, buffers: sb1, match_condition: match_char('Z'),
1339 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1340 args: _2, args: &length, args: &called));
1341 ioc.restart();
1342 ioc.run();
1343 BOOST_ASIO_CHECK(called);
1344 BOOST_ASIO_CHECK(!ec);
1345 BOOST_ASIO_CHECK(length == 26);
1346
1347 s.reset(data: read_data, length: sizeof(read_data));
1348 s.next_read_length(length: 10);
1349 ec = boost::system::error_code();
1350 length = 0;
1351 called = false;
1352 sb1.consume(n: sb1.size());
1353 boost::asio::async_read_until(s, buffers: sb1, match_condition: match_char('Z'),
1354 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1355 args: _2, args: &length, args: &called));
1356 ioc.restart();
1357 ioc.run();
1358 BOOST_ASIO_CHECK(called);
1359 BOOST_ASIO_CHECK(!ec);
1360 BOOST_ASIO_CHECK(length == 26);
1361
1362 s.reset(data: read_data, length: sizeof(read_data));
1363 ec = boost::system::error_code();
1364 length = 0;
1365 called = false;
1366 sb2.consume(n: sb2.size());
1367 boost::asio::async_read_until(s, buffers: sb2, match_condition: match_char('Z'),
1368 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1369 args: _2, args: &length, args: &called));
1370 ioc.restart();
1371 ioc.run();
1372 BOOST_ASIO_CHECK(called);
1373 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1374 BOOST_ASIO_CHECK(length == 0);
1375
1376 s.reset(data: read_data, length: sizeof(read_data));
1377 s.next_read_length(length: 1);
1378 ec = boost::system::error_code();
1379 length = 0;
1380 called = false;
1381 sb2.consume(n: sb2.size());
1382 boost::asio::async_read_until(s, buffers: sb2, match_condition: match_char('Z'),
1383 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1384 args: _2, args: &length, args: &called));
1385 ioc.restart();
1386 ioc.run();
1387 BOOST_ASIO_CHECK(called);
1388 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1389 BOOST_ASIO_CHECK(length == 0);
1390
1391 s.reset(data: read_data, length: sizeof(read_data));
1392 s.next_read_length(length: 10);
1393 ec = boost::system::error_code();
1394 length = 0;
1395 called = false;
1396 sb2.consume(n: sb2.size());
1397 boost::asio::async_read_until(s, buffers: sb2, match_condition: match_char('Z'),
1398 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1399 args: _2, args: &length, args: &called));
1400 ioc.restart();
1401 ioc.run();
1402 BOOST_ASIO_CHECK(called);
1403 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1404 BOOST_ASIO_CHECK(length == 0);
1405
1406 s.reset(data: read_data, length: sizeof(read_data));
1407 ec = boost::system::error_code();
1408 length = 0;
1409 called = false;
1410 sb2.consume(n: sb2.size());
1411 boost::asio::async_read_until(s, buffers: sb2, match_condition: match_char('Y'),
1412 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1413 args: _2, args: &length, args: &called));
1414 ioc.restart();
1415 ioc.run();
1416 BOOST_ASIO_CHECK(called);
1417 BOOST_ASIO_CHECK(!ec);
1418 BOOST_ASIO_CHECK(length == 25);
1419
1420 s.reset(data: read_data, length: sizeof(read_data));
1421 s.next_read_length(length: 1);
1422 ec = boost::system::error_code();
1423 length = 0;
1424 called = false;
1425 sb2.consume(n: sb2.size());
1426 boost::asio::async_read_until(s, buffers: sb2, match_condition: match_char('Y'),
1427 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1428 args: _2, args: &length, args: &called));
1429 ioc.restart();
1430 ioc.run();
1431 BOOST_ASIO_CHECK(called);
1432 BOOST_ASIO_CHECK(!ec);
1433 BOOST_ASIO_CHECK(length == 25);
1434
1435 s.reset(data: read_data, length: sizeof(read_data));
1436 s.next_read_length(length: 10);
1437 ec = boost::system::error_code();
1438 length = 0;
1439 called = false;
1440 sb2.consume(n: sb2.size());
1441 boost::asio::async_read_until(s, buffers: sb2, match_condition: match_char('Y'),
1442 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1443 args: _2, args: &length, args: &called));
1444 ioc.restart();
1445 ioc.run();
1446 BOOST_ASIO_CHECK(called);
1447 BOOST_ASIO_CHECK(!ec);
1448 BOOST_ASIO_CHECK(length == 25);
1449
1450 s.reset(data: read_data, length: sizeof(read_data));
1451 sb2.consume(n: sb2.size());
1452 int i = boost::asio::async_read_until(s, buffers: sb2, match_condition: match_char('Y'),
1453 token: archetypes::lazy_handler());
1454 BOOST_ASIO_CHECK(i == 42);
1455 ioc.restart();
1456 ioc.run();
1457}
1458
1459void test_streambuf_async_read_until_match_condition()
1460{
1461#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1462 namespace bindns = std;
1463 using bindns::placeholders::_1;
1464 using bindns::placeholders::_2;
1465
1466 boost::asio::io_context ioc;
1467 test_stream s(ioc);
1468 boost::asio::streambuf sb1;
1469 boost::asio::streambuf sb2(25);
1470 boost::system::error_code ec;
1471 std::size_t length;
1472 bool called;
1473
1474 s.reset(data: read_data, length: sizeof(read_data));
1475 ec = boost::system::error_code();
1476 length = 0;
1477 called = false;
1478 sb1.consume(n: sb1.size());
1479 boost::asio::async_read_until(s, b&: sb1, match_condition: match_char('Z'),
1480 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1481 args: _2, args: &length, args: &called));
1482 ioc.restart();
1483 ioc.run();
1484 BOOST_ASIO_CHECK(called);
1485 BOOST_ASIO_CHECK(!ec);
1486 BOOST_ASIO_CHECK(length == 26);
1487
1488 s.reset(data: read_data, length: sizeof(read_data));
1489 s.next_read_length(length: 1);
1490 ec = boost::system::error_code();
1491 length = 0;
1492 called = false;
1493 sb1.consume(n: sb1.size());
1494 boost::asio::async_read_until(s, b&: sb1, match_condition: match_char('Z'),
1495 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1496 args: _2, args: &length, args: &called));
1497 ioc.restart();
1498 ioc.run();
1499 BOOST_ASIO_CHECK(called);
1500 BOOST_ASIO_CHECK(!ec);
1501 BOOST_ASIO_CHECK(length == 26);
1502
1503 s.reset(data: read_data, length: sizeof(read_data));
1504 s.next_read_length(length: 10);
1505 ec = boost::system::error_code();
1506 length = 0;
1507 called = false;
1508 sb1.consume(n: sb1.size());
1509 boost::asio::async_read_until(s, b&: sb1, match_condition: match_char('Z'),
1510 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1511 args: _2, args: &length, args: &called));
1512 ioc.restart();
1513 ioc.run();
1514 BOOST_ASIO_CHECK(called);
1515 BOOST_ASIO_CHECK(!ec);
1516 BOOST_ASIO_CHECK(length == 26);
1517
1518 s.reset(data: read_data, length: sizeof(read_data));
1519 ec = boost::system::error_code();
1520 length = 0;
1521 called = false;
1522 sb2.consume(n: sb2.size());
1523 boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Z'),
1524 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1525 args: _2, args: &length, args: &called));
1526 ioc.restart();
1527 ioc.run();
1528 BOOST_ASIO_CHECK(called);
1529 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1530 BOOST_ASIO_CHECK(length == 0);
1531
1532 s.reset(data: read_data, length: sizeof(read_data));
1533 s.next_read_length(length: 1);
1534 ec = boost::system::error_code();
1535 length = 0;
1536 called = false;
1537 sb2.consume(n: sb2.size());
1538 boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Z'),
1539 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1540 args: _2, args: &length, args: &called));
1541 ioc.restart();
1542 ioc.run();
1543 BOOST_ASIO_CHECK(called);
1544 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1545 BOOST_ASIO_CHECK(length == 0);
1546
1547 s.reset(data: read_data, length: sizeof(read_data));
1548 s.next_read_length(length: 10);
1549 ec = boost::system::error_code();
1550 length = 0;
1551 called = false;
1552 sb2.consume(n: sb2.size());
1553 boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Z'),
1554 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1555 args: _2, args: &length, args: &called));
1556 ioc.restart();
1557 ioc.run();
1558 BOOST_ASIO_CHECK(called);
1559 BOOST_ASIO_CHECK(ec == boost::asio::error::not_found);
1560 BOOST_ASIO_CHECK(length == 0);
1561
1562 s.reset(data: read_data, length: sizeof(read_data));
1563 ec = boost::system::error_code();
1564 length = 0;
1565 called = false;
1566 sb2.consume(n: sb2.size());
1567 boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Y'),
1568 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1569 args: _2, args: &length, args: &called));
1570 ioc.restart();
1571 ioc.run();
1572 BOOST_ASIO_CHECK(called);
1573 BOOST_ASIO_CHECK(!ec);
1574 BOOST_ASIO_CHECK(length == 25);
1575
1576 s.reset(data: read_data, length: sizeof(read_data));
1577 s.next_read_length(length: 1);
1578 ec = boost::system::error_code();
1579 length = 0;
1580 called = false;
1581 sb2.consume(n: sb2.size());
1582 boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Y'),
1583 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1584 args: _2, args: &length, args: &called));
1585 ioc.restart();
1586 ioc.run();
1587 BOOST_ASIO_CHECK(called);
1588 BOOST_ASIO_CHECK(!ec);
1589 BOOST_ASIO_CHECK(length == 25);
1590
1591 s.reset(data: read_data, length: sizeof(read_data));
1592 s.next_read_length(length: 10);
1593 ec = boost::system::error_code();
1594 length = 0;
1595 called = false;
1596 sb2.consume(n: sb2.size());
1597 boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Y'),
1598 token: bindns::bind(f&: async_read_handler, args: _1, args: &ec,
1599 args: _2, args: &length, args: &called));
1600 ioc.restart();
1601 ioc.run();
1602 BOOST_ASIO_CHECK(called);
1603 BOOST_ASIO_CHECK(!ec);
1604 BOOST_ASIO_CHECK(length == 25);
1605
1606 s.reset(data: read_data, length: sizeof(read_data));
1607 sb2.consume(n: sb2.size());
1608 int i = boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Y'),
1609 token: archetypes::lazy_handler());
1610 BOOST_ASIO_CHECK(i == 42);
1611 ioc.restart();
1612 ioc.run();
1613#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1614}
1615
1616BOOST_ASIO_TEST_SUITE
1617(
1618 "read_until",
1619 BOOST_ASIO_TEST_CASE(test_dynamic_string_read_until_char)
1620 BOOST_ASIO_TEST_CASE(test_streambuf_read_until_char)
1621 BOOST_ASIO_TEST_CASE(test_dynamic_string_read_until_string)
1622 BOOST_ASIO_TEST_CASE(test_streambuf_read_until_string)
1623 BOOST_ASIO_TEST_CASE(test_dynamic_string_read_until_match_condition)
1624 BOOST_ASIO_TEST_CASE(test_streambuf_read_until_match_condition)
1625 BOOST_ASIO_TEST_CASE(test_dynamic_string_async_read_until_char)
1626 BOOST_ASIO_TEST_CASE(test_streambuf_async_read_until_char)
1627 BOOST_ASIO_TEST_CASE(test_dynamic_string_async_read_until_string)
1628 BOOST_ASIO_TEST_CASE(test_streambuf_async_read_until_string)
1629 BOOST_ASIO_TEST_CASE(test_dynamic_string_async_read_until_match_condition)
1630 BOOST_ASIO_TEST_CASE(test_streambuf_async_read_until_match_condition)
1631)
1632

source code of boost/libs/asio/test/read_until.cpp