0
votes

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.

3

3 Answers

1
votes

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);
0
votes

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.

0
votes

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