Implementation:CARLA simulator Carla Buffer
| Knowledge Sources | |
|---|---|
| Domains | Networking, Memory Management |
| Last Updated | 2026-02-15 05:00 GMT |
Overview
Buffer is a move-only raw data container in LibCarla that manages dynamically allocated byte arrays with optional integration into a BufferPool for memory reuse.
Description
The Buffer class provides a lightweight, move-only wrapper around a contiguous block of raw bytes (unsigned char). It is designed to be cheap to pass by value through move semantics, as copy construction and copy assignment are explicitly deleted.
Key characteristics of the Buffer class include:
- Grow-only semantics: When more capacity is needed, a new memory block is allocated and the old one is discarded. The buffer can only grow unless explicitly cleared via clear() or pop().
- BufferPool integration: If a Buffer was originally obtained from a BufferPool, the memory is automatically returned to the pool upon destruction via ReuseThisBuffer(), enabling efficient memory recycling in high-throughput scenarios.
- Boost.Asio compatibility: The class provides cbuffer() and buffer() methods that return boost::asio::const_buffer and boost::asio::mutable_buffer objects, enabling seamless integration with asynchronous I/O operations.
- UE4 interoperability: When compiled with LIBCARLA_INCLUDED_FROM_UE4, the class supports copying data from Unreal Engine TArray types.
- Template-based copy_from: Multiple overloaded copy_from methods accept raw pointers, Boost.Asio buffer sequences, and generic types, allowing flexible data ingestion with optional offset.
The class uses uint32_t as its size_type, limiting the maximum buffer size to approximately 4 GB. Creating a buffer larger than max_size() results in undefined behavior or an exception.
Usage
Use Buffer when you need to transport raw binary data between CARLA components, especially across the network layer. It is the primary data container for serialized messages exchanged between the CARLA client and server via boost::asio. Retrieve buffers from a BufferPool in performance-critical paths such as sensor data streaming to avoid repeated heap allocations.
Code Reference
Source Location
- Repository: CARLA
- File:
LibCarla/source/carla/Buffer.h - Lines: 1-375
Signature
namespace carla {
class Buffer {
public:
using value_type = unsigned char;
using size_type = uint32_t;
using iterator = value_type *;
using const_iterator = const value_type *;
Buffer() = default;
explicit Buffer(size_type size);
explicit Buffer(uint64_t size);
template <typename T> explicit Buffer(const T &source);
explicit Buffer(const value_type *data, size_type size);
Buffer(const Buffer &) = delete;
Buffer(Buffer &&rhs) noexcept;
~Buffer();
Buffer &operator=(const Buffer &) = delete;
Buffer &operator=(Buffer &&rhs) noexcept;
// Data access
const value_type &operator[](size_t i) const;
value_type &operator[](size_t i);
const value_type *data() const noexcept;
value_type *data() noexcept;
boost::asio::const_buffer cbuffer() const noexcept;
boost::asio::const_buffer buffer() const noexcept;
boost::asio::mutable_buffer buffer() noexcept;
// Capacity
bool empty() const noexcept;
size_type size() const noexcept;
static constexpr size_type max_size() noexcept;
size_type capacity() const noexcept;
// Iterators
const_iterator cbegin() const noexcept;
const_iterator begin() const noexcept;
iterator begin() noexcept;
const_iterator cend() const noexcept;
const_iterator end() const noexcept;
iterator end() noexcept;
// Modifiers
void reset(size_type size);
void reset(uint64_t size);
void resize(uint64_t size);
std::unique_ptr<value_type[]> pop() noexcept;
void clear() noexcept;
// Copy operations
template <typename T> void copy_from(const T &source);
void copy_from(const value_type *data, size_type size);
void copy_from(size_type offset, const Buffer &rhs);
void copy_from(size_type offset, const value_type *data, size_type size);
private:
void ReuseThisBuffer();
std::weak_ptr<BufferPool> _parent_pool;
size_type _size = 0u;
size_type _capacity = 0u;
std::unique_ptr<value_type[]> _data = nullptr;
};
} // namespace carla
Import
#include "carla/Buffer.h"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| size | size_type or uint64_t |
No | Initial size in bytes for the buffer allocation |
| data | const value_type * |
No | Pointer to raw data to copy into the buffer |
| source | const T & (template) |
No | A Boost.Asio-compatible buffer sequence or copyable data source |
| offset | size_type |
No | Byte offset at the front of the buffer to leave uninitialized during copy |
Outputs
| Name | Type | Description |
|---|---|---|
| data() | const value_type * / value_type * |
Direct pointer to the underlying allocated memory |
| buffer() | boost::asio::const_buffer / boost::asio::mutable_buffer |
Boost.Asio buffer view over the data |
| pop() | std::unique_ptr<value_type[]> |
Releases ownership of the internal data and resets the buffer to empty |
Usage Examples
Basic Usage
#include "carla/Buffer.h"
// Create a buffer with a specific size
carla::Buffer buf(1024u);
// Access the raw data pointer
unsigned char *ptr = buf.data();
ptr[0] = 0xAB;
// Check size and capacity
assert(buf.size() == 1024u);
assert(!buf.empty());
Copying Data into a Buffer
#include "carla/Buffer.h"
// Copy from raw pointer
const unsigned char payload[] = {0x01, 0x02, 0x03, 0x04};
carla::Buffer buf;
buf.copy_from(payload, 4u);
// Copy with offset (leaves first 8 bytes uninitialized)
carla::Buffer buf2;
buf2.copy_from(8u, payload, 4u);
assert(buf2.size() == 12u);
Using with Boost.Asio
#include "carla/Buffer.h"
#include <boost/asio.hpp>
carla::Buffer buf(256u);
// Get a mutable asio buffer for async_read
boost::asio::mutable_buffer asio_buf = buf.buffer();
// Get a const asio buffer for async_write
boost::asio::const_buffer const_buf = buf.cbuffer();