[core] Add zero-allocation object_id methods (#12578)

This commit is contained in:
J. Nick Koston
2025-12-22 07:56:33 -10:00
committed by GitHub
parent 265ad9d264
commit 6383fe4598
8 changed files with 70 additions and 58 deletions
+5 -3
View File
@@ -404,9 +404,11 @@ void WebServer::handle_js_request(AsyncWebServerRequest *request) {
// Helper functions to reduce code size by avoiding macro expansion
static void set_json_id(JsonObject &root, EntityBase *obj, const char *prefix, JsonDetail start_config) {
char id_buf[160]; // object_id can be up to 128 chars + prefix + dash + null
const auto &object_id = obj->get_object_id();
snprintf(id_buf, sizeof(id_buf), "%s-%s", prefix, object_id.c_str());
char id_buf[160]; // prefix + dash + object_id (up to 128) + null
size_t len = strlen(prefix);
memcpy(id_buf, prefix, len); // NOLINT(bugprone-not-null-terminated-result) - null added by write_object_id_to
id_buf[len++] = '-';
obj->write_object_id_to(id_buf + len, sizeof(id_buf) - len);
root[ESPHOME_F("id")] = id_buf;
if (start_config == DETAIL_ALL) {
root[ESPHOME_F("name")] = obj->get_name();
+4 -8
View File
@@ -52,14 +52,10 @@ struct UrlMatch {
}
bool id_equals_entity(EntityBase *entity) const {
// Zero-copy comparison using StringRef
StringRef static_ref = entity->get_object_id_ref_for_api_();
if (!static_ref.empty()) {
return id && id_len == static_ref.size() && memcmp(id, static_ref.c_str(), id_len) == 0;
}
// Fallback to allocation (rare)
const auto &obj_id = entity->get_object_id();
return id && id_len == obj_id.length() && memcmp(id, obj_id.c_str(), id_len) == 0;
// Get object_id with zero heap allocation
char object_id_buf[OBJECT_ID_MAX_LEN];
StringRef object_id = entity->get_object_id_to(object_id_buf);
return id && id_len == object_id.size() && memcmp(id, object_id.c_str(), id_len) == 0;
}
bool method_equals(const char *str) const {
@@ -15,7 +15,8 @@ void write_row(AsyncResponseStream *stream, EntityBase *obj, const std::string &
stream->print("\" id=\"");
stream->print(klass.c_str());
stream->print("-");
stream->print(obj->get_object_id().c_str());
char object_id_buf[OBJECT_ID_MAX_LEN];
stream->print(obj->get_object_id_to(object_id_buf).c_str());
stream->print("\"><td>");
stream->print(obj->get_name().c_str());
stream->print("</td><td></td><td>");