Buffer sequence, part 2
It's time to learn a few new functions to operate on buffer sequences. In the previous lesson we've constructed buffer sequences from our own data pieces so it was obvious how to access the data of the buffer sequence or how to calculate its size. However you could deal with a given buffer sequence when the underlying memory buffers are hidden from you. You should know how to access the data in a buffer sequence in such cases.
To get total size of the memory pointed by the buffer sequence use buffer_size
free function:
auto seq = client.get_buffer_sequence(); // Some third-party function giving you a buffer sequence
std::size_t total_size = boost::asio::buffer_size(seq);
Remember that buffer sequence is a set of different buffer views. It means that in general the underlying memory block isn't contiguous, but represented as different memory blocks scattered around.
To iterate over each buffer view in the sequence use buffer_sequence_begin
and buffer_sequence_end
functions:
auto seq = client.get_buffer_sequence();
auto begin = boost::asio::buffer_sequence_begin(seq);
auto end = boost::asio::buffer_sequence_end(seq);
for(auto it = begin; it != end; ++it)
{
// *it is a single buffer view here
}
However usually you can just pass buffer sequence into range-based for loop:
for(auto view : client.get_buffer_sequence())
{
// view is a single buffer view here
}
Dealing with each buffer view from the sequence isn't really convenient. You can iterate over the whole sequence per-byte at once with buffer_iterator
given by buffers_begin
and buffers_end
free functions:
auto seq = client.get_buffer_sequence();
auto begin = boost::asio::buffer_begin(seq);
auto end = boost::asio::buffer_end(seq);
for(auto it = begin; it != end; ++it)
{
// *it is not a buffer view but a byte here
}
The buffer_iterator
“knows” about the pieces of which the sequence consists of, so it jumps from one piece to another while iterating, so no need to worry about going out of bounds of some particular buffer view.
And the last thing you should learn in this lesson is how to copy data from one buffer sequence into another. Of course, you can do this manually since you're already know how to iterate over buffer views and how to access the memory of a particular buffer view. However there are already ready-to-use free functions for that in Boost.Asio:
// Returns ConstBufferSequence concept instance
auto source = some_source_buffer_sequence();
// Returns MutableBufferSequence concept instance
auto target = some_target_buffer_sequence();
// Just like that!
boost::asio::buffer_copy(target, source);
If you need to limit maximum bytes to copy then use three parameters overload:
boost::asio::buffer_copy(target, source, 1024);