Enhance NVSStorageHandler with filtering capabilities and update constructor to accept namespace
This commit is contained in:
12
main/io/io.h
12
main/io/io.h
@@ -2,6 +2,9 @@
|
|||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/event_groups.h"
|
#include "freertos/event_groups.h"
|
||||||
|
|
||||||
|
typedef bool(*FilterFunc)(const char* const& key);
|
||||||
|
typedef void (*KeyValueProcessor)(void* arg, const char* const& key, const char* const& value);
|
||||||
|
|
||||||
class KVStorageHandler {
|
class KVStorageHandler {
|
||||||
public:
|
public:
|
||||||
virtual ~KVStorageHandler() = default;
|
virtual ~KVStorageHandler() = default;
|
||||||
@@ -9,12 +12,15 @@ public:
|
|||||||
virtual void init(const EventGroupHandle_t& system_event_group) = 0;
|
virtual void init(const EventGroupHandle_t& system_event_group) = 0;
|
||||||
|
|
||||||
// Store a key-value pair
|
// Store a key-value pair
|
||||||
virtual void put(const char*& key, const char*& value) = 0;
|
virtual void put(const char* const& key, const char* const& value) = 0;
|
||||||
|
|
||||||
// Retrieve a value by key, returns nullptr if key not found
|
// Retrieve a value by key, returns nullptr if key not found
|
||||||
// The caller is responsible for freeing the returned memory
|
// The caller is responsible for freeing the returned memory
|
||||||
virtual char* get(const char*& key) const = 0;
|
virtual char* get(const char* const& key) const = 0;
|
||||||
|
virtual esp_err_t process_all(KeyValueProcessor processor, void* arg) const = 0;
|
||||||
|
virtual esp_err_t process_filtered(const char* const& key_prefix, KeyValueProcessor processor, void* arg) const = 0;
|
||||||
|
virtual esp_err_t process_filtered(FilterFunc filter_func, KeyValueProcessor processor, void* arg) const = 0;
|
||||||
|
|
||||||
// Delete a key-value pair
|
// Delete a key-value pair
|
||||||
virtual void remove(const char*& key) = 0;
|
virtual void remove(const char* const& key) = 0;
|
||||||
};
|
};
|
||||||
@@ -1,6 +1,11 @@
|
|||||||
#include "common/constants.h"
|
#include "common/constants.h"
|
||||||
#include "io/nvs_handler.h"
|
#include "io/nvs_handler.h"
|
||||||
#include "nvs_flash.h"
|
#include "nvs_flash.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
NVSStorageHandler::NVSStorageHandler(
|
||||||
|
const char* name_space
|
||||||
|
) : name_space(name_space) { }
|
||||||
|
|
||||||
NVSStorageHandler::~NVSStorageHandler() {
|
NVSStorageHandler::~NVSStorageHandler() {
|
||||||
if (this->nvsHandle != 0) {
|
if (this->nvsHandle != 0) {
|
||||||
@@ -17,7 +22,7 @@ void NVSStorageHandler::init(const EventGroupHandle_t& system_event_group) {
|
|||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(err);
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
err = nvs_open("storage", NVS_READWRITE, &this->nvsHandle);
|
err = nvs_open(this->name_space, NVS_READWRITE, &this->nvsHandle);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));
|
printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));
|
||||||
} else {
|
} else {
|
||||||
@@ -26,7 +31,7 @@ void NVSStorageHandler::init(const EventGroupHandle_t& system_event_group) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NVSStorageHandler::put(const char*& key, const char*& value) {
|
void NVSStorageHandler::put(const char* const& key, const char* const& value) {
|
||||||
if (this->nvsHandle == 0) {
|
if (this->nvsHandle == 0) {
|
||||||
printf("NVS handle is not initialized.\n");
|
printf("NVS handle is not initialized.\n");
|
||||||
return;
|
return;
|
||||||
@@ -41,7 +46,7 @@ void NVSStorageHandler::put(const char*& key, const char*& value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* NVSStorageHandler::get(const char*& key) const {
|
char* NVSStorageHandler::get(const char* const& key) const {
|
||||||
if (this->nvsHandle == 0) {
|
if (this->nvsHandle == 0) {
|
||||||
printf("NVS handle is not initialized.\n");
|
printf("NVS handle is not initialized.\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -68,7 +73,102 @@ char* NVSStorageHandler::get(const char*& key) const {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NVSStorageHandler::remove(const char*& key) {
|
NVSIteratorGuard NVSStorageHandler::create_iterator() const {
|
||||||
|
nvs_iterator_t it = nullptr;
|
||||||
|
esp_err_t err = nvs_entry_find(NVS_DEFAULT_PART_NAME, this->name_space, NVS_TYPE_ANY, &it);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
printf("Error (%s) creating NVS iterator!\n", esp_err_to_name(err));
|
||||||
|
return NVSIteratorGuard(nullptr, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NVSIteratorGuard(it, ESP_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t NVSStorageHandler::process_all(KeyValueProcessor processor, void* arg) const {
|
||||||
|
NVSIteratorGuard iterator_guard = this->create_iterator();
|
||||||
|
if (!iterator_guard.is_valid()) {
|
||||||
|
return iterator_guard.get_error();
|
||||||
|
}
|
||||||
|
const nvs_iterator_t& it = iterator_guard.get_iterator();
|
||||||
|
|
||||||
|
for (; it != NULL; iterator_guard.advance_iter()) {
|
||||||
|
nvs_entry_info_t info;
|
||||||
|
esp_err_t err = nvs_entry_info(it, &info);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
printf("Error (%s) getting NVS entry info!\n", esp_err_to_name(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
nvs_handle_t temp_handle;
|
||||||
|
err = nvs_open(this->name_space, NVS_READONLY, &temp_handle);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
printf("Error (%s) opening NVS handle for reading!\n", esp_err_to_name(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// call the processor with the key and value
|
||||||
|
processor(arg, info.key, this->get(info.key));
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
esp_err_t NVSStorageHandler::process_filtered(const char* const& key_prefix, KeyValueProcessor processor, void* arg) const {
|
||||||
|
NVSIteratorGuard iterator_guard = this->create_iterator();
|
||||||
|
if (!iterator_guard.is_valid()) {
|
||||||
|
return iterator_guard.get_error();
|
||||||
|
}
|
||||||
|
const nvs_iterator_t& it = iterator_guard.get_iterator();
|
||||||
|
|
||||||
|
for (; it != NULL; iterator_guard.advance_iter()) {
|
||||||
|
nvs_entry_info_t info;
|
||||||
|
esp_err_t err = nvs_entry_info(it, &info);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
printf("Error (%s) getting NVS entry info!\n", esp_err_to_name(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
// check if the key matches the prefix
|
||||||
|
if (strncmp(info.key, key_prefix, strlen(key_prefix)) == 0) {
|
||||||
|
nvs_handle_t temp_handle;
|
||||||
|
err = nvs_open(this->name_space, NVS_READONLY, &temp_handle);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
printf("Error (%s) opening NVS handle for reading!\n", esp_err_to_name(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
// call the processor with the key and value
|
||||||
|
processor(arg, info.key, this->get(info.key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t NVSStorageHandler::process_filtered(FilterFunc filter_func, KeyValueProcessor processor, void* arg) const {
|
||||||
|
NVSIteratorGuard iterator_guard = this->create_iterator();
|
||||||
|
if (!iterator_guard.is_valid()) {
|
||||||
|
return iterator_guard.get_error();
|
||||||
|
}
|
||||||
|
const nvs_iterator_t& it = iterator_guard.get_iterator();
|
||||||
|
|
||||||
|
for (; it != NULL; iterator_guard.advance_iter()) {
|
||||||
|
nvs_entry_info_t info;
|
||||||
|
esp_err_t err = nvs_entry_info(it, &info);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
printf("Error (%s) getting NVS entry info!\n", esp_err_to_name(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
// check if the key matches the filter function
|
||||||
|
if (filter_func(info.key)) {
|
||||||
|
nvs_handle_t temp_handle;
|
||||||
|
err = nvs_open(this->name_space, NVS_READONLY, &temp_handle);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
printf("Error (%s) opening NVS handle for reading!\n", esp_err_to_name(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
// call the processor with the key and value
|
||||||
|
processor(arg, info.key, this->get(info.key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NVSStorageHandler::remove(const char* const& key) {
|
||||||
if (this->nvsHandle == 0) {
|
if (this->nvsHandle == 0) {
|
||||||
printf("NVS handle is not initialized.\n");
|
printf("NVS handle is not initialized.\n");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -5,17 +5,61 @@
|
|||||||
|
|
||||||
class NVSStorageHandler : public KVStorageHandler {
|
class NVSStorageHandler : public KVStorageHandler {
|
||||||
public:
|
public:
|
||||||
NVSStorageHandler() = default;
|
NVSStorageHandler(
|
||||||
|
const char* name_space
|
||||||
|
);
|
||||||
~NVSStorageHandler() override;
|
~NVSStorageHandler() override;
|
||||||
|
|
||||||
void init(const EventGroupHandle_t& system_event_group) override;
|
void init(const EventGroupHandle_t& system_event_group) override;
|
||||||
|
|
||||||
void put(const char*& key, const char*& value) override;
|
void put(const char* const& key, const char* const& value) override;
|
||||||
|
|
||||||
char* get(const char*& key) const override;
|
char* get(const char* const& key) const override;
|
||||||
|
esp_err_t process_all(KeyValueProcessor processor, void* arg) const override;
|
||||||
|
esp_err_t process_filtered(const char* const& key_prefix, KeyValueProcessor processor, void* arg) const override;
|
||||||
|
esp_err_t process_filtered(FilterFunc filter_func, KeyValueProcessor processor, void* arg) const override;
|
||||||
|
|
||||||
void remove(const char*& key) override;
|
void remove(const char* const& key) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
NVSIteratorGuard create_iterator() const;
|
||||||
|
|
||||||
nvs_handle_t nvsHandle = 0;
|
nvs_handle_t nvsHandle = 0;
|
||||||
|
const char* name_space;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NVSIteratorGuard {
|
||||||
|
public:
|
||||||
|
~NVSIteratorGuard() {
|
||||||
|
if (iterator) {
|
||||||
|
nvs_release_iterator(iterator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const nvs_iterator_t const& get_iterator() const {
|
||||||
|
return iterator;
|
||||||
|
}
|
||||||
|
void advance_iter() {
|
||||||
|
if (iterator) {
|
||||||
|
// advance the iterator and update the internal state
|
||||||
|
esp_err_t err = nvs_entry_next(&iterator);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
error = err;
|
||||||
|
iterator = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t get_error() const {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
bool is_valid() const {
|
||||||
|
return iterator != nullptr && error == ESP_OK;
|
||||||
|
}
|
||||||
|
friend class NVSStorageHandler;
|
||||||
|
private:
|
||||||
|
NVSIteratorGuard(nvs_iterator_t it
|
||||||
|
, esp_err_t err
|
||||||
|
) : iterator(it), error(err) { }
|
||||||
|
nvs_iterator_t iterator;
|
||||||
|
esp_err_t error;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ void app_main(void) {
|
|||||||
throw std::runtime_error("Failed to create LVGL mutex");
|
throw std::runtime_error("Failed to create LVGL mutex");
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
KVStorageHandler* kv_storage_handler = new NVSStorageHandler();
|
KVStorageHandler* kv_storage_handler = new NVSStorageHandler(
|
||||||
|
"storage"
|
||||||
|
);
|
||||||
DisplayHandler* display_handler = new EInkDisplayHandler(touch_event_queue, lvgl_mutex);
|
DisplayHandler* display_handler = new EInkDisplayHandler(touch_event_queue, lvgl_mutex);
|
||||||
TouchHandler* touch_handler = new EInkTouchHandler(touch_event_queue);
|
TouchHandler* touch_handler = new EInkTouchHandler(touch_event_queue);
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user