Reputation: 313
What's the easiest way to implement a version of boost::asio::async_read_until that only reads until the delimiter is found? Can I implement a special match condition that knows how to consume the proper amount of bytes? If not, then how to I write an async reader that checks each byte?
I need to stop the provided streambuf from consuming bytes beyond the delimiter.
Upvotes: 0
Views: 2609
Reputation: 133
I'd like to point out that the REMARK in this document is actually incorrect, no matter how many times I test it.
Remarks After a successful async_read_until operation, the streambuf may contain additional data beyond that which matched the function object. An application will typically leave that data in the streambuf for a subsequent async_read_until operation to examine.
MatchCondition functor should consume all that there is in the streambuf, do not leave unconsumed bytes for the next async_read_until() call or your application may wait forever.
p.s. testing setup is x86-64 centos4.3 kernel-2.6.32 gcc4.8
Upvotes: 0
Reputation: 67128
In the documentation you can find a simple match function:
std::pair<iterator, bool>
match_whitespace(iterator begin, iterator end)
{
iterator i = begin;
while (i != end)
if (std::isspace(*i++))
return std::make_pair(i, true);
return std::make_pair(i, false);
}
In this case it matches any whitespace (change std::isspace according to what you want). Again in that documentation you can see a more complex event, it consumes the stream until it finds a specific character:
class match_char
{
public:
explicit match_char(char c) : c_(c) {}
template <typename Iterator>
std::pair<Iterator, bool> operator()(
Iterator begin, Iterator end) const
{
Iterator i = begin;
while (i != end)
if (c_ == *i++)
return std::make_pair(i, true);
return std::make_pair(i, false);
}
private:
char c_;
};
And the code to use that class:
// Function used for error handling
void handler(const boost::system::error_code& e, std::size_t size)
{
// Do something
}
// Example of call, it reads from inputStream to outputStreamBuff
// until the specified delimiter (";") is found
boost::asio::async_read_until(inputStream, outputStreamBuff,
match_char(';'), handler);
Upvotes: 1
Reputation: 24174
I need to stop the provided streambuf from consuming bytes beyond the delimiter.
The only way to accomplish this is to (inefficiently) read a single byte at a time from the stream. I wouldn't suggest this approach, the documentation readily describes how to handle this scenario
After a successful async_read_until operation, the streambuf may contain additional data beyond the delimiter. An application will typically leave that data in the streambuf for a subsequent async_read_until operation to examine.
which is exactly what the async http client example does.
Upvotes: 1