44 explicit PacketBuffer(
const std::vector<uint8_t> &vec) : pre_buffer_(vec.data()), pre_length_(vec.
size()) {}
51 PacketBuffer(
const uint8_t *pre_data,
size_t pre_length,
const uint8_t *post_data,
size_t post_length)
52 : pre_buffer_(pre_data), pre_length_(pre_length), post_buffer_(post_data), post_length_(post_length) {}
59 : pre_buffer_(pre_data),
60 pre_length_(pre_length),
61 mid_buffer_(mid_buffer),
62 post_buffer_(post_data),
63 post_length_(post_length) {}
69 size_t total = this->pre_length_ + this->post_length_;
70 if (this->mid_buffer_ !=
nullptr) {
71 total += this->mid_buffer_->
size();
84 bool is_contiguous()
const {
return this->mid_buffer_ ==
nullptr && this->post_length_ == 0; }
89 std::span<const uint8_t>
as_span()
const {
return {this->pre_buffer_, this->pre_length_}; }
97 if (index < this->pre_length_) {
98 return this->pre_buffer_[index];
100 index -= this->pre_length_;
102 if (this->mid_buffer_ !=
nullptr) {
103 size_t mid_size = this->mid_buffer_->
size();
104 if (index < mid_size) {
105 return (*this->mid_buffer_)[index];
110 return index < this->post_length_ ? this->post_buffer_[index] : 0;
121 size_t total_size = this->
size();
122 if (offset >= total_size) {
126 size_t available = total_size - offset;
127 size_t to_copy =
count < available ?
count : available;
131 if (offset < this->pre_length_) {
132 size_t pre_offset = offset;
133 size_t pre_available = this->pre_length_ - pre_offset;
134 size_t pre_copy = to_copy < pre_available ? to_copy : pre_available;
135 std::memcpy(dest, this->pre_buffer_ + pre_offset, pre_copy);
142 size_t mid_size = this->mid_buffer_ !=
nullptr ? this->mid_buffer_->
size() : 0;
143 if (copied < to_copy && offset < this->pre_length_ + mid_size) {
144 size_t mid_offset = offset - this->pre_length_;
145 size_t mid_available = mid_size - mid_offset;
146 size_t mid_copy = (to_copy - copied) < mid_available ? (to_copy - copied) : mid_available;
147 this->mid_buffer_->
copy_to(dest, mid_copy, mid_offset);
154 if ((copied < to_copy) && (this->post_length_ > 0)) {
155 size_t post_offset = offset - this->pre_length_ - mid_size;
156 size_t post_available = this->post_length_ - post_offset;
157 size_t post_copy = (to_copy - copied) < post_available ? (to_copy - copied) : post_available;
158 std::memcpy(dest, this->post_buffer_ + post_offset, post_copy);
166 const uint8_t *pre_buffer_{
nullptr};
167 size_t pre_length_{0};
169 const uint8_t *post_buffer_{
nullptr};
170 size_t post_length_{0};
A buffer class that efficiently represents a composite buffer with three sections:
PacketBuffer & operator=(const PacketBuffer &)=delete
size_t copy_to(uint8_t *dest, size_t count, size_t offset=0) const
Copy data from the buffer to a destination pointer.
std::span< const uint8_t > as_span() const
Get the data as one span.
PacketBuffer(std::vector< uint8_t > &&)=delete
PacketBuffer(const PacketBuffer &)=delete
PacketBuffer & operator=(PacketBuffer &&)=default
PacketBuffer(const uint8_t *pre_data, size_t pre_length, const uint8_t *post_data, size_t post_length)
Construct with pre and post buffers.
size_t size() const
Get the total size of the buffer.
PacketBuffer(const uint8_t *data, size_t length)
Construct from a single buffer.
PacketBuffer(const std::vector< uint8_t > &vec)
Construct from a vector.
uint8_t operator[](size_t index) const
Access a byte at a specific position.
bool empty() const
Check if the buffer is empty.
PacketBuffer(const uint8_t *pre_data, size_t pre_length, const PacketBuffer *mid_buffer, const uint8_t *post_data, size_t post_length)
Construct with pre, mid, and post buffers.
bool is_contiguous() const
Check if all the data is held in the pre-buffer, so it can be read as one span.
PacketBuffer(PacketBuffer &&)=default