mirror of
https://github.com/esphome/esphome.git
synced 2026-09-20 11:38:48 +00:00
Remove leading null from blobs and EMPTY_REF from getters
- Blobs now start directly with first string (no wasted \0 prefix) - Lookup functions handle index 0 by pointing to trailing null of blob - get_*_ref() simplified: just calls lookup, no separate empty check - Removes EMPTY_REF constant and per-getter branch
This commit is contained in:
@@ -50,23 +50,16 @@ __attribute__((weak)) const char *entity_device_class_lookup(uint16_t) { return
|
||||
__attribute__((weak)) const char *entity_uom_lookup(uint16_t) { return ""; }
|
||||
__attribute__((weak)) const char *entity_icon_lookup(uint16_t) { return ""; }
|
||||
|
||||
static constexpr auto EMPTY_REF = StringRef::from_lit("");
|
||||
|
||||
// Entity device class (from packed index)
|
||||
StringRef EntityBase::get_device_class_ref() const {
|
||||
uint16_t idx = (this->entity_string_packed_ >> ENTITY_STR_DC_SHIFT) & ENTITY_STR_DC_MASK;
|
||||
if (idx == 0)
|
||||
return EMPTY_REF;
|
||||
return StringRef(entity_device_class_lookup(idx));
|
||||
return StringRef(
|
||||
entity_device_class_lookup((this->entity_string_packed_ >> ENTITY_STR_DC_SHIFT) & ENTITY_STR_DC_MASK));
|
||||
}
|
||||
std::string EntityBase::get_device_class() const { return std::string(this->get_device_class_ref().c_str()); }
|
||||
|
||||
// Entity unit of measurement (from packed index)
|
||||
StringRef EntityBase::get_unit_of_measurement_ref() const {
|
||||
uint16_t idx = (this->entity_string_packed_ >> ENTITY_STR_UOM_SHIFT) & ENTITY_STR_UOM_MASK;
|
||||
if (idx == 0)
|
||||
return EMPTY_REF;
|
||||
return StringRef(entity_uom_lookup(idx));
|
||||
return StringRef(entity_uom_lookup((this->entity_string_packed_ >> ENTITY_STR_UOM_SHIFT) & ENTITY_STR_UOM_MASK));
|
||||
}
|
||||
std::string EntityBase::get_unit_of_measurement() const {
|
||||
return std::string(this->get_unit_of_measurement_ref().c_str());
|
||||
@@ -75,12 +68,9 @@ std::string EntityBase::get_unit_of_measurement() const {
|
||||
// Entity icon (from packed index)
|
||||
StringRef EntityBase::get_icon_ref() const {
|
||||
#ifdef USE_ENTITY_ICON
|
||||
uint16_t idx = (this->entity_string_packed_ >> ENTITY_STR_ICON_SHIFT) & ENTITY_STR_ICON_MASK;
|
||||
if (idx == 0)
|
||||
return EMPTY_REF;
|
||||
return StringRef(entity_icon_lookup(idx));
|
||||
return StringRef(entity_icon_lookup((this->entity_string_packed_ >> ENTITY_STR_ICON_SHIFT) & ENTITY_STR_ICON_MASK));
|
||||
#else
|
||||
return EMPTY_REF;
|
||||
return StringRef(entity_icon_lookup(0));
|
||||
#endif
|
||||
}
|
||||
std::string EntityBase::get_icon() const { return std::string(this->get_icon_ref().c_str()); }
|
||||
|
||||
@@ -84,13 +84,14 @@ def _generate_blob_and_offsets(
|
||||
) -> tuple[bytes, list[int]]:
|
||||
"""Build a packed blob and offset list from a string dict.
|
||||
|
||||
Returns (blob_bytes, offsets) where offsets[0] points to "" (empty)
|
||||
and offsets[i] points to the i-th string.
|
||||
Returns (blob_bytes, offsets) where offsets are 1-based (matching the
|
||||
1-based indices returned by _register_string). Index 0 means "not set"
|
||||
and is handled by the caller before reaching the lookup function.
|
||||
"""
|
||||
# Sort by assigned index to ensure deterministic output
|
||||
sorted_strings = sorted(strings.items(), key=lambda x: x[1])
|
||||
blob = bytearray(b"\x00") # Index 0 = offset 0 = empty string
|
||||
offsets = [0] # offset for index 0 (empty string)
|
||||
blob = bytearray()
|
||||
offsets = []
|
||||
for s, _idx in sorted_strings:
|
||||
offsets.append(len(blob))
|
||||
blob.extend(s.encode("utf-8"))
|
||||
@@ -104,7 +105,11 @@ def _generate_category_code(
|
||||
lookup_fn: str,
|
||||
strings: dict[str, int],
|
||||
) -> str:
|
||||
"""Generate C++ code for one string category (blob + offsets + lookup)."""
|
||||
"""Generate C++ code for one string category (blob + offsets + lookup).
|
||||
|
||||
Index 0 means "not set" and is handled by get_*_ref() before calling
|
||||
the lookup function. The lookup uses 1-based indexing directly.
|
||||
"""
|
||||
if not strings:
|
||||
return ""
|
||||
|
||||
@@ -116,12 +121,16 @@ def _generate_category_code(
|
||||
blob_escaped = cpp_string_escape(blob_bytes)
|
||||
offsets_str = ", ".join(str(o) for o in offsets)
|
||||
|
||||
# The blob's last byte is always '\0' (null terminator of last string).
|
||||
# Point there for index 0 ("not set") and out-of-range to return "".
|
||||
empty_offset = len(blob_bytes) - 1
|
||||
|
||||
return (
|
||||
f"static const char {blob_var}[] = {blob_escaped};\n"
|
||||
f"static const {offset_type} {offsets_var}[] PROGMEM = {{{offsets_str}}};\n"
|
||||
f"const char *{lookup_fn}(uint16_t index) {{\n"
|
||||
f" if (index >= {count}) return {blob_var};\n"
|
||||
f" return &{blob_var}[{read_fn}(&{offsets_var}[index])];\n"
|
||||
f" if (index == 0 || index > {count}) return &{blob_var}[{empty_offset}];\n"
|
||||
f" return &{blob_var}[{read_fn}(&{offsets_var}[index - 1])];\n"
|
||||
f"}}\n"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user