boost::asio
's various read
and write
functions and methods accept boost::asio::buffer
. According to buffer's documentation, a mutable std::string
cannot be wrapped in boost::asio::buffer
, and thus cannot be used for asio's read
functions. This is probably due to the fact that std::string
does not allow mutable access to its internal buffer (this was discussed previously here).
This is a shame, because std::string
is a convenient way to represent mutable buffers of data in C++. Without it, we're either left with POD arrays, boost::array
and std::vector<char>
. The first two are inconvenient with variable-length messages. std::vector<char>
can work, but it's an unnatural way to carry buffers of data around (*)
Questions:
std::string
with boost::asio
for reading buffers? Am I missing something here?std::vector<char>
is supported in a mutable buffer. Is it because it guarantees its internal buffer is contiguous in memory and allows mutable access to it with &vec[0]
?Thanks in advance
(*) IMHO. Look at protobuf
serialization for instance - it offers serialization into std::string
but not into std::vector<char>
, at least not explicitly.
EDIT: I ended up using vector<char>
after all. protobuf
allows serialization into a vector<char>
by means of the SerializeToArray
call which takes a pointer (&vec[0]
can be passed there).
Mutable access to a string buffer using &str[0]
works fine on all known implementations, and the wording of the upcoming C++0x standardizes makes it officially allowed.
Still, I think you're insane to think that a std::vector
is an unnatural representation for a variable-length buffer.
This is to answer Eli's comment
I didn't mention asio::streambuf in my question originally, indeed because it wasn't 100% clear to me how to use it with fixed size reads and asio. Could you point to an example (or add one as an answer) of showing how to read fixed-length chunks into a
std::sstream
?
Here's a previous answer about using asio::streambuf
and Boost.Serialization
. The asio documentation also has an example of a synchronous read:
boost::asio::streambuf b;
// reserve 512 bytes in output sequence
boost::asio::streambuf::mutable_buffers_type bufs = b.prepare(512);
size_t n = sock.receive(bufs);
// received data is "committed" from output sequence to input sequence
b.commit(n);
std::istream is(&b);
std::string s;
is >> s;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With