[api] Outline ProtoByteBuffer reallocation into grow_()

The capacity check in reserve()/resize() is the hot path and stays
inline. The actual reallocation (make_buffer + memcpy) is a cold path
that should be outlined to avoid bloating every call site.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
J. Nick Koston
2026-03-07 13:28:04 -10:00
co-authored by Claude Opus 4.6
parent d3c5d91469
commit 9e082edecb
2 changed files with 12 additions and 8 deletions
+8
View File
@@ -8,6 +8,14 @@ namespace esphome::api {
static const char *const TAG = "api.proto";
void ProtoByteBuffer::grow_(size_t n) {
auto new_data = make_buffer(n);
if (this->size_)
std::memcpy(new_data.get(), this->data_.get(), this->size_);
this->data_ = std::move(new_data);
this->capacity_ = n;
}
#ifdef USE_API_VARINT64
optional<ProtoVarInt> ProtoVarInt::parse_wide(const uint8_t *buffer, uint32_t len, uint32_t *consumed,
uint32_t result32) {
+4 -8
View File
@@ -260,17 +260,12 @@ class ProtoByteBuffer {
public:
void clear() { this->size_ = 0; }
void reserve(size_t n) {
if (n > this->capacity_) {
auto new_data = make_buffer(n);
if (this->size_)
std::memcpy(new_data.get(), this->data_.get(), this->size_);
this->data_ = std::move(new_data);
this->capacity_ = n;
}
if (n > this->capacity_)
this->grow_(n);
}
void resize(size_t n) {
if (n > this->capacity_)
this->reserve(n);
this->grow_(n);
this->size_ = n; // no zero-fill
}
uint8_t *data() { return this->data_.get(); }
@@ -278,6 +273,7 @@ class ProtoByteBuffer {
size_t size() const { return this->size_; }
protected:
void grow_(size_t n);
std::unique_ptr<uint8_t[]> data_;
size_t size_{0};
size_t capacity_{0};