mirror of
https://github.com/esphome/esphome.git
synced 2026-09-17 18:18:43 +00:00
[store_yaml] Address review: combined dump_config, encapsulate PROGMEM read
- Coalesce dump_config into a single ESP_LOGCONFIG call. - Replace the raw get_data() accessor with a read_chunk() helper that copies bytes via progmem_read_byte, so callers cannot accidentally dereference the PROGMEM pointer directly on ESP8266. - Update the API streaming handler to use read_chunk().
This commit is contained in:
@@ -1179,7 +1179,8 @@ static constexpr size_t STORE_YAML_CHUNK_SIZE = 512;
|
||||
static uint8_t store_yaml_chunk_buf[STORE_YAML_CHUNK_SIZE];
|
||||
|
||||
void APIConnection::on_get_yaml_request() {
|
||||
if (store_yaml::global_store_yaml == nullptr || store_yaml::global_store_yaml->get_data() == nullptr) {
|
||||
auto *comp = store_yaml::global_store_yaml;
|
||||
if (comp == nullptr || comp->get_size() == 0) {
|
||||
// No blob — send a single done=true response so the client doesn't hang.
|
||||
GetYamlResponse resp;
|
||||
resp.done = true;
|
||||
@@ -1197,7 +1198,6 @@ void APIConnection::try_send_store_yaml_() {
|
||||
if (comp == nullptr)
|
||||
return;
|
||||
|
||||
const uint8_t *data = comp->get_data();
|
||||
const size_t total = comp->get_size();
|
||||
|
||||
while (this->store_yaml_pos_ < total || this->store_yaml_pos_ == 0) {
|
||||
@@ -1207,10 +1207,9 @@ void APIConnection::try_send_store_yaml_() {
|
||||
const size_t remaining = total - this->store_yaml_pos_;
|
||||
const size_t to_send = remaining < STORE_YAML_CHUNK_SIZE ? remaining : STORE_YAML_CHUNK_SIZE;
|
||||
|
||||
// Copy from PROGMEM into a stack buffer. progmem_read_byte is a no-op except on ESP8266.
|
||||
for (size_t i = 0; i < to_send; i++) {
|
||||
store_yaml_chunk_buf[i] = progmem_read_byte(&data[this->store_yaml_pos_ + i]);
|
||||
}
|
||||
// Pulls a chunk out of PROGMEM into a stack buffer; on ESP8266 this routes
|
||||
// through progmem_read_byte, on every other platform it's a plain byte copy.
|
||||
comp->read_chunk(this->store_yaml_pos_, store_yaml_chunk_buf, to_send);
|
||||
|
||||
GetYamlResponse resp;
|
||||
resp.set_data(store_yaml_chunk_buf, to_send);
|
||||
|
||||
@@ -14,10 +14,19 @@ StoreYamlComponent *global_store_yaml = nullptr;
|
||||
void StoreYamlComponent::setup() { global_store_yaml = this; }
|
||||
|
||||
void StoreYamlComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "YAML:");
|
||||
ESP_LOGCONFIG(TAG, " Compressed size: %zu bytes", this->size_);
|
||||
ESP_LOGCONFIG(TAG, " Uncompressed size: %zu bytes", this->uncompressed_size_);
|
||||
ESP_LOGCONFIG(TAG, " Encoding: %s", ENCODING);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"YAML:\n"
|
||||
" Compressed size: %zu bytes\n"
|
||||
" Uncompressed size: %zu bytes\n"
|
||||
" Encoding: %s",
|
||||
this->size_, this->uncompressed_size_, ENCODING);
|
||||
}
|
||||
|
||||
void StoreYamlComponent::read_chunk(size_t pos, uint8_t *dst, size_t len) const {
|
||||
const uint8_t *src = this->data_ + pos;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
dst[i] = progmem_read_byte(&src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace esphome::store_yaml
|
||||
|
||||
@@ -23,11 +23,19 @@ class StoreYamlComponent : public Component {
|
||||
this->size_ = size;
|
||||
this->uncompressed_size_ = uncompressed_size;
|
||||
}
|
||||
const uint8_t *get_data() const { return this->data_; }
|
||||
size_t get_size() const { return this->size_; }
|
||||
size_t get_uncompressed_size() const { return this->uncompressed_size_; }
|
||||
|
||||
// Copy `len` bytes from the PROGMEM blob at offset `pos` into `dst`.
|
||||
// Hides the platform-specific read (no-op everywhere except ESP8266, where the
|
||||
// blob lives in code space and must be read through `progmem_read_byte`).
|
||||
void read_chunk(size_t pos, uint8_t *dst, size_t len) const;
|
||||
|
||||
protected:
|
||||
// Points to a `const uint8_t[] PROGMEM` array emitted by codegen. On ESP8266 this
|
||||
// address is in instruction flash and must be accessed via `progmem_read_byte` —
|
||||
// hence the `read_chunk` accessor above. There is no public getter for the raw
|
||||
// pointer; callers must go through `read_chunk`.
|
||||
const uint8_t *data_{nullptr};
|
||||
size_t size_{0};
|
||||
size_t uncompressed_size_{0};
|
||||
|
||||
Reference in New Issue
Block a user