Buffer Composition
Composing buffer sequences without allocation for scatter/gather I/O.
What You Will Learn
-
Creating buffers from different sources
-
Using
const_buffer_pairandmutable_buffer_pairfor scatter/gather I/O -
Zero-allocation buffer sequence patterns
Prerequisites
-
Completed Producer-Consumer
-
Understanding of buffer types from Buffer Types
Source Code
#include <boost/capy.hpp>
#include <iostream>
#include <string>
#include <array>
#include <vector>
using namespace boost::capy;
void demonstrate_single_buffers()
{
std::cout << "=== Single Buffer Examples ===\n\n";
// Create buffers from various sources
std::string str = "Hello, World!";
char arr[] = "Array data";
std::vector<char> vec = {'V', 'e', 'c', 't', 'o', 'r'};
// make_buffer creates buffer views (no copies)
auto str_buf = make_buffer(str); // mutable_buffer
auto arr_buf = make_buffer(arr, sizeof(arr) - 1); // mutable_buffer - Exclude null terminator
auto vec_buf = make_buffer(vec); // mutable_buffer
std::cout << "String buffer: " << str_buf.size() << " bytes\n";
std::cout << "Array buffer: " << arr_buf.size() << " bytes\n";
std::cout << "Vector buffer: " << vec_buf.size() << " bytes\n";
}
void demonstrate_buffer_pair()
{
std::cout << "\n=== Buffer Pair (Scatter/Gather) ===\n\n";
// const_buffer_pair is std::array<const_buffer, 2>
std::string header = "Content-Type: text/plain\r\n\r\n";
std::string body = "Hello, World!";
const_buffer_pair message = {{
make_buffer(header),
make_buffer(body)
}};
// Calculate total size
std::size_t total = buffer_size(message);
std::cout << "Total message size: " << total << " bytes\n";
std::cout << "Buffer count: " << buffer_length(message) << "\n";
// Iterate through buffers
std::cout << "\nBuffer contents:\n";
for (auto const& buf : message) // const_buffer const&
{
std::cout << " [" << buf.size() << " bytes]: ";
std::cout.write(static_cast<char const*>(buf.data()), buf.size());
std::cout << "\n";
}
}
void demonstrate_buffer_array()
{
std::cout << "\n=== Multi-Buffer Array ===\n\n";
// Use std::array for more than 2 buffers
std::string status = "HTTP/1.1 200 OK\r\n";
std::string content_type = "Content-Type: application/json\r\n";
std::string server = "Server: Capy/1.0\r\n";
std::string empty_line = "\r\n";
std::string body = R"({"status":"ok"})";
std::array<const_buffer, 5> http_response = {{
make_buffer(status),
make_buffer(content_type),
make_buffer(server),
make_buffer(empty_line),
make_buffer(body)
}};
std::size_t total = buffer_size(http_response);
std::cout << "HTTP response size: " << total << " bytes\n";
std::cout << "Buffer count: " << buffer_length(http_response) << "\n";
// In real code with streams:
// co_await write(stream, http_response);
// This performs scatter/gather I/O - single syscall for all buffers
}
void demonstrate_mutable_buffers()
{
std::cout << "\n=== Mutable Buffer Example ===\n\n";
// Mutable buffers for receiving data
char buf1[64];
char buf2[64];
mutable_buffer_pair recv_buffers = {{
mutable_buffer(buf1, sizeof(buf1)),
mutable_buffer(buf2, sizeof(buf2))
}};
std::cout << "Prepared " << buffer_length(recv_buffers)
<< " buffers with " << buffer_size(recv_buffers)
<< " bytes total capacity\n";
// In real code:
// auto [ec, n] = co_await stream.read_some(recv_buffers);
}
int main()
{
demonstrate_single_buffers();
demonstrate_buffer_pair();
demonstrate_buffer_array();
demonstrate_mutable_buffers();
return 0;
}
Build
add_executable(buffer_composition buffer_composition.cpp)
target_link_libraries(buffer_composition PRIVATE capy)
Walkthrough
Creating Buffers
auto str_buf = make_buffer(str); // mutable_buffer
auto arr_buf = make_buffer(arr, sizeof(arr) - 1); // mutable_buffer
make_buffer creates buffer views from various sources. No data is copied—the buffers reference the original storage.
Buffer Pairs
const_buffer_pair message = {{
make_buffer(header),
make_buffer(body)
}};
const_buffer_pair is std::array<const_buffer, 2> — a fixed-size buffer sequence for scatter/gather I/O. Similarly, mutable_buffer_pair holds two mutable buffers.
Output
=== Single Buffer Examples ===
String buffer: 13 bytes
Array buffer: 10 bytes
Vector buffer: 6 bytes
=== Buffer Pair (Scatter/Gather) ===
Total message size: 41 bytes
Buffer count: 2
Buffer contents:
[28 bytes]: Content-Type: text/plain
[13 bytes]: Hello, World!
=== Multi-Buffer Array ===
HTTP response size: 84 bytes
Buffer count: 5
=== Mutable Buffer Example ===
Prepared 2 buffers with 128 bytes total capacity
Exercises
-
Create a function that takes any
ConstBufferSequenceand prints its contents -
Measure the difference between copying data into a single buffer vs. using
cat() -
Implement a simple message framing protocol using buffer composition
Next Steps
-
Mock Stream Testing — Unit testing with mock streams