Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy a streambuf's contents to a string

Apparently boost::asio::async_read doesn't like strings, as the only overload of boost::asio::buffer allows me to create const_buffers, so I'm stuck with reading everything into a streambuf.
Now I want to copy the contents of the streambuf into a string, but it apparently only supports writing to char* (sgetn()), creating an istream with the streambuf and using getline().

Is there any other way to create a string with the streambufs contents without excessive copying?

like image 896
tstenner Avatar asked May 18 '09 13:05

tstenner


2 Answers

I don't know whether it counts as "excessive copying", but you can use a stringstream:

std::ostringstream ss; ss << someStreamBuf; std::string s = ss.str(); 

Like, to read everything from stdin into a string, do

std::ostringstream ss; ss << std::cin.rdbuf(); std::string s = ss.str(); 

Alternatively, you may also use a istreambuf_iterator. You will have to measure whether this or the above way is faster - i don't know.

std::string s((istreambuf_iterator<char>(someStreamBuf)),                 istreambuf_iterator<char>()); 

Note that someStreamBuf above is meant to represent a streambuf*, so take its address as appropriate. Also note the additional parentheses around the first argument in the last example, so that it doesn't interpret it as a function declaration returning a string and taking an iterator and another function pointer ("most vexing parse").

like image 54
Johannes Schaub - litb Avatar answered Oct 09 '22 00:10

Johannes Schaub - litb


It's really buried in the docs...

Given boost::asio::streambuf b, with size_t buf_size ...

boost::asio::streambuf::const_buffers_type bufs = b.data(); std::string str(boost::asio::buffers_begin(bufs),                 boost::asio::buffers_begin(bufs) + buf_size); 
like image 32
Sean DeNigris Avatar answered Oct 08 '22 23:10

Sean DeNigris