1 | // |
2 | // read_until.cpp |
3 | // ~~~~~~~~~~~~~~ |
4 | // |
5 | // Copyright (c) 2003-2015 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 "archetypes/async_result.hpp" |
21 | #include <boost/asio/io_service.hpp> |
22 | #include <boost/asio/streambuf.hpp> |
23 | #include "unit_test.hpp" |
24 | |
25 | #if defined(BOOST_ASIO_HAS_BOOST_BIND) |
26 | # include <boost/bind.hpp> |
27 | #else // defined(BOOST_ASIO_HAS_BOOST_BIND) |
28 | # include <functional> |
29 | #endif // defined(BOOST_ASIO_HAS_BOOST_BIND) |
30 | |
31 | class test_stream |
32 | { |
33 | public: |
34 | typedef boost::asio::io_service io_service_type; |
35 | |
36 | test_stream(boost::asio::io_service& io_service) |
37 | : io_service_(io_service), |
38 | length_(0), |
39 | position_(0), |
40 | next_read_length_(0) |
41 | { |
42 | } |
43 | |
44 | io_service_type& get_io_service() |
45 | { |
46 | return io_service_; |
47 | } |
48 | |
49 | void reset(const void* data, size_t length) |
50 | { |
51 | using namespace std; // For memcpy. |
52 | |
53 | BOOST_ASIO_CHECK(length <= max_length); |
54 | |
55 | memcpy(dest: data_, src: data, n: length); |
56 | length_ = length; |
57 | position_ = 0; |
58 | next_read_length_ = length; |
59 | } |
60 | |
61 | void next_read_length(size_t length) |
62 | { |
63 | next_read_length_ = length; |
64 | } |
65 | |
66 | template <typename Mutable_Buffers> |
67 | size_t read_some(const Mutable_Buffers& buffers) |
68 | { |
69 | size_t n = boost::asio::buffer_copy(buffers, |
70 | boost::asio::buffer(data&: data_, max_size_in_bytes: length_) + position_, |
71 | next_read_length_); |
72 | position_ += n; |
73 | return n; |
74 | } |
75 | |
76 | template <typename Mutable_Buffers> |
77 | size_t read_some(const Mutable_Buffers& buffers, |
78 | boost::system::error_code& ec) |
79 | { |
80 | ec = boost::system::error_code(); |
81 | return read_some(buffers); |
82 | } |
83 | |
84 | template <typename Mutable_Buffers, typename Handler> |
85 | void async_read_some(const Mutable_Buffers& buffers, Handler handler) |
86 | { |
87 | size_t bytes_transferred = read_some(buffers); |
88 | io_service_.post(boost::asio::detail::bind_handler( |
89 | handler, boost::system::error_code(), bytes_transferred)); |
90 | } |
91 | |
92 | private: |
93 | io_service_type& io_service_; |
94 | enum { max_length = 8192 }; |
95 | char data_[max_length]; |
96 | size_t length_; |
97 | size_t position_; |
98 | size_t next_read_length_; |
99 | }; |
100 | |
101 | static const char read_data[] |
102 | = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ; |
103 | |
104 | void test_char_read_until() |
105 | { |
106 | boost::asio::io_service ios; |
107 | test_stream s(ios); |
108 | boost::asio::streambuf sb1; |
109 | boost::asio::streambuf sb2(25); |
110 | boost::system::error_code ec; |
111 | |
112 | s.reset(data: read_data, length: sizeof(read_data)); |
113 | sb1.consume(n: sb1.size()); |
114 | std::size_t length = boost::asio::read_until(s, b&: sb1, delim: 'Z'); |
115 | BOOST_ASIO_CHECK(length == 26); |
116 | |
117 | s.reset(data: read_data, length: sizeof(read_data)); |
118 | s.next_read_length(length: 1); |
119 | sb1.consume(n: sb1.size()); |
120 | length = boost::asio::read_until(s, b&: sb1, delim: 'Z'); |
121 | BOOST_ASIO_CHECK(length == 26); |
122 | |
123 | s.reset(data: read_data, length: sizeof(read_data)); |
124 | s.next_read_length(length: 10); |
125 | sb1.consume(n: sb1.size()); |
126 | length = boost::asio::read_until(s, b&: sb1, delim: 'Z'); |
127 | BOOST_ASIO_CHECK(length == 26); |
128 | |
129 | s.reset(data: read_data, length: sizeof(read_data)); |
130 | sb1.consume(n: sb1.size()); |
131 | length = boost::asio::read_until(s, b&: sb1, delim: 'Z', ec); |
132 | BOOST_ASIO_CHECK(!ec); |
133 | BOOST_ASIO_CHECK(length == 26); |
134 | |
135 | s.reset(data: read_data, length: sizeof(read_data)); |
136 | s.next_read_length(length: 1); |
137 | sb1.consume(n: sb1.size()); |
138 | length = boost::asio::read_until(s, b&: sb1, delim: 'Z', ec); |
139 | BOOST_ASIO_CHECK(!ec); |
140 | BOOST_ASIO_CHECK(length == 26); |
141 | |
142 | s.reset(data: read_data, length: sizeof(read_data)); |
143 | s.next_read_length(length: 10); |
144 | sb1.consume(n: sb1.size()); |
145 | length = boost::asio::read_until(s, b&: sb1, delim: 'Z', ec); |
146 | BOOST_ASIO_CHECK(!ec); |
147 | BOOST_ASIO_CHECK(length == 26); |
148 | |
149 | s.reset(data: read_data, length: sizeof(read_data)); |
150 | sb2.consume(n: sb2.size()); |
151 | length = boost::asio::read_until(s, b&: sb2, delim: 'Z', ec); |
152 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
153 | BOOST_ASIO_CHECK(length == 0); |
154 | |
155 | s.reset(data: read_data, length: sizeof(read_data)); |
156 | s.next_read_length(length: 1); |
157 | sb2.consume(n: sb2.size()); |
158 | length = boost::asio::read_until(s, b&: sb2, delim: 'Z', ec); |
159 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
160 | BOOST_ASIO_CHECK(length == 0); |
161 | |
162 | s.reset(data: read_data, length: sizeof(read_data)); |
163 | s.next_read_length(length: 10); |
164 | sb2.consume(n: sb2.size()); |
165 | length = boost::asio::read_until(s, b&: sb2, delim: 'Z', ec); |
166 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
167 | BOOST_ASIO_CHECK(length == 0); |
168 | |
169 | s.reset(data: read_data, length: sizeof(read_data)); |
170 | sb2.consume(n: sb2.size()); |
171 | length = boost::asio::read_until(s, b&: sb2, delim: 'Y', ec); |
172 | BOOST_ASIO_CHECK(!ec); |
173 | BOOST_ASIO_CHECK(length == 25); |
174 | |
175 | s.reset(data: read_data, length: sizeof(read_data)); |
176 | s.next_read_length(length: 1); |
177 | sb2.consume(n: sb2.size()); |
178 | length = boost::asio::read_until(s, b&: sb2, delim: 'Y', ec); |
179 | BOOST_ASIO_CHECK(!ec); |
180 | BOOST_ASIO_CHECK(length == 25); |
181 | |
182 | s.reset(data: read_data, length: sizeof(read_data)); |
183 | s.next_read_length(length: 10); |
184 | sb2.consume(n: sb2.size()); |
185 | length = boost::asio::read_until(s, b&: sb2, delim: 'Y', ec); |
186 | BOOST_ASIO_CHECK(!ec); |
187 | BOOST_ASIO_CHECK(length == 25); |
188 | } |
189 | |
190 | void test_string_read_until() |
191 | { |
192 | boost::asio::io_service ios; |
193 | test_stream s(ios); |
194 | boost::asio::streambuf sb1; |
195 | boost::asio::streambuf sb2(25); |
196 | boost::system::error_code ec; |
197 | |
198 | s.reset(data: read_data, length: sizeof(read_data)); |
199 | sb1.consume(n: sb1.size()); |
200 | std::size_t length = boost::asio::read_until(s, b&: sb1, delim: "XYZ" ); |
201 | BOOST_ASIO_CHECK(length == 26); |
202 | |
203 | s.reset(data: read_data, length: sizeof(read_data)); |
204 | s.next_read_length(length: 1); |
205 | sb1.consume(n: sb1.size()); |
206 | length = boost::asio::read_until(s, b&: sb1, delim: "XYZ" ); |
207 | BOOST_ASIO_CHECK(length == 26); |
208 | |
209 | s.reset(data: read_data, length: sizeof(read_data)); |
210 | s.next_read_length(length: 10); |
211 | sb1.consume(n: sb1.size()); |
212 | length = boost::asio::read_until(s, b&: sb1, delim: "XYZ" ); |
213 | BOOST_ASIO_CHECK(length == 26); |
214 | |
215 | s.reset(data: read_data, length: sizeof(read_data)); |
216 | sb1.consume(n: sb1.size()); |
217 | length = boost::asio::read_until(s, b&: sb1, delim: "XYZ" , ec); |
218 | BOOST_ASIO_CHECK(!ec); |
219 | BOOST_ASIO_CHECK(length == 26); |
220 | |
221 | s.reset(data: read_data, length: sizeof(read_data)); |
222 | s.next_read_length(length: 1); |
223 | sb1.consume(n: sb1.size()); |
224 | length = boost::asio::read_until(s, b&: sb1, delim: "XYZ" , ec); |
225 | BOOST_ASIO_CHECK(!ec); |
226 | BOOST_ASIO_CHECK(length == 26); |
227 | |
228 | s.reset(data: read_data, length: sizeof(read_data)); |
229 | s.next_read_length(length: 10); |
230 | sb1.consume(n: sb1.size()); |
231 | length = boost::asio::read_until(s, b&: sb1, delim: "XYZ" , ec); |
232 | BOOST_ASIO_CHECK(!ec); |
233 | BOOST_ASIO_CHECK(length == 26); |
234 | |
235 | s.reset(data: read_data, length: sizeof(read_data)); |
236 | sb2.consume(n: sb2.size()); |
237 | length = boost::asio::read_until(s, b&: sb2, delim: "XYZ" , ec); |
238 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
239 | BOOST_ASIO_CHECK(length == 0); |
240 | |
241 | s.reset(data: read_data, length: sizeof(read_data)); |
242 | s.next_read_length(length: 1); |
243 | sb2.consume(n: sb2.size()); |
244 | length = boost::asio::read_until(s, b&: sb2, delim: "XYZ" , ec); |
245 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
246 | BOOST_ASIO_CHECK(length == 0); |
247 | |
248 | s.reset(data: read_data, length: sizeof(read_data)); |
249 | s.next_read_length(length: 10); |
250 | sb2.consume(n: sb2.size()); |
251 | length = boost::asio::read_until(s, b&: sb2, delim: "XYZ" , ec); |
252 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
253 | BOOST_ASIO_CHECK(length == 0); |
254 | |
255 | s.reset(data: read_data, length: sizeof(read_data)); |
256 | sb2.consume(n: sb2.size()); |
257 | length = boost::asio::read_until(s, b&: sb2, delim: "WXY" , ec); |
258 | BOOST_ASIO_CHECK(!ec); |
259 | BOOST_ASIO_CHECK(length == 25); |
260 | |
261 | s.reset(data: read_data, length: sizeof(read_data)); |
262 | s.next_read_length(length: 1); |
263 | sb2.consume(n: sb2.size()); |
264 | length = boost::asio::read_until(s, b&: sb2, delim: "WXY" , ec); |
265 | BOOST_ASIO_CHECK(!ec); |
266 | BOOST_ASIO_CHECK(length == 25); |
267 | |
268 | s.reset(data: read_data, length: sizeof(read_data)); |
269 | s.next_read_length(length: 10); |
270 | sb2.consume(n: sb2.size()); |
271 | length = boost::asio::read_until(s, b&: sb2, delim: "WXY" , ec); |
272 | BOOST_ASIO_CHECK(!ec); |
273 | BOOST_ASIO_CHECK(length == 25); |
274 | } |
275 | |
276 | class match_char |
277 | { |
278 | public: |
279 | explicit match_char(char c) : c_(c) {} |
280 | |
281 | template <typename Iterator> |
282 | std::pair<Iterator, bool> operator()( |
283 | Iterator begin, Iterator end) const |
284 | { |
285 | Iterator i = begin; |
286 | while (i != end) |
287 | if (c_ == *i++) |
288 | return std::make_pair(i, true); |
289 | return std::make_pair(i, false); |
290 | } |
291 | |
292 | private: |
293 | char c_; |
294 | }; |
295 | |
296 | namespace boost { |
297 | namespace asio { |
298 | template <> struct is_match_condition<match_char> |
299 | { |
300 | enum { value = true }; |
301 | }; |
302 | } // namespace asio |
303 | } // namespace boost |
304 | |
305 | void test_match_condition_read_until() |
306 | { |
307 | boost::asio::io_service ios; |
308 | test_stream s(ios); |
309 | boost::asio::streambuf sb1; |
310 | boost::asio::streambuf sb2(25); |
311 | boost::system::error_code ec; |
312 | |
313 | s.reset(data: read_data, length: sizeof(read_data)); |
314 | sb1.consume(n: sb1.size()); |
315 | std::size_t length = boost::asio::read_until(s, b&: sb1, match_condition: match_char('Z')); |
316 | BOOST_ASIO_CHECK(length == 26); |
317 | |
318 | s.reset(data: read_data, length: sizeof(read_data)); |
319 | s.next_read_length(length: 1); |
320 | sb1.consume(n: sb1.size()); |
321 | length = boost::asio::read_until(s, b&: sb1, match_condition: match_char('Z')); |
322 | BOOST_ASIO_CHECK(length == 26); |
323 | |
324 | s.reset(data: read_data, length: sizeof(read_data)); |
325 | s.next_read_length(length: 10); |
326 | sb1.consume(n: sb1.size()); |
327 | length = boost::asio::read_until(s, b&: sb1, match_condition: match_char('Z')); |
328 | BOOST_ASIO_CHECK(length == 26); |
329 | |
330 | s.reset(data: read_data, length: sizeof(read_data)); |
331 | sb1.consume(n: sb1.size()); |
332 | length = boost::asio::read_until(s, b&: sb1, match_condition: match_char('Z'), ec); |
333 | BOOST_ASIO_CHECK(!ec); |
334 | BOOST_ASIO_CHECK(length == 26); |
335 | |
336 | s.reset(data: read_data, length: sizeof(read_data)); |
337 | s.next_read_length(length: 1); |
338 | sb1.consume(n: sb1.size()); |
339 | length = boost::asio::read_until(s, b&: sb1, match_condition: match_char('Z'), ec); |
340 | BOOST_ASIO_CHECK(!ec); |
341 | BOOST_ASIO_CHECK(length == 26); |
342 | |
343 | s.reset(data: read_data, length: sizeof(read_data)); |
344 | s.next_read_length(length: 10); |
345 | sb1.consume(n: sb1.size()); |
346 | length = boost::asio::read_until(s, b&: sb1, match_condition: match_char('Z'), ec); |
347 | BOOST_ASIO_CHECK(!ec); |
348 | BOOST_ASIO_CHECK(length == 26); |
349 | |
350 | s.reset(data: read_data, length: sizeof(read_data)); |
351 | sb2.consume(n: sb2.size()); |
352 | length = boost::asio::read_until(s, b&: sb2, match_condition: match_char('Z'), ec); |
353 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
354 | BOOST_ASIO_CHECK(length == 0); |
355 | |
356 | s.reset(data: read_data, length: sizeof(read_data)); |
357 | s.next_read_length(length: 1); |
358 | sb2.consume(n: sb2.size()); |
359 | length = boost::asio::read_until(s, b&: sb2, match_condition: match_char('Z'), ec); |
360 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
361 | BOOST_ASIO_CHECK(length == 0); |
362 | |
363 | s.reset(data: read_data, length: sizeof(read_data)); |
364 | s.next_read_length(length: 10); |
365 | sb2.consume(n: sb2.size()); |
366 | length = boost::asio::read_until(s, b&: sb2, match_condition: match_char('Z'), ec); |
367 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
368 | BOOST_ASIO_CHECK(length == 0); |
369 | |
370 | s.reset(data: read_data, length: sizeof(read_data)); |
371 | sb2.consume(n: sb2.size()); |
372 | length = boost::asio::read_until(s, b&: sb2, match_condition: match_char('Y'), ec); |
373 | BOOST_ASIO_CHECK(!ec); |
374 | BOOST_ASIO_CHECK(length == 25); |
375 | |
376 | s.reset(data: read_data, length: sizeof(read_data)); |
377 | s.next_read_length(length: 1); |
378 | sb2.consume(n: sb2.size()); |
379 | length = boost::asio::read_until(s, b&: sb2, match_condition: match_char('Y'), ec); |
380 | BOOST_ASIO_CHECK(!ec); |
381 | BOOST_ASIO_CHECK(length == 25); |
382 | |
383 | s.reset(data: read_data, length: sizeof(read_data)); |
384 | s.next_read_length(length: 10); |
385 | sb2.consume(n: sb2.size()); |
386 | length = boost::asio::read_until(s, b&: sb2, match_condition: match_char('Y'), ec); |
387 | BOOST_ASIO_CHECK(!ec); |
388 | BOOST_ASIO_CHECK(length == 25); |
389 | } |
390 | |
391 | void async_read_handler( |
392 | const boost::system::error_code& err, boost::system::error_code* err_out, |
393 | std::size_t bytes_transferred, std::size_t* bytes_out, bool* called) |
394 | { |
395 | *err_out = err; |
396 | *bytes_out = bytes_transferred; |
397 | *called = true; |
398 | } |
399 | |
400 | void test_char_async_read_until() |
401 | { |
402 | #if defined(BOOST_ASIO_HAS_BOOST_BIND) |
403 | namespace bindns = boost; |
404 | #else // defined(BOOST_ASIO_HAS_BOOST_BIND) |
405 | namespace bindns = std; |
406 | using std::placeholders::_1; |
407 | using std::placeholders::_2; |
408 | #endif // defined(BOOST_ASIO_HAS_BOOST_BIND) |
409 | |
410 | boost::asio::io_service ios; |
411 | test_stream s(ios); |
412 | boost::asio::streambuf sb1; |
413 | boost::asio::streambuf sb2(25); |
414 | boost::system::error_code ec; |
415 | std::size_t length; |
416 | bool called; |
417 | |
418 | s.reset(data: read_data, length: sizeof(read_data)); |
419 | ec = boost::system::error_code(); |
420 | length = 0; |
421 | called = false; |
422 | sb1.consume(n: sb1.size()); |
423 | boost::asio::async_read_until(s, b&: sb1, delim: 'Z', |
424 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
425 | a3: _2, a4: &length, a5: &called)); |
426 | ios.reset(); |
427 | ios.run(); |
428 | BOOST_ASIO_CHECK(called); |
429 | BOOST_ASIO_CHECK(!ec); |
430 | BOOST_ASIO_CHECK(length == 26); |
431 | |
432 | s.reset(data: read_data, length: sizeof(read_data)); |
433 | s.next_read_length(length: 1); |
434 | ec = boost::system::error_code(); |
435 | length = 0; |
436 | called = false; |
437 | sb1.consume(n: sb1.size()); |
438 | boost::asio::async_read_until(s, b&: sb1, delim: 'Z', |
439 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
440 | a3: _2, a4: &length, a5: &called)); |
441 | ios.reset(); |
442 | ios.run(); |
443 | BOOST_ASIO_CHECK(called); |
444 | BOOST_ASIO_CHECK(!ec); |
445 | BOOST_ASIO_CHECK(length == 26); |
446 | |
447 | s.reset(data: read_data, length: sizeof(read_data)); |
448 | s.next_read_length(length: 10); |
449 | ec = boost::system::error_code(); |
450 | length = 0; |
451 | called = false; |
452 | sb1.consume(n: sb1.size()); |
453 | boost::asio::async_read_until(s, b&: sb1, delim: 'Z', |
454 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
455 | a3: _2, a4: &length, a5: &called)); |
456 | ios.reset(); |
457 | ios.run(); |
458 | BOOST_ASIO_CHECK(called); |
459 | BOOST_ASIO_CHECK(!ec); |
460 | BOOST_ASIO_CHECK(length == 26); |
461 | |
462 | s.reset(data: read_data, length: sizeof(read_data)); |
463 | ec = boost::system::error_code(); |
464 | length = 0; |
465 | called = false; |
466 | sb2.consume(n: sb2.size()); |
467 | boost::asio::async_read_until(s, b&: sb2, delim: 'Z', |
468 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
469 | a3: _2, a4: &length, a5: &called)); |
470 | ios.reset(); |
471 | ios.run(); |
472 | BOOST_ASIO_CHECK(called); |
473 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
474 | BOOST_ASIO_CHECK(length == 0); |
475 | |
476 | s.reset(data: read_data, length: sizeof(read_data)); |
477 | s.next_read_length(length: 1); |
478 | ec = boost::system::error_code(); |
479 | length = 0; |
480 | called = false; |
481 | sb2.consume(n: sb2.size()); |
482 | boost::asio::async_read_until(s, b&: sb2, delim: 'Z', |
483 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
484 | a3: _2, a4: &length, a5: &called)); |
485 | ios.reset(); |
486 | ios.run(); |
487 | BOOST_ASIO_CHECK(called); |
488 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
489 | BOOST_ASIO_CHECK(length == 0); |
490 | |
491 | s.reset(data: read_data, length: sizeof(read_data)); |
492 | s.next_read_length(length: 10); |
493 | ec = boost::system::error_code(); |
494 | length = 0; |
495 | called = false; |
496 | sb2.consume(n: sb2.size()); |
497 | boost::asio::async_read_until(s, b&: sb2, delim: 'Z', |
498 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
499 | a3: _2, a4: &length, a5: &called)); |
500 | ios.reset(); |
501 | ios.run(); |
502 | BOOST_ASIO_CHECK(called); |
503 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
504 | BOOST_ASIO_CHECK(length == 0); |
505 | |
506 | s.reset(data: read_data, length: sizeof(read_data)); |
507 | ec = boost::system::error_code(); |
508 | length = 0; |
509 | called = false; |
510 | sb2.consume(n: sb2.size()); |
511 | boost::asio::async_read_until(s, b&: sb2, delim: 'Y', |
512 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
513 | a3: _2, a4: &length, a5: &called)); |
514 | ios.reset(); |
515 | ios.run(); |
516 | BOOST_ASIO_CHECK(called); |
517 | BOOST_ASIO_CHECK(!ec); |
518 | BOOST_ASIO_CHECK(length == 25); |
519 | |
520 | s.reset(data: read_data, length: sizeof(read_data)); |
521 | s.next_read_length(length: 1); |
522 | ec = boost::system::error_code(); |
523 | length = 0; |
524 | called = false; |
525 | sb2.consume(n: sb2.size()); |
526 | boost::asio::async_read_until(s, b&: sb2, delim: 'Y', |
527 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
528 | a3: _2, a4: &length, a5: &called)); |
529 | ios.reset(); |
530 | ios.run(); |
531 | BOOST_ASIO_CHECK(called); |
532 | BOOST_ASIO_CHECK(!ec); |
533 | BOOST_ASIO_CHECK(length == 25); |
534 | |
535 | s.reset(data: read_data, length: sizeof(read_data)); |
536 | s.next_read_length(length: 10); |
537 | ec = boost::system::error_code(); |
538 | length = 0; |
539 | called = false; |
540 | sb2.consume(n: sb2.size()); |
541 | boost::asio::async_read_until(s, b&: sb2, delim: 'Y', |
542 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
543 | a3: _2, a4: &length, a5: &called)); |
544 | ios.reset(); |
545 | ios.run(); |
546 | BOOST_ASIO_CHECK(called); |
547 | BOOST_ASIO_CHECK(!ec); |
548 | BOOST_ASIO_CHECK(length == 25); |
549 | |
550 | s.reset(data: read_data, length: sizeof(read_data)); |
551 | sb2.consume(n: sb2.size()); |
552 | int i = boost::asio::async_read_until(s, b&: sb2, delim: 'Y', |
553 | handler: archetypes::lazy_handler()); |
554 | BOOST_ASIO_CHECK(i == 42); |
555 | ios.reset(); |
556 | ios.run(); |
557 | } |
558 | |
559 | void test_string_async_read_until() |
560 | { |
561 | #if defined(BOOST_ASIO_HAS_BOOST_BIND) |
562 | namespace bindns = boost; |
563 | #else // defined(BOOST_ASIO_HAS_BOOST_BIND) |
564 | namespace bindns = std; |
565 | using std::placeholders::_1; |
566 | using std::placeholders::_2; |
567 | #endif // defined(BOOST_ASIO_HAS_BOOST_BIND) |
568 | |
569 | boost::asio::io_service ios; |
570 | test_stream s(ios); |
571 | boost::asio::streambuf sb1; |
572 | boost::asio::streambuf sb2(25); |
573 | boost::system::error_code ec; |
574 | std::size_t length; |
575 | bool called; |
576 | |
577 | s.reset(data: read_data, length: sizeof(read_data)); |
578 | ec = boost::system::error_code(); |
579 | length = 0; |
580 | called = false; |
581 | sb1.consume(n: sb1.size()); |
582 | boost::asio::async_read_until(s, b&: sb1, delim: "XYZ" , |
583 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
584 | a3: _2, a4: &length, a5: &called)); |
585 | ios.reset(); |
586 | ios.run(); |
587 | BOOST_ASIO_CHECK(called); |
588 | BOOST_ASIO_CHECK(!ec); |
589 | BOOST_ASIO_CHECK(length == 26); |
590 | |
591 | s.reset(data: read_data, length: sizeof(read_data)); |
592 | s.next_read_length(length: 1); |
593 | ec = boost::system::error_code(); |
594 | length = 0; |
595 | called = false; |
596 | sb1.consume(n: sb1.size()); |
597 | boost::asio::async_read_until(s, b&: sb1, delim: "XYZ" , |
598 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
599 | a3: _2, a4: &length, a5: &called)); |
600 | ios.reset(); |
601 | ios.run(); |
602 | BOOST_ASIO_CHECK(called); |
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: 10); |
608 | ec = boost::system::error_code(); |
609 | length = 0; |
610 | called = false; |
611 | sb1.consume(n: sb1.size()); |
612 | boost::asio::async_read_until(s, b&: sb1, delim: "XYZ" , |
613 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
614 | a3: _2, a4: &length, a5: &called)); |
615 | ios.reset(); |
616 | ios.run(); |
617 | BOOST_ASIO_CHECK(called); |
618 | BOOST_ASIO_CHECK(!ec); |
619 | BOOST_ASIO_CHECK(length == 26); |
620 | |
621 | s.reset(data: read_data, length: sizeof(read_data)); |
622 | ec = boost::system::error_code(); |
623 | length = 0; |
624 | called = false; |
625 | sb2.consume(n: sb2.size()); |
626 | boost::asio::async_read_until(s, b&: sb2, delim: "XYZ" , |
627 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
628 | a3: _2, a4: &length, a5: &called)); |
629 | ios.reset(); |
630 | ios.run(); |
631 | BOOST_ASIO_CHECK(called); |
632 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
633 | BOOST_ASIO_CHECK(length == 0); |
634 | |
635 | s.reset(data: read_data, length: sizeof(read_data)); |
636 | s.next_read_length(length: 1); |
637 | ec = boost::system::error_code(); |
638 | length = 0; |
639 | called = false; |
640 | sb2.consume(n: sb2.size()); |
641 | boost::asio::async_read_until(s, b&: sb2, delim: "XYZ" , |
642 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
643 | a3: _2, a4: &length, a5: &called)); |
644 | ios.reset(); |
645 | ios.run(); |
646 | BOOST_ASIO_CHECK(called); |
647 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
648 | BOOST_ASIO_CHECK(length == 0); |
649 | |
650 | s.reset(data: read_data, length: sizeof(read_data)); |
651 | s.next_read_length(length: 10); |
652 | ec = boost::system::error_code(); |
653 | length = 0; |
654 | called = false; |
655 | sb2.consume(n: sb2.size()); |
656 | boost::asio::async_read_until(s, b&: sb2, delim: "XYZ" , |
657 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
658 | a3: _2, a4: &length, a5: &called)); |
659 | ios.reset(); |
660 | ios.run(); |
661 | BOOST_ASIO_CHECK(called); |
662 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
663 | BOOST_ASIO_CHECK(length == 0); |
664 | |
665 | s.reset(data: read_data, length: sizeof(read_data)); |
666 | ec = boost::system::error_code(); |
667 | length = 0; |
668 | called = false; |
669 | sb2.consume(n: sb2.size()); |
670 | boost::asio::async_read_until(s, b&: sb2, delim: "WXY" , |
671 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
672 | a3: _2, a4: &length, a5: &called)); |
673 | ios.reset(); |
674 | ios.run(); |
675 | BOOST_ASIO_CHECK(called); |
676 | BOOST_ASIO_CHECK(!ec); |
677 | BOOST_ASIO_CHECK(length == 25); |
678 | |
679 | s.reset(data: read_data, length: sizeof(read_data)); |
680 | s.next_read_length(length: 1); |
681 | ec = boost::system::error_code(); |
682 | length = 0; |
683 | called = false; |
684 | sb2.consume(n: sb2.size()); |
685 | boost::asio::async_read_until(s, b&: sb2, delim: "WXY" , |
686 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
687 | a3: _2, a4: &length, a5: &called)); |
688 | ios.reset(); |
689 | ios.run(); |
690 | BOOST_ASIO_CHECK(called); |
691 | BOOST_ASIO_CHECK(!ec); |
692 | BOOST_ASIO_CHECK(length == 25); |
693 | |
694 | s.reset(data: read_data, length: sizeof(read_data)); |
695 | s.next_read_length(length: 10); |
696 | ec = boost::system::error_code(); |
697 | length = 0; |
698 | called = false; |
699 | sb2.consume(n: sb2.size()); |
700 | boost::asio::async_read_until(s, b&: sb2, delim: "WXY" , |
701 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
702 | a3: _2, a4: &length, a5: &called)); |
703 | ios.reset(); |
704 | ios.run(); |
705 | BOOST_ASIO_CHECK(called); |
706 | BOOST_ASIO_CHECK(!ec); |
707 | BOOST_ASIO_CHECK(length == 25); |
708 | |
709 | s.reset(data: read_data, length: sizeof(read_data)); |
710 | sb2.consume(n: sb2.size()); |
711 | int i = boost::asio::async_read_until(s, b&: sb2, delim: "WXY" , |
712 | handler: archetypes::lazy_handler()); |
713 | BOOST_ASIO_CHECK(i == 42); |
714 | ios.reset(); |
715 | ios.run(); |
716 | } |
717 | |
718 | void test_match_condition_async_read_until() |
719 | { |
720 | #if defined(BOOST_ASIO_HAS_BOOST_BIND) |
721 | namespace bindns = boost; |
722 | #else // defined(BOOST_ASIO_HAS_BOOST_BIND) |
723 | namespace bindns = std; |
724 | using std::placeholders::_1; |
725 | using std::placeholders::_2; |
726 | #endif // defined(BOOST_ASIO_HAS_BOOST_BIND) |
727 | |
728 | boost::asio::io_service ios; |
729 | test_stream s(ios); |
730 | boost::asio::streambuf sb1; |
731 | boost::asio::streambuf sb2(25); |
732 | boost::system::error_code ec; |
733 | std::size_t length; |
734 | bool called; |
735 | |
736 | s.reset(data: read_data, length: sizeof(read_data)); |
737 | ec = boost::system::error_code(); |
738 | length = 0; |
739 | called = false; |
740 | sb1.consume(n: sb1.size()); |
741 | boost::asio::async_read_until(s, b&: sb1, match_condition: match_char('Z'), |
742 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
743 | a3: _2, a4: &length, a5: &called)); |
744 | ios.reset(); |
745 | ios.run(); |
746 | BOOST_ASIO_CHECK(called); |
747 | BOOST_ASIO_CHECK(!ec); |
748 | BOOST_ASIO_CHECK(length == 26); |
749 | |
750 | s.reset(data: read_data, length: sizeof(read_data)); |
751 | s.next_read_length(length: 1); |
752 | ec = boost::system::error_code(); |
753 | length = 0; |
754 | called = false; |
755 | sb1.consume(n: sb1.size()); |
756 | boost::asio::async_read_until(s, b&: sb1, match_condition: match_char('Z'), |
757 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
758 | a3: _2, a4: &length, a5: &called)); |
759 | ios.reset(); |
760 | ios.run(); |
761 | BOOST_ASIO_CHECK(called); |
762 | BOOST_ASIO_CHECK(!ec); |
763 | BOOST_ASIO_CHECK(length == 26); |
764 | |
765 | s.reset(data: read_data, length: sizeof(read_data)); |
766 | s.next_read_length(length: 10); |
767 | ec = boost::system::error_code(); |
768 | length = 0; |
769 | called = false; |
770 | sb1.consume(n: sb1.size()); |
771 | boost::asio::async_read_until(s, b&: sb1, match_condition: match_char('Z'), |
772 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
773 | a3: _2, a4: &length, a5: &called)); |
774 | ios.reset(); |
775 | ios.run(); |
776 | BOOST_ASIO_CHECK(called); |
777 | BOOST_ASIO_CHECK(!ec); |
778 | BOOST_ASIO_CHECK(length == 26); |
779 | |
780 | s.reset(data: read_data, length: sizeof(read_data)); |
781 | ec = boost::system::error_code(); |
782 | length = 0; |
783 | called = false; |
784 | sb2.consume(n: sb2.size()); |
785 | boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Z'), |
786 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
787 | a3: _2, a4: &length, a5: &called)); |
788 | ios.reset(); |
789 | ios.run(); |
790 | BOOST_ASIO_CHECK(called); |
791 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
792 | BOOST_ASIO_CHECK(length == 0); |
793 | |
794 | s.reset(data: read_data, length: sizeof(read_data)); |
795 | s.next_read_length(length: 1); |
796 | ec = boost::system::error_code(); |
797 | length = 0; |
798 | called = false; |
799 | sb2.consume(n: sb2.size()); |
800 | boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Z'), |
801 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
802 | a3: _2, a4: &length, a5: &called)); |
803 | ios.reset(); |
804 | ios.run(); |
805 | BOOST_ASIO_CHECK(called); |
806 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
807 | BOOST_ASIO_CHECK(length == 0); |
808 | |
809 | s.reset(data: read_data, length: sizeof(read_data)); |
810 | s.next_read_length(length: 10); |
811 | ec = boost::system::error_code(); |
812 | length = 0; |
813 | called = false; |
814 | sb2.consume(n: sb2.size()); |
815 | boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Z'), |
816 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
817 | a3: _2, a4: &length, a5: &called)); |
818 | ios.reset(); |
819 | ios.run(); |
820 | BOOST_ASIO_CHECK(called); |
821 | BOOST_ASIO_CHECK(ec == boost::asio::error::not_found); |
822 | BOOST_ASIO_CHECK(length == 0); |
823 | |
824 | s.reset(data: read_data, length: sizeof(read_data)); |
825 | ec = boost::system::error_code(); |
826 | length = 0; |
827 | called = false; |
828 | sb2.consume(n: sb2.size()); |
829 | boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Y'), |
830 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
831 | a3: _2, a4: &length, a5: &called)); |
832 | ios.reset(); |
833 | ios.run(); |
834 | BOOST_ASIO_CHECK(called); |
835 | BOOST_ASIO_CHECK(!ec); |
836 | BOOST_ASIO_CHECK(length == 25); |
837 | |
838 | s.reset(data: read_data, length: sizeof(read_data)); |
839 | s.next_read_length(length: 1); |
840 | ec = boost::system::error_code(); |
841 | length = 0; |
842 | called = false; |
843 | sb2.consume(n: sb2.size()); |
844 | boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Y'), |
845 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
846 | a3: _2, a4: &length, a5: &called)); |
847 | ios.reset(); |
848 | ios.run(); |
849 | BOOST_ASIO_CHECK(called); |
850 | BOOST_ASIO_CHECK(!ec); |
851 | BOOST_ASIO_CHECK(length == 25); |
852 | |
853 | s.reset(data: read_data, length: sizeof(read_data)); |
854 | s.next_read_length(length: 10); |
855 | ec = boost::system::error_code(); |
856 | length = 0; |
857 | called = false; |
858 | sb2.consume(n: sb2.size()); |
859 | boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Y'), |
860 | handler: bindns::bind(f: async_read_handler, a1: _1, a2: &ec, |
861 | a3: _2, a4: &length, a5: &called)); |
862 | ios.reset(); |
863 | ios.run(); |
864 | BOOST_ASIO_CHECK(called); |
865 | BOOST_ASIO_CHECK(!ec); |
866 | BOOST_ASIO_CHECK(length == 25); |
867 | |
868 | s.reset(data: read_data, length: sizeof(read_data)); |
869 | sb2.consume(n: sb2.size()); |
870 | int i = boost::asio::async_read_until(s, b&: sb2, match_condition: match_char('Y'), |
871 | handler: archetypes::lazy_handler()); |
872 | BOOST_ASIO_CHECK(i == 42); |
873 | ios.reset(); |
874 | ios.run(); |
875 | } |
876 | |
877 | BOOST_ASIO_TEST_SUITE |
878 | ( |
879 | "read_until" , |
880 | BOOST_ASIO_TEST_CASE(test_char_read_until) |
881 | BOOST_ASIO_TEST_CASE(test_string_read_until) |
882 | BOOST_ASIO_TEST_CASE(test_match_condition_read_until) |
883 | BOOST_ASIO_TEST_CASE(test_char_async_read_until) |
884 | BOOST_ASIO_TEST_CASE(test_string_async_read_until) |
885 | BOOST_ASIO_TEST_CASE(test_match_condition_async_read_until) |
886 | ) |
887 | |