Merge branch 'feature/nvs_cxx_enums' into 'master'

Enabled enum types for nvs C++ handle

See merge request espressif/esp-idf!8700
This commit is contained in:
Ivan Grokhotkov 2020-06-02 01:13:00 +08:00
commit b40c7c78e3
2 changed files with 182 additions and 2 deletions

View file

@ -47,9 +47,11 @@ public:
* @param[in] key Key name. Maximal length is determined by the underlying
* implementation, but is guaranteed to be at least
* 15 characters. Shouldn't be empty.
* @param[in] value The value to set. Allowed types are the ones declared in ItemType.
* @param[in] value The value to set. Allowed types are the ones declared in ItemType as well as enums.
* For strings, the maximum length (including null character) is
* 4000 bytes.
* Note that enums loose their type information when stored in NVS. Ensure that the correct
* enum type is used during retrieval with \ref get_item!
*
* @return
* - ESP_OK if value was set successfully
@ -80,7 +82,9 @@ public:
* @param[in] key Key name. Maximal length is determined by the underlying
* implementation, but is guaranteed to be at least
* 15 characters. Shouldn't be empty.
* @param value The output value.
* @param value The output value. All integral types which are declared in ItemType as well as enums
* are allowed. Note however that enums lost their type information when stored in NVS.
* Ensure that the correct enum type is used during retrieval with \ref get_item!
*
* @return
* - ESP_OK if the value was retrieved successfully
@ -233,12 +237,24 @@ std::unique_ptr<NVSHandle> open_nvs_handle(const char *ns_name,
esp_err_t *err = nullptr);
// Helper functions for template usage
/**
* Help to translate all integral types into ItemType.
*/
template<typename T, typename std::enable_if<std::is_integral<T>::value, void*>::type = nullptr>
constexpr ItemType itemTypeOf()
{
return static_cast<ItemType>(((std::is_signed<T>::value)?0x10:0x00) | sizeof(T));
}
/**
* Help to translate all enum types into integral ItemType.
*/
template<typename T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
constexpr ItemType itemTypeOf()
{
return static_cast<ItemType>(((std::is_signed<T>::value)?0x10:0x00) | sizeof(T));
}
template<typename T>
constexpr ItemType itemTypeOf(const T&)
{

View file

@ -20,6 +20,7 @@
#include "spi_flash_emulation.h"
#include <iostream>
#include <string>
using namespace std;
using namespace nvs;
@ -114,3 +115,166 @@ TEST_CASE("nvshandle readonly fails", "[partition_mgr]")
CHECK(nvs_flash_deinit_partition(NVS_DEFAULT_PART_NAME) == ESP_OK);
}
TEST_CASE("NVSHandleSimple set/get char", "[partition_mgr]")
{
enum class TestEnum : char {
FOO = -1,
BEER,
BAR
};
SpiFlashEmulator emu(10);
const uint32_t NVS_FLASH_SECTOR = 6;
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
REQUIRE(NVSPartitionManager::get_instance()->init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)
== ESP_OK);
NVSHandleSimple *handle;
REQUIRE(NVSPartitionManager::get_instance()->open_handle(NVS_DEFAULT_PART_NAME, "ns_1", NVS_READWRITE, &handle) == ESP_OK);
char test_e = 'a';
char test_e_read = 'z';
CHECK(handle->set_item("key", test_e) == ESP_OK);
CHECK(handle->get_item("key", test_e_read) == ESP_OK);
CHECK(test_e == test_e_read);
delete handle;
REQUIRE(NVSPartitionManager::get_instance()->deinit_partition(NVS_DEFAULT_PART_NAME) == ESP_OK);
}
TEST_CASE("NVSHandleSimple correctly sets/gets int enum", "[partition_mgr]")
{
enum class TestEnum : int {
FOO,
BAR
};
SpiFlashEmulator emu(10);
const uint32_t NVS_FLASH_SECTOR = 6;
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
REQUIRE(NVSPartitionManager::get_instance()->init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)
== ESP_OK);
NVSHandleSimple *handle;
REQUIRE(NVSPartitionManager::get_instance()->open_handle(NVS_DEFAULT_PART_NAME, "ns_1", NVS_READWRITE, &handle) == ESP_OK);
TestEnum test_e = TestEnum::BAR;
TestEnum test_e_read = TestEnum::FOO;
CHECK(handle->set_item("key", test_e) == ESP_OK);
CHECK(handle->get_item("key", test_e_read) == ESP_OK);
CHECK(test_e == test_e_read);
delete handle;
REQUIRE(NVSPartitionManager::get_instance()->deinit_partition(NVS_DEFAULT_PART_NAME) == ESP_OK);
}
TEST_CASE("NVSHandleSimple correctly sets/gets int enum with negative values", "[partition_mgr]")
{
enum class TestEnum : int {
FOO = -1,
BEER,
BAR
};
SpiFlashEmulator emu(10);
const uint32_t NVS_FLASH_SECTOR = 6;
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
REQUIRE(NVSPartitionManager::get_instance()->init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)
== ESP_OK);
NVSHandleSimple *handle;
REQUIRE(NVSPartitionManager::get_instance()->open_handle(NVS_DEFAULT_PART_NAME, "ns_1", NVS_READWRITE, &handle) == ESP_OK);
TestEnum test_e = TestEnum::FOO;
TestEnum test_e_read = TestEnum::BEER;
CHECK(handle->set_item("key", test_e) == ESP_OK);
CHECK(handle->get_item("key", test_e_read) == ESP_OK);
CHECK(test_e == test_e_read);
delete handle;
REQUIRE(NVSPartitionManager::get_instance()->deinit_partition(NVS_DEFAULT_PART_NAME) == ESP_OK);
}
TEST_CASE("NVSHandleSimple correctly sets/gets uint8_t enum", "[partition_mgr]")
{
enum class TestEnum : uint8_t {
FOO,
BAR
};
SpiFlashEmulator emu(10);
const uint32_t NVS_FLASH_SECTOR = 6;
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
REQUIRE(NVSPartitionManager::get_instance()->init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)
== ESP_OK);
NVSHandleSimple *handle;
REQUIRE(NVSPartitionManager::get_instance()->open_handle(NVS_DEFAULT_PART_NAME, "ns_1", NVS_READWRITE, &handle) == ESP_OK);
TestEnum test_e = TestEnum::BAR;
TestEnum test_e_read = TestEnum::FOO;
CHECK(handle->set_item("key", test_e) == ESP_OK);
CHECK(handle->get_item("key", test_e_read) == ESP_OK);
CHECK(test_e == test_e_read);
delete handle;
REQUIRE(NVSPartitionManager::get_instance()->deinit_partition(NVS_DEFAULT_PART_NAME) == ESP_OK);
}
TEST_CASE("NVSHandleSimple correctly sets/gets char enum", "[partition_mgr]")
{
enum class TestEnum : char {
FOO = -1,
BEER,
BAR
};
SpiFlashEmulator emu(10);
const uint32_t NVS_FLASH_SECTOR = 6;
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
REQUIRE(NVSPartitionManager::get_instance()->init_custom(NVS_DEFAULT_PART_NAME, NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)
== ESP_OK);
NVSHandleSimple *handle;
REQUIRE(NVSPartitionManager::get_instance()->open_handle(NVS_DEFAULT_PART_NAME, "ns_1", NVS_READWRITE, &handle) == ESP_OK);
TestEnum test_e = TestEnum::BAR;
TestEnum test_e_read = TestEnum::FOO;
CHECK(handle->set_item("key", test_e) == ESP_OK);
CHECK(handle->get_item("key", test_e_read) == ESP_OK);
CHECK(test_e == test_e_read);
delete handle;
REQUIRE(NVSPartitionManager::get_instance()->deinit_partition(NVS_DEFAULT_PART_NAME) == ESP_OK);
}