Fix problem in read_until's match_condition handling when the delimiter

lies at the end of the data.
This commit is contained in:
chris_kohlhoff 2008-10-29 12:23:51 +00:00
parent f74b229a41
commit eafc4262dc
2 changed files with 267 additions and 39 deletions

View File

@ -277,19 +277,16 @@ std::size_t read_until(SyncReadStream& s,
// Look for a match.
std::pair<iterator, bool> result = match_condition(start, end);
if (result.first != end)
if (result.second)
{
if (result.second)
{
// Full match. We're done.
ec = asio::error_code();
return result.first - begin;
}
else
{
// Partial match. Next search needs to start from beginning of match.
next_search_start = result.first - begin;
}
// Full match. We're done.
ec = asio::error_code();
return result.first - begin;
}
else if (result.first != end)
{
// Partial match. Next search needs to start from beginning of match.
next_search_start = result.first - begin;
}
else
{
@ -857,20 +854,17 @@ namespace detail
// Look for a match.
std::pair<iterator, bool> result = match_condition_(start, end);
if (result.first != end)
if (result.second)
{
if (result.second)
{
// Full match. We're done.
std::size_t bytes = result.first - begin;
handler_(ec, bytes);
return;
}
else
{
// Partial match. Next search needs to start from beginning of match.
next_search_start_ = result.first - begin;
}
// Full match. We're done.
std::size_t bytes = result.first - begin;
handler_(ec, bytes);
return;
}
else if (result.first != end)
{
// Partial match. Next search needs to start from beginning of match.
next_search_start_ = result.first - begin;
}
else
{
@ -950,21 +944,18 @@ void async_read_until(AsyncReadStream& s,
// Look for a match.
std::size_t next_search_start;
std::pair<iterator, bool> result = match_condition(begin, end);
if (result.first != end)
if (result.second)
{
if (result.second)
{
// Full match. We're done.
asio::error_code ec;
std::size_t bytes = result.first - begin;
s.get_io_service().post(detail::bind_handler(handler, ec, bytes));
return;
}
else
{
// Partial match. Next search needs to start from beginning of match.
next_search_start = result.first - begin;
}
// Full match. We're done.
asio::error_code ec;
std::size_t bytes = result.first - begin;
s.get_io_service().post(detail::bind_handler(handler, ec, bytes));
return;
}
else if (result.first != end)
{
// Partial match. Next search needs to start from beginning of match.
next_search_start = result.first - begin;
}
else
{

View File

@ -121,52 +121,81 @@ void test_char_read_until()
asio::error_code ec;
s.reset(read_data, sizeof(read_data));
sb1.consume(sb1.size());
std::size_t length = asio::read_until(s, sb1, 'Z');
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, 'Z');
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, 'Z');
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, 'Z', ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, 'Z', ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, 'Z', ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, 'Z', ec);
BOOST_CHECK(ec == asio::error::not_found);
BOOST_CHECK(length == 0);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, 'Z', ec);
BOOST_CHECK(ec == asio::error::not_found);
BOOST_CHECK(length == 0);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, 'Z', ec);
BOOST_CHECK(ec == asio::error::not_found);
BOOST_CHECK(length == 0);
s.reset(read_data, sizeof(read_data));
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, 'Y', ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, 'Y', ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, 'Y', ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
}
void test_string_read_until()
@ -178,52 +207,81 @@ void test_string_read_until()
asio::error_code ec;
s.reset(read_data, sizeof(read_data));
sb1.consume(sb1.size());
std::size_t length = asio::read_until(s, sb1, "XYZ");
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, "XYZ");
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, "XYZ");
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, "XYZ", ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, "XYZ", ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, "XYZ", ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, "XYZ", ec);
BOOST_CHECK(ec == asio::error::not_found);
BOOST_CHECK(length == 0);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, "XYZ", ec);
BOOST_CHECK(ec == asio::error::not_found);
BOOST_CHECK(length == 0);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, "XYZ", ec);
BOOST_CHECK(ec == asio::error::not_found);
BOOST_CHECK(length == 0);
s.reset(read_data, sizeof(read_data));
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, "WXY", ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, "WXY", ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, "WXY", ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
}
class match_char
@ -260,52 +318,81 @@ void test_match_condition_read_until()
asio::error_code ec;
s.reset(read_data, sizeof(read_data));
sb1.consume(sb1.size());
std::size_t length = asio::read_until(s, sb1, match_char('Z'));
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, match_char('Z'));
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, match_char('Z'));
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, match_char('Z'), ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, match_char('Z'), ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
sb1.consume(sb1.size());
length = asio::read_until(s, sb1, match_char('Z'), ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 26);
s.reset(read_data, sizeof(read_data));
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, match_char('Z'), ec);
BOOST_CHECK(ec == asio::error::not_found);
BOOST_CHECK(length == 0);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, match_char('Z'), ec);
BOOST_CHECK(ec == asio::error::not_found);
BOOST_CHECK(length == 0);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, match_char('Z'), ec);
BOOST_CHECK(ec == asio::error::not_found);
BOOST_CHECK(length == 0);
s.reset(read_data, sizeof(read_data));
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, match_char('Y'), ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, match_char('Y'), ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
sb2.consume(sb2.size());
length = asio::read_until(s, sb2, match_char('Y'), ec);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
}
void async_read_handler(
@ -331,6 +418,7 @@ void test_char_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb1.consume(sb1.size());
asio::async_read_until(s, sb1, 'Z',
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -345,6 +433,7 @@ void test_char_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb1.consume(sb1.size());
asio::async_read_until(s, sb1, 'Z',
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -359,6 +448,7 @@ void test_char_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb1.consume(sb1.size());
asio::async_read_until(s, sb1, 'Z',
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -372,6 +462,7 @@ void test_char_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, 'Z',
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -386,6 +477,7 @@ void test_char_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, 'Z',
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -400,6 +492,7 @@ void test_char_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, 'Z',
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -408,6 +501,50 @@ void test_char_async_read_until()
BOOST_CHECK(called);
BOOST_CHECK(ec == asio::error::not_found);
BOOST_CHECK(length == 0);
s.reset(read_data, sizeof(read_data));
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, 'Y',
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
ios.reset();
ios.run();
BOOST_CHECK(called);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, 'Y',
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
ios.reset();
ios.run();
BOOST_CHECK(called);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, 'Y',
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
ios.reset();
ios.run();
BOOST_CHECK(called);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
}
void test_string_async_read_until()
@ -424,6 +561,7 @@ void test_string_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb1.consume(sb1.size());
asio::async_read_until(s, sb1, "XYZ",
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -438,6 +576,7 @@ void test_string_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb1.consume(sb1.size());
asio::async_read_until(s, sb1, "XYZ",
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -452,6 +591,7 @@ void test_string_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb1.consume(sb1.size());
asio::async_read_until(s, sb1, "XYZ",
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -465,6 +605,7 @@ void test_string_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, "XYZ",
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -479,6 +620,7 @@ void test_string_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, "XYZ",
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -493,6 +635,7 @@ void test_string_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, "XYZ",
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -501,6 +644,50 @@ void test_string_async_read_until()
BOOST_CHECK(called);
BOOST_CHECK(ec == asio::error::not_found);
BOOST_CHECK(length == 0);
s.reset(read_data, sizeof(read_data));
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, "WXY",
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
ios.reset();
ios.run();
BOOST_CHECK(called);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, "WXY",
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
ios.reset();
ios.run();
BOOST_CHECK(called);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, "WXY",
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
ios.reset();
ios.run();
BOOST_CHECK(called);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
}
void test_match_condition_async_read_until()
@ -517,6 +704,7 @@ void test_match_condition_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb1.consume(sb1.size());
asio::async_read_until(s, sb1, match_char('Z'),
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -531,6 +719,7 @@ void test_match_condition_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb1.consume(sb1.size());
asio::async_read_until(s, sb1, match_char('Z'),
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -545,6 +734,7 @@ void test_match_condition_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb1.consume(sb1.size());
asio::async_read_until(s, sb1, match_char('Z'),
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -558,6 +748,7 @@ void test_match_condition_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, match_char('Z'),
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -572,6 +763,7 @@ void test_match_condition_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, match_char('Z'),
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -586,6 +778,7 @@ void test_match_condition_async_read_until()
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, match_char('Z'),
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
@ -594,6 +787,50 @@ void test_match_condition_async_read_until()
BOOST_CHECK(called);
BOOST_CHECK(ec == asio::error::not_found);
BOOST_CHECK(length == 0);
s.reset(read_data, sizeof(read_data));
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, match_char('Y'),
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
ios.reset();
ios.run();
BOOST_CHECK(called);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
s.reset(read_data, sizeof(read_data));
s.next_read_length(1);
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, match_char('Y'),
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
ios.reset();
ios.run();
BOOST_CHECK(called);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
s.reset(read_data, sizeof(read_data));
s.next_read_length(10);
ec = asio::error_code();
length = 0;
called = false;
sb2.consume(sb2.size());
asio::async_read_until(s, sb2, match_char('Y'),
boost::bind(async_read_handler, asio::placeholders::error, &ec,
asio::placeholders::bytes_transferred, &length, &called));
ios.reset();
ios.run();
BOOST_CHECK(called);
BOOST_CHECK(!ec);
BOOST_CHECK(length == 25);
}
test_suite* init_unit_test_suite(int, char*[])