4
votes

I am trying to use a std::istream as data source. I want to place custom binary data in the istream's stream buffer so it can later be retrieved from the istream.

I have read about boost::asio::streambuf and how it is used to do exactly what I want but using a socket as data source instead of an in-memory buffer, which is what I would like to use.

From what I understand from the documentation, the steps should be:

  1. Create a boost::asio::streambuf
  2. Create a std::istream passing the streambuf
  3. Invoke boost::asio::streambuf::prepare to get the list of buffers representing the output sequence.
  4. Somehow write in the output sequence.
  5. Invoke boost::asio::streambuf::commit to move what I wrote in the output sequence to the input sequence.
  6. Read from the std::istream from step 2 normally with std::stream::read.

I don't know how to address step 4, so I don't know even if I'm going in the right direction.

Are the depicted steps correct? If so, how to address step 4?

2
@Xeo that's exactly what I want to do but with binary data instead of text. As I understand with stringstream it would not be possible. Am I right? Is there any other stream implementation that could be used for that?noe

2 Answers

6
votes

You can easily send any std stream, so you can also you a stringstream. You can write binary data to your stringstream (it is just a byte array, effectively).

A few samples:

boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream.write(&binarydata_buf, sizeof(binarydata_buf));
// or use stream operators: request_stream << "xxx" << yyy;

// Send the request.
boost::asio::write(socket, request);

If you already have a fully populated istream (using std::cin as dummy in this example):

boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << std::cin.rdbuf() << std::flush;

// Send the request.
boost::asio::write(socket, request);

Ways to populate an istream are e.g. ostream::write or Boost Serialization binary_archive

There are many ways to skin a cat of course, so be sure to think over the other options before blindly copying this.

See How to send ostream via boost sockets in C++?

0
votes

Why not just transmit the data across a socket into your streambuf? If you can link the std::istream to the asio::streambuf which is listening on a particular socket, just use the same socket with boost::asio::write to send it data.

There isn't much penalty to using actual sockets intra-process, rather than trying to simulated it by accessing underlying data structures.