Buffer Types
This page covers the fundamental buffer types and the make_buffer helper
for creating buffers from common data structures.
Code snippets assume using namespace boost::capy; is in effect.
|
const_buffer and mutable_buffer
Capy provides two buffer types representing contiguous memory regions:
| Type | Description |
|---|---|
|
Read-only view of contiguous bytes |
|
Writable view of contiguous bytes |
Both are lightweight (pointer + size) and do not own memory.
const_buffer
A const_buffer represents memory that can be read but not modified:
char const data[] = "Hello, World!";
const_buffer buf(data, sizeof(data) - 1);
void const* p = buf.data(); // Pointer to first byte
std::size_t n = buf.size(); // Number of bytes (13)
Use const_buffer when:
-
Sending data over a network
-
Writing to a file
-
Passing data to any operation that only reads
mutable_buffer
A mutable_buffer represents memory that can be written:
char data[1024];
mutable_buffer buf(data, sizeof(data));
void* p = buf.data(); // Pointer to first byte
std::size_t n = buf.size(); // Number of bytes (1024)
Use mutable_buffer when:
-
Receiving data from a network
-
Reading from a file
-
Any operation that writes into the buffer
Creating Buffers with make_buffer
The make_buffer function creates buffers from common types without
manual pointer/size calculation.
From Pointer and Size
#include <boost/capy/buffers/make_buffer.hpp>
char data[1024];
auto mb = make_buffer(data, sizeof(data)); // mutable_buffer
auto cb = make_buffer("Hello", 5); // const_buffer
From C Arrays
char storage[256];
auto mb = make_buffer(storage); // mutable_buffer, size 256
char const message[] = "Hello";
auto cb = make_buffer(message); // const_buffer, size 6 (includes null)
From std::array
std::array<char, 64> arr;
auto mb = make_buffer(arr); // mutable_buffer, size 64
std::array<char, 64> const carr = { /* ... */ };
auto cb = make_buffer(carr); // const_buffer, size 64
From std::vector
std::vector<unsigned char> vec(1024);
auto mb = make_buffer(vec); // mutable_buffer
std::vector<unsigned char> const cvec = { 0x01, 0x02, 0x03 };
auto cb = make_buffer(cvec); // const_buffer, size 3
Using Buffers with I/O
Buffers become useful when combined with stream operations.
Reading Data
task<void> receive_message(ReadStream auto& stream)
{
char header[4];
auto [ec, n] = co_await read(stream, mutable_buffer(header, 4));
if (ec.failed())
co_return;
// Parse length from header
std::uint32_t len = parse_length(header);
// Read the body
std::vector<char> body(len);
auto [ec2, n2] = co_await read(stream, make_buffer(body));
if (ec2.failed())
co_return;
process_message(body);
}
Writing Data
task<void> send_response(WriteStream auto& stream, std::string_view body)
{
// Write headers
std::string headers = "HTTP/1.1 200 OK\r\nContent-Length: "
+ std::to_string(body.size()) + "\r\n\r\n";
auto [ec1, n1] = co_await write(stream, make_buffer(headers));
if (ec1.failed())
co_return;
// Write body
auto [ec2, n2] = co_await write(stream, make_buffer(body));
}
Partial Operations
The read_some and write_some methods may transfer fewer bytes than
requested. Use them when you want to process data as it arrives:
task<void> echo_loop(ReadStream auto& in, WriteStream auto& out)
{
char buffer[4096];
for (;;)
{
auto [ec1, n] = co_await in.read_some(make_buffer(buffer));
if (ec1 == cond::eof)
break;
if (ec1.failed())
co_return;
auto [ec2, written] = co_await write(out, make_buffer(buffer, n));
if (ec2.failed())
co_return;
}
}
Summary
| Type | Purpose |
|---|---|
|
Read-only view for sending/writing data |
|
Writable view for receiving/reading data |
|
Create buffers from arrays, vectors, strings, and more |