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);
Rate this post:
Lesson 20
Lesson 22
Share this page:

Learning plan

How to deal with completion handlers manually to combine Boost.Asio with other APIs
Let's take a break and briefly look across everything we've learned so far
A closer look on how to pass data views into Boost.Asio functions
21. Buffer sequence, part 2
How to operate on the underlying buffer sequence data with Boost.Asio free functions
How to read data from Boost.Asio dynamic buffers
How to work with Boost.Asio dynamic buffers manually
Let's briefly summarize everything we've learned about different Boost.Asio buffers