Boost::Asio read_until and streambuf usage

I have a server that sends three lines, each of which have to be parsed independently. I am using read_until but have a problem with its usage. When read_until reads once, the streambuf seems to contain the three lines but not in the istream and only when I call read_until several times, I get the lines. I am wondering how can I safely read_until the buffer is empty (the 3 or more lines are read) and then exit the loop. boost::asio::streambuf buf; while( 1 ) { size_t reply_length = boost::asio::read_until( socket_, buf, '\n' ); std::istream is(&buf); std::string reply; std::getline(is, reply); // only 1 line obtained }

I have a server that sends three lines, each of which have to be parsed independently. I am using read_until but have a problem with its usage. When read_until reads once, the streambuf seems to contain the three lines but not in the istream and only when I call read_until several times, I get the lines. I am wondering how can I safely read_until the buffer is empty (the 3 or more lines are read) and then exit the loop.
boost::asio::streambuf buf;
while( 1 )
{ size_t reply_length = boost::asio::read_until( socket_, buf, '\n' );
std::istream is(&buf); std::string reply; std::getline(is, reply); // only 1 line obtained
}
Do you expect std::getline to give you more than 1 line?

Do you expect std::getline to give you more than 1 line? No, sorry I was not clear. I expect the streambuf or read_until to have some way of telling me there's more lines to read. With that piece of code, the streambuf swallows multiple lines, but getline only gets to
On 21/11/12 14:56, Igor R wrote: the first line. Only when read_until is run again, the other lines appear. I need to poll? the socket for more data, but not sure how that is done in asio.

Do you expect std::getline to give you more than 1 line?
No, sorry I was not clear. I expect the streambuf or read_until to have some way of telling me there's more lines to read. With that piece of code, the streambuf swallows multiple lines, but getline only gets to the first line. Only when read_until is run again, the other lines appear. I need to poll? the socket for more data, but not sure how that is done in asio.
The point is that read_until() may read *more* data than you asked, but std::getline() always extracts chars until it encounters eol or until error occurs. So you can iterate over getline() until error in the istream state -- the last extracted string would be incomplete, so it should be appended by the next result of read_until. Alternatively, you can scan the streambuf contents manually, find eol's and split the whole input as you wish.

Il 22/11/2012 19:38, Gonzalo Garramuno ha scritto:
Do you expect std::getline to give you more than 1 line? No, sorry I was not clear. I expect the streambuf or read_until to have some way of telling me there's more lines to read. With that piece of code, the streambuf swallows multiple lines, but getline only gets to
On 21/11/12 14:56, Igor R wrote: the first line. Only when read_until is run again, the other lines appear. I need to poll? the socket for more data, but not sure how that is done in asio.
This is not the way read_until works. The problem is that it can have
read more data thant what is until the "\n", but it only committed
reply_length bytes. Thus you should do something like the following
typedef boost::asio::streambuf::const_buffers_type buffer_type;
typedef boost::asio::buffers_iterator
participants (3)
-
Gonzalo Garramuno
-
Igor R
-
Leo Cacciari