From 1f493b208c227e63f65379033d018b32392ae61a Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 7 Jan 2023 14:38:49 +0100 Subject: [PATCH] replace std::string with const char #869 --- src/command.cpp | 4 ++- src/emsdevice.cpp | 92 ++++++++++++++++++++++++++++------------------- src/emsdevice.h | 14 ++++---- src/mqtt.cpp | 18 +++++----- 4 files changed, 75 insertions(+), 53 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index c068a7121..5b5ddbad5 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -416,7 +416,9 @@ bool Command::list(const uint8_t device_type, JsonObject & output) { for (const auto & cf : cmdfunctions_) { if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == std::string(cf.cmd_))) { if (cf.has_flags(CommandFlag::MQTT_SUB_FLAG_WW)) { - output[cl] = EMSdevice::tag_to_string(DeviceValueTAG::TAG_DEVICE_DATA_WW) + " " + Helpers::translated_word(cf.description_); + char s[100]; + snprintf(s, sizeof(s), "%s %s", EMSdevice::tag_to_string(DeviceValueTAG::TAG_DEVICE_DATA_WW), Helpers::translated_word(cf.description_)); + output[cl] = s; } else { output[cl] = Helpers::translated_word(cf.description_); } diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 891f2f4ee..4b383cdaf 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -43,16 +43,17 @@ bool EMSdevice::has_entities() const { return false; } -std::string EMSdevice::tag_to_string(uint8_t tag, const bool translate) { - return (translate ? Helpers::translated_word(DeviceValue::DeviceValueTAG_s[tag]) : DeviceValue::DeviceValueTAG_s[tag][0]); +const char * EMSdevice::tag_to_string(uint8_t tag, const bool translate) { + uint8_t tag_n = tag > DeviceValue::NUM_TAGS ? 0 : tag; + return (translate ? Helpers::translated_word(DeviceValue::DeviceValueTAG_s[tag_n]) : DeviceValue::DeviceValueTAG_s[tag_n][0]); } -std::string EMSdevice::tag_to_mqtt(uint8_t tag) { - return (DeviceValue::DeviceValueTAG_mqtt[tag]); +const char * EMSdevice::tag_to_mqtt(uint8_t tag) { + return (DeviceValue::DeviceValueTAG_mqtt[tag > DeviceValue::NUM_TAGS ? 0 : tag]); } -// convert UOM to a string - translating only for hours/minutes/seconds -std::string EMSdevice::uom_to_string(uint8_t uom) { +// convert UOM to a char string - translating only for hours/minutes/seconds +const char * EMSdevice::uom_to_string(uint8_t uom) { switch (uom) { case DeviceValueUOM::DEGREES: case DeviceValueUOM::DEGREES_R: @@ -303,7 +304,7 @@ bool EMSdevice::is_fetch(uint16_t telegram_id) const { } // check for a tag to create a nest -bool EMSdevice::has_tag(const uint8_t tag) const { +bool EMSdevice::has_tags(const uint8_t tag) const { for (const auto & dv : devicevalues_) { if (dv.tag == tag && tag >= DeviceValueTAG::TAG_HC1) { return true; @@ -331,8 +332,9 @@ void EMSdevice::list_device_entries(JsonObject & output) const { if (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && dv.type != DeviceValueType::CMD && !fullname.empty()) { // if we have a tag prefix it char key[50]; - if (!EMSdevice::tag_to_mqtt(dv.tag).empty()) { - snprintf(key, sizeof(key), "%s.%s", EMSdevice::tag_to_mqtt(dv.tag).c_str(), dv.short_name); + auto tag_s = EMSdevice::tag_to_mqtt(dv.tag); + if (strlen(tag_s)) { + snprintf(key, sizeof(key), "%s.%s", tag_s, dv.short_name); } else { snprintf(key, sizeof(key), "%s", dv.short_name); } @@ -343,7 +345,7 @@ void EMSdevice::list_device_entries(JsonObject & output) const { details.add(fullname); // add uom - if (!uom_to_string(dv.uom).empty() && uom_to_string(dv.uom) != " ") { + if (dv.uom != DeviceValueUOM::NONE) { details.add(EMSdevice::uom_to_string(dv.uom)); } } @@ -507,7 +509,13 @@ void EMSdevice::add_device_value(uint8_t tag, EMSESP::webCustomizationService.read([&](WebCustomization & settings) { for (EntityCustomization entityCustomization : settings.entityCustomizations) { if ((entityCustomization.product_id == product_id()) && (entityCustomization.device_id == device_id())) { - std::string entity = tag < DeviceValueTAG::TAG_HC1 ? short_name : tag_to_mqtt(tag) + "/" + short_name; + char entity[70]; + if (tag < DeviceValueTAG::TAG_HC1) { + strncpy(entity, short_name, sizeof(entity)); + } else { + snprintf(entity, sizeof(entity), "%s/%s", tag_to_mqtt(tag), short_name); + } + for (std::string entity_id : entityCustomization.entity_ids) { // if there is an appended custom name, strip it to get the true entity name // and extract the new custom name @@ -697,12 +705,12 @@ void EMSdevice::publish_value(void * value_p) const { char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; if (Mqtt::publish_single2cmd()) { if (dv.tag >= DeviceValueTAG::TAG_HC1) { - snprintf(topic, sizeof(topic), "%s/%s/%s", device_type_2_device_name(device_type_), tag_to_mqtt(dv.tag).c_str(), dv.short_name); + snprintf(topic, sizeof(topic), "%s/%s/%s", device_type_2_device_name(device_type_), tag_to_mqtt(dv.tag), dv.short_name); } else { snprintf(topic, sizeof(topic), "%s/%s", device_type_2_device_name(device_type_), (dv.short_name)); } } else if (Mqtt::is_nested() && dv.tag >= DeviceValueTAG::TAG_HC1) { - snprintf(topic, sizeof(topic), "%s/%s/%s", Mqtt::tag_to_topic(device_type_, dv.tag).c_str(), tag_to_mqtt(dv.tag).c_str(), dv.short_name); + snprintf(topic, sizeof(topic), "%s/%s/%s", Mqtt::tag_to_topic(device_type_, dv.tag).c_str(), tag_to_mqtt(dv.tag), dv.short_name); } else { snprintf(topic, sizeof(topic), "%s/%s", Mqtt::tag_to_topic(device_type_, dv.tag).c_str(), dv.short_name); } @@ -772,7 +780,7 @@ std::string EMSdevice::get_value_uom(const char * key) const { strlcpy(new_key, key, sizeof(new_key)); char * key_p = new_key; - for (uint8_t i = 0; i < DeviceValue::tag_count; i++) { + for (uint8_t i = 0; i < DeviceValue::NUM_TAGS; i++) { auto tag = Helpers::translated_word(DeviceValue::DeviceValueTAG_s[i]); if (tag) { std::string key2 = key; // copy string to a std::string so we can use the find function @@ -863,17 +871,19 @@ void EMSdevice::generate_values_web(JsonObject & output) { auto mask = Helpers::hextoa((uint8_t)(dv.state >> 4), false); // create mask to a 2-char string // add name, prefixing the tag if it exists. This is the id used in the WebUI table and must be unique - if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) { - obj["id"] = mask + fullname; - } else { + if (dv.has_tag()) { obj["id"] = mask + tag_to_string(dv.tag) + " " + fullname; + } else { + obj["id"] = mask + fullname; } // add commands and options if (dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY)) { // add the name of the Command function if (dv.tag >= DeviceValueTAG::TAG_HC1) { - obj["c"] = tag_to_mqtt(dv.tag) + "/" + dv.short_name; + char c_s[50]; + snprintf(c_s, sizeof(c_s), "%s/%s", tag_to_mqtt(dv.tag), dv.short_name); + obj["c"] = c_s; } else { obj["c"] = dv.short_name; } @@ -968,7 +978,9 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) { // id holds the shortname and must always have a value for the WebUI table to work if (dv.tag >= DeviceValueTAG::TAG_HC1) { - obj["id"] = tag_to_mqtt(dv.tag) + "/" + dv.short_name; + char id_s[50]; + snprintf(id_s, sizeof(id_s), "%s/%s", tag_to_mqtt(dv.tag), dv.short_name); + obj["id"] = id_s; } else { obj["id"] = dv.short_name; } @@ -978,12 +990,12 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) { auto fullname = Helpers::translated_word(dv.fullname); if (dv.type != DeviceValueType::CMD) { if (fullname) { - if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) { - obj["n"] = fullname; - } else { + if (dv.has_tag()) { char name[50]; - snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag).c_str(), fullname); + snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag), fullname); obj["n"] = name; + } else { + obj["n"] = fullname; } } @@ -1030,7 +1042,12 @@ void EMSdevice::set_climate_minmax(uint8_t tag, int16_t min, uint16_t max) { // returns true if the entity has a mask set (not 0 the default) void EMSdevice::setCustomEntity(const std::string & entity_id) { for (auto & dv : devicevalues_) { - std::string entity_name = dv.tag < DeviceValueTAG::TAG_HC1 ? dv.short_name : tag_to_mqtt(dv.tag) + "/" + dv.short_name; + char entity_name[70]; + if (dv.tag < DeviceValueTAG::TAG_HC1) { + strncpy(entity_name, dv.short_name, sizeof(entity_name)); + } else { + snprintf(entity_name, sizeof(entity_name), "%s/%s", tag_to_mqtt(dv.tag), dv.short_name); + } // extra shortname std::string shortname; @@ -1082,7 +1099,7 @@ void EMSdevice::setCustomEntity(const std::string & entity_id) { // populate a string vector with entities that have masks set or have a custom name void EMSdevice::getCustomEntities(std::vector & entity_ids) { for (const auto & dv : devicevalues_) { - std::string entity_name = dv.tag < DeviceValueTAG::TAG_HC1 ? dv.short_name : tag_to_mqtt(dv.tag) + "/" + dv.short_name; + std::string entity_name = dv.tag < DeviceValueTAG::TAG_HC1 ? dv.short_name : std::string(tag_to_mqtt(dv.tag)) + "/" + dv.short_name; uint8_t mask = dv.state >> 4; if (mask || !dv.custom_fullname.empty()) { @@ -1105,7 +1122,7 @@ void EMSdevice::dump_value_info() { if (dv.fullname != nullptr) { Serial.print(name_); Serial.print(','); - Serial.print(device_type_name().c_str()); + Serial.print(device_type_name()); Serial.print(','); Serial.print(product_id_); @@ -1203,7 +1220,6 @@ void EMSdevice::dump_value_info() { char entityid[500]; char entity_name[100]; - for (uint8_t count = 0; count < 2; count++) { if (count) { // new name, comes as last @@ -1222,7 +1238,7 @@ void EMSdevice::dump_value_info() { sizeof(entity_with_tag), "%s_%s_%s", device_type_2_device_name(device_type_), - EMSdevice::tag_to_mqtt(dv.tag).c_str(), + EMSdevice::tag_to_mqtt(dv.tag), entity_name); } else { snprintf(entity_with_tag, sizeof(entity_with_tag), "%s_%s", device_type_2_device_name(device_type_), entity_name); @@ -1300,14 +1316,16 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8 auto fullname = dv.get_fullname(); if (!fullname.empty()) { - if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) { - json["fullname"] = fullname; + if (dv.has_tag()) { + char name[50]; + snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag), fullname.c_str()); + json["name"] = name; } else { - json["fullname"] = tag_to_string(dv.tag) + " " + fullname; + json["fullname"] = fullname; } } - if (!tag_to_mqtt(dv.tag).empty()) { + if (dv.tag != DeviceValueTAG::TAG_NONE) { json["circuit"] = tag_to_mqtt(dv.tag); } @@ -1419,7 +1437,7 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8 } // add uom if it's not a " " (single space) - if (!uom_to_string(dv.uom).empty() && uom_to_string(dv.uom) != " ") { + if (dv.uom != DeviceValueUOM::NONE) { json["uom"] = uom_to_string(dv.uom); } @@ -1494,14 +1512,14 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c has_values = true; // flagged if we actually have data // we have a tag if it matches the filter given, and that the tag name is not empty/"" - bool have_tag = ((dv.tag != tag_filter) && !tag_to_string(dv.tag).empty()); + bool have_tag = ((dv.tag != tag_filter) && dv.has_tag()); // create the name for the JSON key char name[80]; if (output_target == OUTPUT_TARGET::API_VERBOSE || output_target == OUTPUT_TARGET::CONSOLE) { if (have_tag) { - snprintf(name, 80, "%s %s", tag_to_string(dv.tag).c_str(), fullname.c_str()); // prefix the tag + snprintf(name, 80, "%s %s", tag_to_string(dv.tag), fullname.c_str()); // prefix the tag } else { strlcpy(name, fullname.c_str(), sizeof(name)); // use full name } @@ -1689,7 +1707,7 @@ bool EMSdevice::has_telegram_id(uint16_t id) const { } // return the name of the telegram type -std::string EMSdevice::telegram_type_name(std::shared_ptr telegram) const { +const char * EMSdevice::telegram_type_name(std::shared_ptr telegram) { // see if it's one of the common ones, like Version if (telegram->type_id == EMS_TYPE_VERSION) { return "Version"; @@ -1703,7 +1721,7 @@ std::string EMSdevice::telegram_type_name(std::shared_ptr telegr } } - return std::string{}; + return ""; } // take a telegram_type_id and call the matching handler diff --git a/src/emsdevice.h b/src/emsdevice.h index 54df6d87d..63695f1b0 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -47,15 +47,17 @@ class EMSdevice { // static functions, used outside the class like in console.cpp, command.cpp, emsesp.cpp, mqtt.cpp static const char * device_type_2_device_name(const uint8_t device_type); static uint8_t device_name_2_device_type(const char * topic); - static std::string uom_to_string(uint8_t uom); - static std::string tag_to_string(uint8_t tag, const bool translate = true); - static std::string tag_to_mqtt(uint8_t tag); - static uint8_t decode_brand(uint8_t value); + + static const char * tag_to_string(uint8_t tag, const bool translate = true); + static const char * uom_to_string(uint8_t uom); + static const char * tag_to_mqtt(uint8_t tag); + + static uint8_t decode_brand(uint8_t value); const char * device_type_name(); // returns short non-translated device type name const char * device_type_2_device_name_translated(); // returns translated device type name - bool has_tag(const uint8_t tag) const; + bool has_tags(const uint8_t tag) const; bool has_cmd(const char * cmd, const int8_t id) const; inline uint8_t device_id() const { @@ -291,7 +293,7 @@ class EMSdevice { void mqtt_ha_entity_config_create(); void mqtt_ha_entity_config_remove(); - std::string telegram_type_name(std::shared_ptr telegram) const; + const char * telegram_type_name(std::shared_ptr telegram); void fetch_values(); void toggle_fetch(uint16_t telegram_id, bool toggle); diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 7024b250b..7ee6b3638 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -985,7 +985,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // create entity by add the hc/wwc tag if present, separating with a _ char entity_with_tag[50]; if (tag >= DeviceValueTAG::TAG_HC1) { - snprintf(entity_with_tag, sizeof(entity_with_tag), "%s_%s", EMSdevice::tag_to_mqtt(tag).c_str(), entity); + snprintf(entity_with_tag, sizeof(entity_with_tag), "%s_%s", EMSdevice::tag_to_mqtt(tag), entity); } else { snprintf(entity_with_tag, sizeof(entity_with_tag), "%s", entity); } @@ -1004,10 +1004,10 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev char uniq_s[60]; strlcpy(uniq_s, en_name, sizeof(uniq_s)); Helpers::replace_char(uniq_s, ' ', '_'); - if (EMSdevice::tag_to_string(tag).empty()) { + if (tag == DeviceValueTAG::TAG_NONE) { snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, Helpers::toLower(uniq_s).c_str()); } else { - snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", device_name, EMSdevice::tag_to_string(tag).c_str(), Helpers::toLower(uniq_s).c_str()); + snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", device_name, EMSdevice::tag_to_string(tag), Helpers::toLower(uniq_s).c_str()); } } @@ -1080,7 +1080,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // command topic back to EMS-ESP char command_topic[MQTT_TOPIC_MAX_SIZE]; if (tag >= DeviceValueTAG::TAG_HC1) { - snprintf(command_topic, sizeof(command_topic), "%s/%s/%s/%s", mqtt_basename_.c_str(), device_name, EMSdevice::tag_to_mqtt(tag).c_str(), entity); + snprintf(command_topic, sizeof(command_topic), "%s/%s/%s/%s", mqtt_basename_.c_str(), device_name, EMSdevice::tag_to_mqtt(tag), entity); } else { snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", mqtt_basename_.c_str(), device_name, entity); } @@ -1137,10 +1137,10 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev char ha_name[70]; char * F_name = strdup(fullname); F_name[0] = toupper(F_name[0]); // capitalize first letter - if (EMSdevice::tag_to_string(tag).empty()) { - snprintf(ha_name, sizeof(ha_name), "%s", F_name); // no tag + if (tag != DeviceValueTAG::TAG_NONE) { + snprintf(ha_name, sizeof(ha_name), "%s %s", EMSdevice::tag_to_string(tag), F_name); } else { - snprintf(ha_name, sizeof(ha_name), "%s %s", EMSdevice::tag_to_string(tag).c_str(), F_name); + snprintf(ha_name, sizeof(ha_name), "%s", F_name); // no tag } free(F_name); // very important! doc["name"] = ha_name; @@ -1150,7 +1150,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev char val_tpl[75]; if (is_nested()) { if (tag >= DeviceValueTAG::TAG_HC1) { - snprintf(val_tpl, sizeof(val_tpl), "{{value_json.%s.%s}}", EMSdevice::tag_to_mqtt(tag).c_str(), entity); + snprintf(val_tpl, sizeof(val_tpl), "{{value_json.%s.%s}}", EMSdevice::tag_to_mqtt(tag), entity); } else { snprintf(val_tpl, sizeof(val_tpl), "{{value_json.%s}}", entity); } @@ -1383,7 +1383,7 @@ std::string Mqtt::tag_to_topic(uint8_t device_type, uint8_t tag) { std::string topic = EMSdevice::device_type_2_device_name(device_type); // if there is a tag add it - if (!EMSdevice::tag_to_mqtt(tag).empty() && ((tag == DeviceValueTAG::TAG_BOILER_DATA_WW) || (!is_nested() && tag >= DeviceValueTAG::TAG_HC1))) { + if ((tag == DeviceValueTAG::TAG_BOILER_DATA_WW) || (!is_nested() && tag >= DeviceValueTAG::TAG_HC1)) { return topic + "_data_" + EMSdevice::tag_to_mqtt(tag); } else { return topic + "_data";