mirror of
https://github.com/esphome/esphome.git
synced 2026-02-08 00:31:58 +00:00
[api] Use stack buffer for bytes field dumping in proto message logs (#13162)
This commit is contained in:
@@ -100,6 +100,16 @@ template<typename T> static void dump_field(std::string &out, const char *field_
|
||||
out.append("\n");
|
||||
}
|
||||
|
||||
// Helper for bytes fields - uses stack buffer to avoid heap allocation
|
||||
// Buffer sized for 160 bytes of data (480 chars with separators) to fit typical log buffer
|
||||
static void dump_bytes_field(std::string &out, const char *field_name, const uint8_t *data, size_t len,
|
||||
int indent = 2) {
|
||||
char hex_buf[format_hex_pretty_size(160)];
|
||||
append_field_prefix(out, field_name, indent);
|
||||
format_hex_pretty_to(hex_buf, data, len);
|
||||
append_with_newline(out, hex_buf);
|
||||
}
|
||||
|
||||
template<> const char *proto_enum_to_string<enums::EntityCategory>(enums::EntityCategory value) {
|
||||
switch (value) {
|
||||
case enums::ENTITY_CATEGORY_NONE:
|
||||
@@ -1127,16 +1137,12 @@ void SubscribeLogsRequest::dump_to(std::string &out) const {
|
||||
void SubscribeLogsResponse::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "SubscribeLogsResponse");
|
||||
dump_field(out, "level", static_cast<enums::LogLevel>(this->level));
|
||||
out.append(" message: ");
|
||||
out.append(format_hex_pretty(this->message_ptr_, this->message_len_));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "message", this->message_ptr_, this->message_len_);
|
||||
}
|
||||
#ifdef USE_API_NOISE
|
||||
void NoiseEncryptionSetKeyRequest::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "NoiseEncryptionSetKeyRequest");
|
||||
out.append(" key: ");
|
||||
out.append(format_hex_pretty(this->key, this->key_len));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "key", this->key, this->key_len);
|
||||
}
|
||||
void NoiseEncryptionSetKeyResponse::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "NoiseEncryptionSetKeyResponse");
|
||||
@@ -1189,9 +1195,7 @@ void HomeassistantActionResponse::dump_to(std::string &out) const {
|
||||
dump_field(out, "success", this->success);
|
||||
dump_field(out, "error_message", this->error_message);
|
||||
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
|
||||
out.append(" response_data: ");
|
||||
out.append(format_hex_pretty(this->response_data, this->response_data_len));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "response_data", this->response_data, this->response_data_len);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -1278,9 +1282,7 @@ void ExecuteServiceResponse::dump_to(std::string &out) const {
|
||||
dump_field(out, "success", this->success);
|
||||
dump_field(out, "error_message", this->error_message);
|
||||
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
|
||||
out.append(" response_data: ");
|
||||
out.append(format_hex_pretty(this->response_data, this->response_data_len));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "response_data", this->response_data, this->response_data_len);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -1302,9 +1304,7 @@ void ListEntitiesCameraResponse::dump_to(std::string &out) const {
|
||||
void CameraImageResponse::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "CameraImageResponse");
|
||||
dump_field(out, "key", this->key);
|
||||
out.append(" data: ");
|
||||
out.append(format_hex_pretty(this->data_ptr_, this->data_len_));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "data", this->data_ptr_, this->data_len_);
|
||||
dump_field(out, "done", this->done);
|
||||
#ifdef USE_DEVICES
|
||||
dump_field(out, "device_id", this->device_id);
|
||||
@@ -1705,9 +1705,7 @@ void BluetoothLERawAdvertisement::dump_to(std::string &out) const {
|
||||
dump_field(out, "address", this->address);
|
||||
dump_field(out, "rssi", this->rssi);
|
||||
dump_field(out, "address_type", this->address_type);
|
||||
out.append(" data: ");
|
||||
out.append(format_hex_pretty(this->data, this->data_len));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "data", this->data, this->data_len);
|
||||
}
|
||||
void BluetoothLERawAdvertisementsResponse::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "BluetoothLERawAdvertisementsResponse");
|
||||
@@ -1792,18 +1790,14 @@ void BluetoothGATTReadResponse::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "BluetoothGATTReadResponse");
|
||||
dump_field(out, "address", this->address);
|
||||
dump_field(out, "handle", this->handle);
|
||||
out.append(" data: ");
|
||||
out.append(format_hex_pretty(this->data_ptr_, this->data_len_));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "data", this->data_ptr_, this->data_len_);
|
||||
}
|
||||
void BluetoothGATTWriteRequest::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "BluetoothGATTWriteRequest");
|
||||
dump_field(out, "address", this->address);
|
||||
dump_field(out, "handle", this->handle);
|
||||
dump_field(out, "response", this->response);
|
||||
out.append(" data: ");
|
||||
out.append(format_hex_pretty(this->data, this->data_len));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "data", this->data, this->data_len);
|
||||
}
|
||||
void BluetoothGATTReadDescriptorRequest::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "BluetoothGATTReadDescriptorRequest");
|
||||
@@ -1814,9 +1808,7 @@ void BluetoothGATTWriteDescriptorRequest::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "BluetoothGATTWriteDescriptorRequest");
|
||||
dump_field(out, "address", this->address);
|
||||
dump_field(out, "handle", this->handle);
|
||||
out.append(" data: ");
|
||||
out.append(format_hex_pretty(this->data, this->data_len));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "data", this->data, this->data_len);
|
||||
}
|
||||
void BluetoothGATTNotifyRequest::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "BluetoothGATTNotifyRequest");
|
||||
@@ -1828,9 +1820,7 @@ void BluetoothGATTNotifyDataResponse::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "BluetoothGATTNotifyDataResponse");
|
||||
dump_field(out, "address", this->address);
|
||||
dump_field(out, "handle", this->handle);
|
||||
out.append(" data: ");
|
||||
out.append(format_hex_pretty(this->data_ptr_, this->data_len_));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "data", this->data_ptr_, this->data_len_);
|
||||
}
|
||||
void SubscribeBluetoothConnectionsFreeRequest::dump_to(std::string &out) const {
|
||||
out.append("SubscribeBluetoothConnectionsFreeRequest {}");
|
||||
@@ -1934,9 +1924,7 @@ void VoiceAssistantEventResponse::dump_to(std::string &out) const {
|
||||
}
|
||||
void VoiceAssistantAudio::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "VoiceAssistantAudio");
|
||||
out.append(" data: ");
|
||||
out.append(format_hex_pretty(this->data, this->data_len));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "data", this->data, this->data_len);
|
||||
dump_field(out, "end", this->end);
|
||||
}
|
||||
void VoiceAssistantTimerEventResponse::dump_to(std::string &out) const {
|
||||
@@ -2297,16 +2285,12 @@ void UpdateCommandRequest::dump_to(std::string &out) const {
|
||||
#ifdef USE_ZWAVE_PROXY
|
||||
void ZWaveProxyFrame::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "ZWaveProxyFrame");
|
||||
out.append(" data: ");
|
||||
out.append(format_hex_pretty(this->data, this->data_len));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "data", this->data, this->data_len);
|
||||
}
|
||||
void ZWaveProxyRequest::dump_to(std::string &out) const {
|
||||
MessageDumpHelper helper(out, "ZWaveProxyRequest");
|
||||
dump_field(out, "type", static_cast<enums::ZWaveProxyRequestType>(this->type));
|
||||
out.append(" data: ");
|
||||
out.append(format_hex_pretty(this->data, this->data_len));
|
||||
out.append("\n");
|
||||
dump_bytes_field(out, "data", this->data, this->data_len);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_INFRARED
|
||||
|
||||
@@ -786,10 +786,32 @@ class BytesType(TypeInfo):
|
||||
|
||||
@property
|
||||
def dump_content(self) -> str:
|
||||
o = f'out.append(" {self.name}: ");\n'
|
||||
o += self.dump(f"this->{self.field_name}") + "\n"
|
||||
o += 'out.append("\\n");'
|
||||
return o
|
||||
# For SOURCE_CLIENT only, always use std::string
|
||||
if not self._needs_encode:
|
||||
return (
|
||||
f'dump_bytes_field(out, "{self.name}", '
|
||||
f"reinterpret_cast<const uint8_t*>(this->{self.field_name}.data()), "
|
||||
f"this->{self.field_name}.size());"
|
||||
)
|
||||
|
||||
# For SOURCE_SERVER, always use pointer/length
|
||||
if not self._needs_decode:
|
||||
return (
|
||||
f'dump_bytes_field(out, "{self.name}", '
|
||||
f"this->{self.field_name}_ptr_, this->{self.field_name}_len_);"
|
||||
)
|
||||
|
||||
# For SOURCE_BOTH, check if pointer is set (sending) or use string (received)
|
||||
return (
|
||||
f"if (this->{self.field_name}_ptr_ != nullptr) {{\n"
|
||||
f' dump_bytes_field(out, "{self.name}", '
|
||||
f"this->{self.field_name}_ptr_, this->{self.field_name}_len_);\n"
|
||||
f"}} else {{\n"
|
||||
f' dump_bytes_field(out, "{self.name}", '
|
||||
f"reinterpret_cast<const uint8_t*>(this->{self.field_name}.data()), "
|
||||
f"this->{self.field_name}.size());\n"
|
||||
f"}}"
|
||||
)
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
return f"size.add_length({self.calculate_field_id_size()}, this->{self.field_name}_len_);"
|
||||
@@ -862,9 +884,8 @@ class PointerToBytesBufferType(PointerToBufferTypeBase):
|
||||
@property
|
||||
def dump_content(self) -> str:
|
||||
return (
|
||||
f'out.append(" {self.name}: ");\n'
|
||||
+ f"out.append({self.dump(self.field_name)});\n"
|
||||
+ 'out.append("\\n");'
|
||||
f'dump_bytes_field(out, "{self.name}", '
|
||||
f"this->{self.field_name}, this->{self.field_name}_len);"
|
||||
)
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
@@ -1062,10 +1083,10 @@ class FixedArrayBytesType(TypeInfo):
|
||||
|
||||
@property
|
||||
def dump_content(self) -> str:
|
||||
o = f'out.append(" {self.name}: ");\n'
|
||||
o += f"out.append(format_hex_pretty(this->{self.field_name}, this->{self.field_name}_len));\n"
|
||||
o += 'out.append("\\n");'
|
||||
return o
|
||||
return (
|
||||
f'dump_bytes_field(out, "{self.name}", '
|
||||
f"this->{self.field_name}, this->{self.field_name}_len);"
|
||||
)
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
# Use the actual length stored in the _len field
|
||||
@@ -2658,6 +2679,15 @@ static void dump_field(std::string &out, const char *field_name, T value, int in
|
||||
out.append("\\n");
|
||||
}
|
||||
|
||||
// Helper for bytes fields - uses stack buffer to avoid heap allocation
|
||||
// Buffer sized for 160 bytes of data (480 chars with separators) to fit typical log buffer
|
||||
static void dump_bytes_field(std::string &out, const char *field_name, const uint8_t *data, size_t len, int indent = 2) {
|
||||
char hex_buf[format_hex_pretty_size(160)];
|
||||
append_field_prefix(out, field_name, indent);
|
||||
format_hex_pretty_to(hex_buf, data, len);
|
||||
append_with_newline(out, hex_buf);
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
content += "namespace enums {\n\n"
|
||||
|
||||
Reference in New Issue
Block a user