diff --git a/esphome/components/esp8266/preferences.cpp b/esphome/components/esp8266/preferences.cpp index efd226e8f8..bb7e436bea 100644 --- a/esphome/components/esp8266/preferences.cpp +++ b/esphome/components/esp8266/preferences.cpp @@ -12,7 +12,7 @@ extern "C" { #include "preferences.h" #include -#include +#include namespace esphome { namespace esp8266 { @@ -67,6 +67,8 @@ static uint32_t get_esp8266_flash_sector() { } static uint32_t get_esp8266_flash_address() { return get_esp8266_flash_sector() * SPI_FLASH_SEC_SIZE; } +static inline size_t bytes_to_words(size_t bytes) { return (bytes + 3) / 4; } + template uint32_t calculate_crc(It first, It last, uint32_t type) { uint32_t crc = type; while (first != last) { @@ -123,41 +125,36 @@ class ESP8266PreferenceBackend : public ESPPreferenceBackend { size_t length_words = 0; bool save(const uint8_t *data, size_t len) override { - if ((len + 3) / 4 != length_words) { + if (bytes_to_words(len) != length_words) { return false; } - std::vector buffer; - buffer.resize(length_words + 1); - memcpy(buffer.data(), data, len); - buffer[buffer.size() - 1] = calculate_crc(buffer.begin(), buffer.end() - 1, type); + size_t buffer_size = length_words + 1; + std::unique_ptr buffer(new uint32_t[buffer_size]()); // Note the () for zero-initialization + memcpy(buffer.get(), data, len); + buffer[length_words] = calculate_crc(buffer.get(), buffer.get() + length_words, type); if (in_flash) { - return save_to_flash(offset, buffer.data(), buffer.size()); - } else { - return save_to_rtc(offset, buffer.data(), buffer.size()); + return save_to_flash(offset, buffer.get(), buffer_size); } + return save_to_rtc(offset, buffer.get(), buffer_size); } bool load(uint8_t *data, size_t len) override { - if ((len + 3) / 4 != length_words) { + if (bytes_to_words(len) != length_words) { return false; } - std::vector buffer; - buffer.resize(length_words + 1); - bool ret; - if (in_flash) { - ret = load_from_flash(offset, buffer.data(), buffer.size()); - } else { - ret = load_from_rtc(offset, buffer.data(), buffer.size()); - } + size_t buffer_size = length_words + 1; + std::unique_ptr buffer(new uint32_t[buffer_size]()); + bool ret = in_flash ? load_from_flash(offset, buffer.get(), buffer_size) + : load_from_rtc(offset, buffer.get(), buffer_size); if (!ret) return false; - uint32_t crc = calculate_crc(buffer.begin(), buffer.end() - 1, type); - if (buffer[buffer.size() - 1] != crc) { + uint32_t crc = calculate_crc(buffer.get(), buffer.get() + length_words, type); + if (buffer[length_words] != crc) { return false; } - memcpy(data, buffer.data(), len); + memcpy(data, buffer.get(), len); return true; } }; @@ -178,7 +175,7 @@ class ESP8266Preferences : public ESPPreferences { } ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash) override { - uint32_t length_words = (length + 3) / 4; + uint32_t length_words = bytes_to_words(length); if (in_flash) { uint32_t start = current_flash_offset; uint32_t end = start + length_words + 1;