mirror of
https://github.com/esphome/esphome.git
synced 2026-05-29 06:27:24 +08: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");
|
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) {
|
template<> const char *proto_enum_to_string<enums::EntityCategory>(enums::EntityCategory value) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case enums::ENTITY_CATEGORY_NONE:
|
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 {
|
void SubscribeLogsResponse::dump_to(std::string &out) const {
|
||||||
MessageDumpHelper helper(out, "SubscribeLogsResponse");
|
MessageDumpHelper helper(out, "SubscribeLogsResponse");
|
||||||
dump_field(out, "level", static_cast<enums::LogLevel>(this->level));
|
dump_field(out, "level", static_cast<enums::LogLevel>(this->level));
|
||||||
out.append(" message: ");
|
dump_bytes_field(out, "message", this->message_ptr_, this->message_len_);
|
||||||
out.append(format_hex_pretty(this->message_ptr_, this->message_len_));
|
|
||||||
out.append("\n");
|
|
||||||
}
|
}
|
||||||
#ifdef USE_API_NOISE
|
#ifdef USE_API_NOISE
|
||||||
void NoiseEncryptionSetKeyRequest::dump_to(std::string &out) const {
|
void NoiseEncryptionSetKeyRequest::dump_to(std::string &out) const {
|
||||||
MessageDumpHelper helper(out, "NoiseEncryptionSetKeyRequest");
|
MessageDumpHelper helper(out, "NoiseEncryptionSetKeyRequest");
|
||||||
out.append(" key: ");
|
dump_bytes_field(out, "key", this->key, this->key_len);
|
||||||
out.append(format_hex_pretty(this->key, this->key_len));
|
|
||||||
out.append("\n");
|
|
||||||
}
|
}
|
||||||
void NoiseEncryptionSetKeyResponse::dump_to(std::string &out) const {
|
void NoiseEncryptionSetKeyResponse::dump_to(std::string &out) const {
|
||||||
MessageDumpHelper helper(out, "NoiseEncryptionSetKeyResponse");
|
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, "success", this->success);
|
||||||
dump_field(out, "error_message", this->error_message);
|
dump_field(out, "error_message", this->error_message);
|
||||||
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
|
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
|
||||||
out.append(" response_data: ");
|
dump_bytes_field(out, "response_data", this->response_data, this->response_data_len);
|
||||||
out.append(format_hex_pretty(this->response_data, this->response_data_len));
|
|
||||||
out.append("\n");
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1278,9 +1282,7 @@ void ExecuteServiceResponse::dump_to(std::string &out) const {
|
|||||||
dump_field(out, "success", this->success);
|
dump_field(out, "success", this->success);
|
||||||
dump_field(out, "error_message", this->error_message);
|
dump_field(out, "error_message", this->error_message);
|
||||||
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
|
#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
|
||||||
out.append(" response_data: ");
|
dump_bytes_field(out, "response_data", this->response_data, this->response_data_len);
|
||||||
out.append(format_hex_pretty(this->response_data, this->response_data_len));
|
|
||||||
out.append("\n");
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1302,9 +1304,7 @@ void ListEntitiesCameraResponse::dump_to(std::string &out) const {
|
|||||||
void CameraImageResponse::dump_to(std::string &out) const {
|
void CameraImageResponse::dump_to(std::string &out) const {
|
||||||
MessageDumpHelper helper(out, "CameraImageResponse");
|
MessageDumpHelper helper(out, "CameraImageResponse");
|
||||||
dump_field(out, "key", this->key);
|
dump_field(out, "key", this->key);
|
||||||
out.append(" data: ");
|
dump_bytes_field(out, "data", this->data_ptr_, this->data_len_);
|
||||||
out.append(format_hex_pretty(this->data_ptr_, this->data_len_));
|
|
||||||
out.append("\n");
|
|
||||||
dump_field(out, "done", this->done);
|
dump_field(out, "done", this->done);
|
||||||
#ifdef USE_DEVICES
|
#ifdef USE_DEVICES
|
||||||
dump_field(out, "device_id", this->device_id);
|
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, "address", this->address);
|
||||||
dump_field(out, "rssi", this->rssi);
|
dump_field(out, "rssi", this->rssi);
|
||||||
dump_field(out, "address_type", this->address_type);
|
dump_field(out, "address_type", this->address_type);
|
||||||
out.append(" data: ");
|
dump_bytes_field(out, "data", this->data, this->data_len);
|
||||||
out.append(format_hex_pretty(this->data, this->data_len));
|
|
||||||
out.append("\n");
|
|
||||||
}
|
}
|
||||||
void BluetoothLERawAdvertisementsResponse::dump_to(std::string &out) const {
|
void BluetoothLERawAdvertisementsResponse::dump_to(std::string &out) const {
|
||||||
MessageDumpHelper helper(out, "BluetoothLERawAdvertisementsResponse");
|
MessageDumpHelper helper(out, "BluetoothLERawAdvertisementsResponse");
|
||||||
@@ -1792,18 +1790,14 @@ void BluetoothGATTReadResponse::dump_to(std::string &out) const {
|
|||||||
MessageDumpHelper helper(out, "BluetoothGATTReadResponse");
|
MessageDumpHelper helper(out, "BluetoothGATTReadResponse");
|
||||||
dump_field(out, "address", this->address);
|
dump_field(out, "address", this->address);
|
||||||
dump_field(out, "handle", this->handle);
|
dump_field(out, "handle", this->handle);
|
||||||
out.append(" data: ");
|
dump_bytes_field(out, "data", this->data_ptr_, this->data_len_);
|
||||||
out.append(format_hex_pretty(this->data_ptr_, this->data_len_));
|
|
||||||
out.append("\n");
|
|
||||||
}
|
}
|
||||||
void BluetoothGATTWriteRequest::dump_to(std::string &out) const {
|
void BluetoothGATTWriteRequest::dump_to(std::string &out) const {
|
||||||
MessageDumpHelper helper(out, "BluetoothGATTWriteRequest");
|
MessageDumpHelper helper(out, "BluetoothGATTWriteRequest");
|
||||||
dump_field(out, "address", this->address);
|
dump_field(out, "address", this->address);
|
||||||
dump_field(out, "handle", this->handle);
|
dump_field(out, "handle", this->handle);
|
||||||
dump_field(out, "response", this->response);
|
dump_field(out, "response", this->response);
|
||||||
out.append(" data: ");
|
dump_bytes_field(out, "data", this->data, this->data_len);
|
||||||
out.append(format_hex_pretty(this->data, this->data_len));
|
|
||||||
out.append("\n");
|
|
||||||
}
|
}
|
||||||
void BluetoothGATTReadDescriptorRequest::dump_to(std::string &out) const {
|
void BluetoothGATTReadDescriptorRequest::dump_to(std::string &out) const {
|
||||||
MessageDumpHelper helper(out, "BluetoothGATTReadDescriptorRequest");
|
MessageDumpHelper helper(out, "BluetoothGATTReadDescriptorRequest");
|
||||||
@@ -1814,9 +1808,7 @@ void BluetoothGATTWriteDescriptorRequest::dump_to(std::string &out) const {
|
|||||||
MessageDumpHelper helper(out, "BluetoothGATTWriteDescriptorRequest");
|
MessageDumpHelper helper(out, "BluetoothGATTWriteDescriptorRequest");
|
||||||
dump_field(out, "address", this->address);
|
dump_field(out, "address", this->address);
|
||||||
dump_field(out, "handle", this->handle);
|
dump_field(out, "handle", this->handle);
|
||||||
out.append(" data: ");
|
dump_bytes_field(out, "data", this->data, this->data_len);
|
||||||
out.append(format_hex_pretty(this->data, this->data_len));
|
|
||||||
out.append("\n");
|
|
||||||
}
|
}
|
||||||
void BluetoothGATTNotifyRequest::dump_to(std::string &out) const {
|
void BluetoothGATTNotifyRequest::dump_to(std::string &out) const {
|
||||||
MessageDumpHelper helper(out, "BluetoothGATTNotifyRequest");
|
MessageDumpHelper helper(out, "BluetoothGATTNotifyRequest");
|
||||||
@@ -1828,9 +1820,7 @@ void BluetoothGATTNotifyDataResponse::dump_to(std::string &out) const {
|
|||||||
MessageDumpHelper helper(out, "BluetoothGATTNotifyDataResponse");
|
MessageDumpHelper helper(out, "BluetoothGATTNotifyDataResponse");
|
||||||
dump_field(out, "address", this->address);
|
dump_field(out, "address", this->address);
|
||||||
dump_field(out, "handle", this->handle);
|
dump_field(out, "handle", this->handle);
|
||||||
out.append(" data: ");
|
dump_bytes_field(out, "data", this->data_ptr_, this->data_len_);
|
||||||
out.append(format_hex_pretty(this->data_ptr_, this->data_len_));
|
|
||||||
out.append("\n");
|
|
||||||
}
|
}
|
||||||
void SubscribeBluetoothConnectionsFreeRequest::dump_to(std::string &out) const {
|
void SubscribeBluetoothConnectionsFreeRequest::dump_to(std::string &out) const {
|
||||||
out.append("SubscribeBluetoothConnectionsFreeRequest {}");
|
out.append("SubscribeBluetoothConnectionsFreeRequest {}");
|
||||||
@@ -1934,9 +1924,7 @@ void VoiceAssistantEventResponse::dump_to(std::string &out) const {
|
|||||||
}
|
}
|
||||||
void VoiceAssistantAudio::dump_to(std::string &out) const {
|
void VoiceAssistantAudio::dump_to(std::string &out) const {
|
||||||
MessageDumpHelper helper(out, "VoiceAssistantAudio");
|
MessageDumpHelper helper(out, "VoiceAssistantAudio");
|
||||||
out.append(" data: ");
|
dump_bytes_field(out, "data", this->data, this->data_len);
|
||||||
out.append(format_hex_pretty(this->data, this->data_len));
|
|
||||||
out.append("\n");
|
|
||||||
dump_field(out, "end", this->end);
|
dump_field(out, "end", this->end);
|
||||||
}
|
}
|
||||||
void VoiceAssistantTimerEventResponse::dump_to(std::string &out) const {
|
void VoiceAssistantTimerEventResponse::dump_to(std::string &out) const {
|
||||||
@@ -2297,16 +2285,12 @@ void UpdateCommandRequest::dump_to(std::string &out) const {
|
|||||||
#ifdef USE_ZWAVE_PROXY
|
#ifdef USE_ZWAVE_PROXY
|
||||||
void ZWaveProxyFrame::dump_to(std::string &out) const {
|
void ZWaveProxyFrame::dump_to(std::string &out) const {
|
||||||
MessageDumpHelper helper(out, "ZWaveProxyFrame");
|
MessageDumpHelper helper(out, "ZWaveProxyFrame");
|
||||||
out.append(" data: ");
|
dump_bytes_field(out, "data", this->data, this->data_len);
|
||||||
out.append(format_hex_pretty(this->data, this->data_len));
|
|
||||||
out.append("\n");
|
|
||||||
}
|
}
|
||||||
void ZWaveProxyRequest::dump_to(std::string &out) const {
|
void ZWaveProxyRequest::dump_to(std::string &out) const {
|
||||||
MessageDumpHelper helper(out, "ZWaveProxyRequest");
|
MessageDumpHelper helper(out, "ZWaveProxyRequest");
|
||||||
dump_field(out, "type", static_cast<enums::ZWaveProxyRequestType>(this->type));
|
dump_field(out, "type", static_cast<enums::ZWaveProxyRequestType>(this->type));
|
||||||
out.append(" data: ");
|
dump_bytes_field(out, "data", this->data, this->data_len);
|
||||||
out.append(format_hex_pretty(this->data, this->data_len));
|
|
||||||
out.append("\n");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_INFRARED
|
#ifdef USE_INFRARED
|
||||||
|
|||||||
@@ -786,10 +786,32 @@ class BytesType(TypeInfo):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def dump_content(self) -> str:
|
def dump_content(self) -> str:
|
||||||
o = f'out.append(" {self.name}: ");\n'
|
# For SOURCE_CLIENT only, always use std::string
|
||||||
o += self.dump(f"this->{self.field_name}") + "\n"
|
if not self._needs_encode:
|
||||||
o += 'out.append("\\n");'
|
return (
|
||||||
return o
|
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:
|
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_);"
|
return f"size.add_length({self.calculate_field_id_size()}, this->{self.field_name}_len_);"
|
||||||
@@ -862,9 +884,8 @@ class PointerToBytesBufferType(PointerToBufferTypeBase):
|
|||||||
@property
|
@property
|
||||||
def dump_content(self) -> str:
|
def dump_content(self) -> str:
|
||||||
return (
|
return (
|
||||||
f'out.append(" {self.name}: ");\n'
|
f'dump_bytes_field(out, "{self.name}", '
|
||||||
+ f"out.append({self.dump(self.field_name)});\n"
|
f"this->{self.field_name}, this->{self.field_name}_len);"
|
||||||
+ 'out.append("\\n");'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||||
@@ -1062,10 +1083,10 @@ class FixedArrayBytesType(TypeInfo):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def dump_content(self) -> str:
|
def dump_content(self) -> str:
|
||||||
o = f'out.append(" {self.name}: ");\n'
|
return (
|
||||||
o += f"out.append(format_hex_pretty(this->{self.field_name}, this->{self.field_name}_len));\n"
|
f'dump_bytes_field(out, "{self.name}", '
|
||||||
o += 'out.append("\\n");'
|
f"this->{self.field_name}, this->{self.field_name}_len);"
|
||||||
return o
|
)
|
||||||
|
|
||||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||||
# Use the actual length stored in the _len field
|
# 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");
|
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"
|
content += "namespace enums {\n\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user