I’m writing a server application using boost::asio.
I am reading known amount of data from user and write it to a data sink which has following api:
class Sink {
...
void write(const char *data, size_t size);
}
The data is big and it is possible to call write(..) multiple times to process one stream.
In my code I would like to call:
boost::asio::async_read(socket, sink_buffer,
boost::asio::transfer_exactly(size), ...);
Is it possible to wrap Sink with custom std::streambuf or boost::asio::basic_streambuf so it could handle writing data parts to it?
For objects being passed as the buffers argument for
async_read(), the buffers argument either :MutableBufferSequencerequirement.boost::asio::basic_streambufobject.Thus, it is possible to write a custom class that interacts with a
Sinkobject when reading occurs. However, theboost::asio::basic_streambufdoes not appear to be designed to serve as a base class.If
Sink::writeis only an abstraction to the underlying memory, consider using an approach similar tobasic_streambuf::prepare(), where a member function returns a handle to a buffer for a given size. The underlying memory implementation would still remain abstracted behind themutable_buffer. For example:If
Sink::writehas business logic, such as performing logic branching based on the value of certain bytes, then it may be required to pass an intermediate buffer toasync_read(). The invocation ofSink::write()with the intermediate buffer would then be done from withinasync_read()‘s handler. For example:And begin the async read loop with:
Make sure to check and handle error based on your desired logic.