From 6879d15ce4c277968d4f1e286d3c70c91e14750d Mon Sep 17 00:00:00 2001 From: Maschell Date: Thu, 14 Dec 2023 17:20:38 +0100 Subject: [PATCH] StorageAPI improvements --- include/wups/config/WUPSConfigItemBoolean.h | 1 - include/wups/hooks.h | 2 +- include/wups/storage.h | 433 ++++++-- libraries/libwups/WUPSConfigItemBoolean.cpp | 1 + .../libwups/WUPSConfigItemIntegerRange.cpp | 1 + .../libwups/WUPSConfigItemMultipleValues.cpp | 1 + libraries/libwups/WUPSConfigItemStub.cpp | 2 + libraries/libwups/storage.cpp | 243 ++--- libraries/libwups/storageCPP.cpp | 136 +++ plugins/example_plugin/src/main.c | 42 +- plugins/example_plugin_cpp/src/main.cpp | 44 +- plugins/storage_test_plugin/src/test.cpp | 928 ++++++------------ 12 files changed, 909 insertions(+), 925 deletions(-) create mode 100644 libraries/libwups/storageCPP.cpp diff --git a/include/wups/config/WUPSConfigItemBoolean.h b/include/wups/config/WUPSConfigItemBoolean.h index 942956a..7e5c1ac 100644 --- a/include/wups/config/WUPSConfigItemBoolean.h +++ b/include/wups/config/WUPSConfigItemBoolean.h @@ -1,6 +1,5 @@ #pragma once -#include "WUPSConfigItem.h" #include #ifdef __cplusplus diff --git a/include/wups/hooks.h b/include/wups/hooks.h index 8484254..a416f46 100644 --- a/include/wups/hooks.h +++ b/include/wups/hooks.h @@ -111,7 +111,7 @@ typedef struct wups_loader_hook_t { void init_storage(wups_loader_init_storage_args_t); \ WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_STORAGE, init_storage); \ void init_storage(wups_loader_init_storage_args_t args) { \ - WUPS_InitStorage(args); \ + WUPSStorageAPI_InitInternal(args); \ } diff --git a/include/wups/storage.h b/include/wups/storage.h index 587ea3d..6004166 100644 --- a/include/wups/storage.h +++ b/include/wups/storage.h @@ -6,19 +6,20 @@ extern "C" { #include #include +#include typedef enum { - WUPS_STORAGE_ERROR_SUCCESS = 0, - WUPS_STORAGE_ERROR_INVALID_ARGS = 1, - WUPS_STORAGE_ERROR_INVALID_POINTER = 2, - WUPS_STORAGE_ERROR_INVALID_VERSION = 3, - WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE = 4, - WUPS_STORAGE_ERROR_NOT_FOUND = 5, - WUPS_STORAGE_ERROR_MALLOC_FAILED = 6, - WUPS_STORAGE_ERROR_ALREADY_OPENED = 7, - WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL = 8, - WUPS_STORAGE_ERROR_ALREADY_EXISTS = 9, - WUPS_STORAGE_ERROR_UNKNOWN_ERROR = 10 + WUPS_STORAGE_ERROR_SUCCESS = 0, + WUPS_STORAGE_ERROR_INVALID_ARGS = -0x01, + WUPS_STORAGE_ERROR_MALLOC_FAILED = -0x02, + WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE = -0x03, + WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL = -0x04, + WUPS_STORAGE_ERROR_ALREADY_EXISTS = -0x05, + WUPS_STORAGE_ERROR_IO_ERROR = -0x06, + WUPS_STORAGE_ERROR_NOT_FOUND = -0x10, + WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED = -0xF0, + WUPS_STORAGE_ERROR_INTERNAL_INVALID_VERSION = -0xF1, + WUPS_STORAGE_ERROR_UNKNOWN_ERROR = -0x100, } WUPSStorageError; typedef enum { @@ -38,72 +39,386 @@ typedef uint32_t WUPSStorageItemType; typedef void *wups_storage_root_item; typedef void *wups_storage_item; -typedef WUPSStorageError (*OpenStorageFunction)(const char *plugin_id, wups_storage_root_item *root); -typedef WUPSStorageError (*CloseStorageFunction)(const char *plugin_id); -typedef WUPSStorageError (*DeleteItemFunction)(wups_storage_root_item root, wups_storage_item parent, const char *key); -typedef WUPSStorageError (*CreateSubItemFunction)(wups_storage_root_item root, wups_storage_item parent, const char *key, wups_storage_item *outItem); -typedef WUPSStorageError (*GetSubItemFunction)(wups_storage_root_item root, wups_storage_item parent, const char *key, wups_storage_item *outItem); -typedef WUPSStorageError (*StoreItemFunction)(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageItemType itemType, void *data, uint32_t length); -typedef WUPSStorageError (*GetItemFunction)(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageItemType itemType, void *data, uint32_t maxSize, uint32_t *outSize); -typedef WUPSStorageError (*GetItemSizeFunction)(wups_storage_root_item root, wups_storage_item parent, const char *key, uint32_t *outSize); +typedef WUPSStorageError (*WUPSStorage_SaveFunction)(wups_storage_root_item root, bool force); +typedef WUPSStorageError (*WUPSStorage_ForceReloadFunction)(wups_storage_root_item root); +typedef WUPSStorageError (*WUPSStorage_WipeStorageFunction)(wups_storage_root_item root); +typedef WUPSStorageError (*WUPSStorage_DeleteItemFunction)(wups_storage_root_item root, wups_storage_item parent, const char *key); +typedef WUPSStorageError (*WUPSStorage_CreateSubItemFunction)(wups_storage_root_item root, wups_storage_item parent, const char *key, wups_storage_item *outItem); +typedef WUPSStorageError (*WUPSStorage_GetSubItemFunction)(wups_storage_root_item root, wups_storage_item parent, const char *key, wups_storage_item *outItem); +typedef WUPSStorageError (*WUPSStorage_StoreItemFunction)(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageItemType itemType, void *data, uint32_t length); +typedef WUPSStorageError (*WUPSStorage_GetItemFunction)(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageItemType itemType, void *data, uint32_t maxSize, uint32_t *outSize); +typedef WUPSStorageError (*WUPSStorage_GetItemSizeFunction)(wups_storage_root_item root, wups_storage_item parent, const char *key, uint32_t *outSize); typedef uint32_t WUPS_STORAGE_API_VERSION; #define WUPS_STORAGE_CUR_API_VERSION 0x02 typedef struct wups_loader_init_storage_args_t_ { WUPS_STORAGE_API_VERSION version; - OpenStorageFunction open_storage_ptr; - CloseStorageFunction close_storage_ptr; - DeleteItemFunction delete_item_function_ptr; - CreateSubItemFunction create_sub_item_function_ptr; - GetSubItemFunction get_sub_item_function_ptr; - StoreItemFunction store_item_function_ptr; - GetItemFunction get_item_function_ptr; - GetItemSizeFunction get_item_size_function_ptr; - const char *plugin_id; + wups_storage_root_item root_item; + WUPSStorage_SaveFunction save_function_ptr; + WUPSStorage_ForceReloadFunction force_reload_function_ptr; + WUPSStorage_WipeStorageFunction wipe_storage_function_ptr; + WUPSStorage_DeleteItemFunction delete_item_function_ptr; + WUPSStorage_CreateSubItemFunction create_sub_item_function_ptr; + WUPSStorage_GetSubItemFunction get_sub_item_function_ptr; + WUPSStorage_StoreItemFunction store_item_function_ptr; + WUPSStorage_GetItemFunction get_item_function_ptr; + WUPSStorage_GetItemSizeFunction get_item_size_function_ptr; } wups_loader_init_storage_args_t; /* called by backend */ -WUPSStorageError WUPS_InitStorage(wups_loader_init_storage_args_t args); +WUPSStorageError WUPSStorageAPI_InitInternal(wups_loader_init_storage_args_t args); -const char *WUPS_GetStorageStatusStr(WUPSStorageError status); +const char *WUPSStorageAPI_GetStatusStr(WUPSStorageError status); -/* opens storage for reading and writing */ -WUPSStorageError WUPS_OpenStorage(void); +WUPSStorageError WUPSStorageAPI_SaveStorage(bool forceSave); +WUPSStorageError WUPSStorageAPI_ForceReloadStorage(); +WUPSStorageError WUPSStorageAPI_WipeStorage(); -/* closes storage and saves changes */ -WUPSStorageError WUPS_CloseStorage(void); +WUPSStorageError WUPSStorageAPI_DeleteItem(wups_storage_item parent, const char *key); -/* deletes key from storage */ -WUPSStorageError WUPS_DeleteItem(wups_storage_item parent, const char *key); +WUPSStorageError WUPSStorageAPI_CreateSubItem(wups_storage_item parent, const char *key, wups_storage_item *outItem); +WUPSStorageError WUPSStorageAPI_GetSubItem(wups_storage_item parent, const char *key, wups_storage_item *outItem); -WUPSStorageError WUPS_CreateSubItem(wups_storage_item parent, const char *key, wups_storage_item *outItem); -WUPSStorageError WUPS_GetSubItem(wups_storage_item parent, const char *key, wups_storage_item *outItem); +WUPSStorageError WUPSStorageAPI_StoreItem(wups_storage_item parent, const char *key, WUPSStorageItemType type, void *data, uint32_t size); -WUPSStorageError WUPS_StoreString(wups_storage_item parent, const char *key, const char *string); -WUPSStorageError WUPS_StoreBool(wups_storage_item parent, const char *key, bool value); -WUPSStorageError WUPS_StoreInt(wups_storage_item parent, const char *key, int32_t value); -WUPSStorageError WUPS_StoreS32(wups_storage_item parent, const char *key, int32_t value); -WUPSStorageError WUPS_StoreS64(wups_storage_item parent, const char *key, int64_t value); -WUPSStorageError WUPS_StoreU32(wups_storage_item parent, const char *key, uint32_t value); -WUPSStorageError WUPS_StoreU64(wups_storage_item parent, const char *key, uint64_t value); -WUPSStorageError WUPS_StoreFloat(wups_storage_item parent, const char *key, float value); -WUPSStorageError WUPS_StoreDouble(wups_storage_item parent, const char *key, double value); -WUPSStorageError WUPS_StoreBinary(wups_storage_item parent, const char *key, const void *data, uint32_t size); +inline WUPSStorageError WUPSStorageAPI_StoreString(wups_storage_item parent, const char *key, const char *value) { + if (value == NULL) { + return WUPS_STORAGE_ERROR_INVALID_ARGS; + } + return WUPSStorageAPI_StoreItem(parent, key, WUPS_STORAGE_ITEM_STRING, (void *) value, strlen(value)); +} -WUPSStorageError WUPS_GetString(wups_storage_item parent, const char *key, char *outString, uint32_t maxSize, uint32_t *outSize); -WUPSStorageError WUPS_GetBool(wups_storage_item parent, const char *key, bool *outValue); -WUPSStorageError WUPS_GetInt(wups_storage_item parent, const char *key, int32_t *outValue); -WUPSStorageError WUPS_GetS32(wups_storage_item parent, const char *key, int32_t *outValue); -WUPSStorageError WUPS_GetS64(wups_storage_item parent, const char *key, int64_t *outValue); -WUPSStorageError WUPS_GetU32(wups_storage_item parent, const char *key, uint32_t *outValue); -WUPSStorageError WUPS_GetU64(wups_storage_item parent, const char *key, uint64_t *outValue); -WUPSStorageError WUPS_GetFloat(wups_storage_item parent, const char *key, float *outValue); -WUPSStorageError WUPS_GetDouble(wups_storage_item parent, const char *key, double *outValue); -WUPSStorageError WUPS_GetBinary(wups_storage_item parent, const char *key, void *outData, uint32_t maxSize, uint32_t *outSize); +inline WUPSStorageError WUPSStorageAPI_StoreBool(wups_storage_item parent, const char *key, bool value) { + return WUPSStorageAPI_StoreItem(parent, key, WUPS_STORAGE_ITEM_BOOL, (void *) &value, sizeof(bool)); +} -WUPSStorageError WUPS_GetItemSize(wups_storage_item parent, const char *key, uint32_t *outSize); +inline WUPSStorageError WUPSStorageAPI_StoreInt(wups_storage_item parent, const char *key, int32_t value) { + return WUPSStorageAPI_StoreItem(parent, key, WUPS_STORAGE_ITEM_S32, (void *) &value, sizeof(int32_t)); +} + +inline WUPSStorageError WUPSStorageAPI_StoreS32(wups_storage_item parent, const char *key, int32_t value) { + return WUPSStorageAPI_StoreItem(parent, key, WUPS_STORAGE_ITEM_S32, (void *) &value, sizeof(int32_t)); +} + +inline WUPSStorageError WUPSStorageAPI_StoreS64(wups_storage_item parent, const char *key, int64_t value) { + return WUPSStorageAPI_StoreItem(parent, key, WUPS_STORAGE_ITEM_S64, (void *) &value, sizeof(int64_t)); +} + +inline WUPSStorageError WUPSStorageAPI_StoreU32(wups_storage_item parent, const char *key, uint32_t value) { + return WUPSStorageAPI_StoreItem(parent, key, WUPS_STORAGE_ITEM_U32, (void *) &value, sizeof(uint32_t)); +} + +inline WUPSStorageError WUPSStorageAPI_StoreU64(wups_storage_item parent, const char *key, uint64_t value) { + return WUPSStorageAPI_StoreItem(parent, key, WUPS_STORAGE_ITEM_U64, (void *) &value, sizeof(uint64_t)); +} + +inline WUPSStorageError WUPSStorageAPI_StoreFloat(wups_storage_item parent, const char *key, float value) { + return WUPSStorageAPI_StoreItem(parent, key, WUPS_STORAGE_ITEM_FLOAT, (void *) &value, sizeof(float)); +} + +inline WUPSStorageError WUPSStorageAPI_StoreDouble(wups_storage_item parent, const char *key, double value) { + return WUPSStorageAPI_StoreItem(parent, key, WUPS_STORAGE_ITEM_DOUBLE, (void *) &value, sizeof(double)); +} + +inline WUPSStorageError WUPSStorageAPI_StoreBinary(wups_storage_item parent, const char *key, const void *data, uint32_t size) { + if (data == NULL) { + return WUPS_STORAGE_ERROR_INVALID_ARGS; + } + return WUPSStorageAPI_StoreItem(parent, key, WUPS_STORAGE_ITEM_BINARY, (void *) data, size); +} + +WUPSStorageError WUPSStorageAPI_GetItem(wups_storage_item parent, const char *key, WUPSStorageItemType type, void *data, uint32_t maxSize, uint32_t *outSize); + +inline WUPSStorageError WUPSStorageAPI_GetString(wups_storage_item parent, const char *key, char *outString, uint32_t maxSize, uint32_t *outSize) { + return WUPSStorageAPI_GetItem(parent, key, WUPS_STORAGE_ITEM_STRING, outString, maxSize, outSize); +} + +inline WUPSStorageError WUPSStorageAPI_GetBool(wups_storage_item parent, const char *key, bool *outValue) { + return WUPSStorageAPI_GetItem(parent, key, WUPS_STORAGE_ITEM_BOOL, outValue, sizeof(*outValue), NULL); +} + +inline WUPSStorageError WUPSStorageAPI_GetInt(wups_storage_item parent, const char *key, int32_t *outValue) { + return WUPSStorageAPI_GetItem(parent, key, WUPS_STORAGE_ITEM_S32, outValue, sizeof(*outValue), NULL); +} + +inline WUPSStorageError WUPSStorageAPI_GetS32(wups_storage_item parent, const char *key, int32_t *outValue) { + return WUPSStorageAPI_GetItem(parent, key, WUPS_STORAGE_ITEM_S32, outValue, sizeof(*outValue), NULL); +} + +inline WUPSStorageError WUPSStorageAPI_GetS64(wups_storage_item parent, const char *key, int64_t *outValue) { + return WUPSStorageAPI_GetItem(parent, key, WUPS_STORAGE_ITEM_S64, outValue, sizeof(*outValue), NULL); +} + +inline WUPSStorageError WUPSStorageAPI_GetU32(wups_storage_item parent, const char *key, uint32_t *outValue) { + return WUPSStorageAPI_GetItem(parent, key, WUPS_STORAGE_ITEM_U32, outValue, sizeof(*outValue), NULL); +} + +inline WUPSStorageError WUPSStorageAPI_GetU64(wups_storage_item parent, const char *key, uint64_t *outValue) { + return WUPSStorageAPI_GetItem(parent, key, WUPS_STORAGE_ITEM_U64, outValue, sizeof(*outValue), NULL); +} + +inline WUPSStorageError WUPSStorageAPI_GetFloat(wups_storage_item parent, const char *key, float *outValue) { + return WUPSStorageAPI_GetItem(parent, key, WUPS_STORAGE_ITEM_FLOAT, outValue, sizeof(*outValue), NULL); +} + +inline WUPSStorageError WUPSStorageAPI_GetDouble(wups_storage_item parent, const char *key, double *outValue) { + return WUPSStorageAPI_GetItem(parent, key, WUPS_STORAGE_ITEM_DOUBLE, outValue, sizeof(*outValue), NULL); +} + +inline WUPSStorageError WUPSStorageAPI_GetBinary(wups_storage_item parent, const char *key, void *outData, uint32_t maxSize, uint32_t *outValue) { + return WUPSStorageAPI_GetItem(parent, key, WUPS_STORAGE_ITEM_BINARY, outData, maxSize, outValue); +} + +WUPSStorageError WUPSStorageAPI_GetItemSize(wups_storage_item parent, const char *key, uint32_t *outSize); #ifdef __cplusplus } #endif + +#ifdef __cplusplus + +#include +#include +#include +#include +#include +#include + +class WUPSStorageSubItem; + +namespace WUPSStorageAPI { + WUPSStorageError DeleteItem(std::string_view key) noexcept; + + WUPSStorageError SaveStorage(bool forceSave = false); + WUPSStorageError ForceReloadStorage(); + WUPSStorageError WipeStorage(); + + std::string_view GetStatusStr(const WUPSStorageError &err) noexcept; + + WUPSStorageSubItem GetRootItem() noexcept; + + std::optional CreateSubItem(std::string_view key, WUPSStorageError &err) noexcept; + std::optional GetSubItem(std::string_view key, WUPSStorageError &err) noexcept; + std::optional GetOrCreateSubItem(std::string_view key, WUPSStorageError &err) noexcept; + + WUPSStorageError GetItemSize(std::string_view key, uint32_t &outSize) noexcept; + + WUPSStorageSubItem CreateSubItem(std::string_view key); + WUPSStorageSubItem GetSubItem(std::string_view key); + WUPSStorageSubItem GetOrCreateSubItem(std::string_view key); + + template + inline WUPSStorageError GetEx(wups_storage_item parent, const char *key, T &outValue) noexcept; + + template<> + inline WUPSStorageError GetEx(wups_storage_item parent, const char *key, int32_t &outValue) noexcept { + return WUPSStorageAPI_GetS32(parent, key, &outValue); + } + + template<> + inline WUPSStorageError GetEx(wups_storage_item parent, const char *key, int64_t &outValue) noexcept { + return WUPSStorageAPI_GetS64(parent, key, &outValue); + } + + template<> + inline WUPSStorageError GetEx(wups_storage_item parent, const char *key, uint32_t &outValue) noexcept { + return WUPSStorageAPI_GetU32(parent, key, &outValue); + } + + template<> + inline WUPSStorageError GetEx(wups_storage_item parent, const char *key, uint64_t &outValue) noexcept { + return WUPSStorageAPI_GetU64(parent, key, &outValue); + } + + template<> + inline WUPSStorageError GetEx(wups_storage_item parent, const char *key, bool &outValue) noexcept { + return WUPSStorageAPI_GetBool(parent, key, &outValue); + } + + template<> + inline WUPSStorageError GetEx(wups_storage_item parent, const char *key, float &outValue) noexcept { + return WUPSStorageAPI_GetFloat(parent, key, &outValue); + } + + template<> + inline WUPSStorageError GetEx(wups_storage_item parent, const char *key, double &outValue) noexcept { + return WUPSStorageAPI_GetDouble(parent, key, &outValue); + } + + template + inline WUPSStorageError GetEx(wups_storage_item parent, const char *key, T &outValue) noexcept { + static_assert(sizeof(T) == sizeof(uint32_t) && std::is_enum::value, "T must be an enum of size sizeof(uint32_t)"); + return WUPSStorageAPI_GetU32(parent, key, (uint32_t *) &outValue); + } + + template<> + inline WUPSStorageError GetEx>(wups_storage_item parent, const char *key, std::vector &outValue) noexcept { + uint32_t outSize = 0; + + if (outValue.empty()) { + uint32_t resizeToSize = 0; + auto r = WUPSStorageAPI_GetItemSize(parent, key, &resizeToSize); + if (r == WUPS_STORAGE_ERROR_SUCCESS) { + outValue.resize(resizeToSize); + } else { + return r; + } + } + + auto res = WUPSStorageAPI_GetBinary(parent, key, outValue.data(), outValue.size(), &outSize); + if (res == WUPS_STORAGE_ERROR_SUCCESS) { + outValue.resize(outSize); + } else { + outValue.resize(0); + } + return res; + } + + template<> + inline WUPSStorageError GetEx(wups_storage_item parent, const char *key, std::string &outValue) noexcept { + uint32_t outSize = 0; + if (outValue.empty()) { + uint32_t resizeToSize = 0; + auto r = WUPSStorageAPI_GetItemSize(parent, key, &resizeToSize); + if (r == WUPS_STORAGE_ERROR_SUCCESS) { + outValue.resize(resizeToSize); + } else { + return r; + } + } + + auto res = WUPSStorageAPI_GetString(parent, key, outValue.data(), outValue.size(), &outSize); + if (res == WUPS_STORAGE_ERROR_SUCCESS) { + // outSize does count the null terminator as well, std::string's size() doesn't include a null terminator. + outValue.resize(strlen(outValue.c_str())); + } else { + outValue.resize(0); + } + return res; + } + + template + inline WUPSStorageError Get(const char *key, T &outValue) noexcept { + return GetEx(nullptr, key, outValue); + } + + template + inline WUPSStorageError StoreEx(wups_storage_item parent, const char *key, const T &value) noexcept; + + template<> + inline WUPSStorageError StoreEx(wups_storage_item parent, const char *key, const int32_t &value) noexcept { + return WUPSStorageAPI_StoreS32(parent, key, value); + } + + template<> + inline WUPSStorageError StoreEx(wups_storage_item parent, const char *key, const int64_t &value) noexcept { + return WUPSStorageAPI_StoreS64(parent, key, value); + } + + template<> + inline WUPSStorageError StoreEx(wups_storage_item parent, const char *key, const uint32_t &value) noexcept { + return WUPSStorageAPI_StoreU32(parent, key, value); + } + + template<> + inline WUPSStorageError StoreEx(wups_storage_item parent, const char *key, const uint64_t &value) noexcept { + return WUPSStorageAPI_StoreU64(parent, key, value); + } + + template<> + inline WUPSStorageError StoreEx(wups_storage_item parent, const char *key, const bool &value) noexcept { + return WUPSStorageAPI_StoreBool(parent, key, value); + } + + template<> + inline WUPSStorageError StoreEx(wups_storage_item parent, const char *key, const float &value) noexcept { + return WUPSStorageAPI_StoreFloat(parent, key, value); + } + + template<> + inline WUPSStorageError StoreEx(wups_storage_item parent, const char *key, const double &value) noexcept { + return WUPSStorageAPI_StoreDouble(parent, key, value); + } + + template<> + inline WUPSStorageError StoreEx>(wups_storage_item parent, const char *key, const std::vector &value) noexcept { + return WUPSStorageAPI_StoreBinary(parent, key, value.data(), value.size()); + } + + template<> + inline WUPSStorageError StoreEx(wups_storage_item parent, const char *key, const std::string &value) noexcept { + return WUPSStorageAPI_StoreString(parent, key, value.c_str()); + } + + template + inline WUPSStorageError StoreEx(wups_storage_item parent, const char *key, const T &value) noexcept { + static_assert(sizeof(T) == sizeof(uint32_t) && std::is_enum::value, "T must be an enum of size sizeof(uint32_t)"); + return WUPSStorageAPI_StoreU32(parent, key, (uint32_t) value); + } + + template + inline WUPSStorageError Store(const char *key, const T &value) noexcept { + return StoreEx(nullptr, key, value); + } + + template + inline WUPSStorageError GetOrStoreDefaultEx(wups_storage_item parent, const char *key, T &outValue, const T &defaultValue) noexcept { + WUPSStorageError err = GetEx(parent, key, outValue); + if (err == WUPS_STORAGE_ERROR_NOT_FOUND) { + err = StoreEx(parent, key, defaultValue); + } + return err; + } + + template + inline WUPSStorageError GetOrStoreDefault(const char *key, T &outValue, const T &defaultValue) noexcept { + return GetOrStoreDefaultEx(nullptr, key, outValue, defaultValue); + } +} // namespace WUPSStorageAPI + +class WUPSStorageSubItem { +public: + explicit WUPSStorageSubItem(wups_storage_item handle) : mHandle(handle) { + } + virtual ~WUPSStorageSubItem() = default; + + bool operator==(const WUPSStorageSubItem &rhs) const; + bool operator!=(const WUPSStorageSubItem &rhs) const; + + template + inline WUPSStorageError Store(const char *key, const T &value) noexcept { + return WUPSStorageAPI::StoreEx(mHandle, key, value); + } + + template + inline WUPSStorageError Get(const char *key, T &value) const noexcept { + return WUPSStorageAPI::GetEx(mHandle, key, value); + } + + template + inline WUPSStorageError GetOrStoreDefault(std::string_view key, T &outValue, const T &defaultValue) const noexcept { + return WUPSStorageAPI::GetOrStoreDefaultEx(mHandle, key.data(), outValue, defaultValue); + } + + WUPSStorageError DeleteItem(std::string_view view) noexcept; + + WUPSStorageError GetItemSize(std::string_view view, uint32_t &outSize) noexcept; + + std::optional CreateSubItem(std::string_view key, WUPSStorageError &err) noexcept; + + std::optional GetSubItem(std::string_view key, WUPSStorageError &err) const noexcept; + + std::optional GetOrCreateSubItem(std::string_view key, WUPSStorageError &err) noexcept; + + [[nodiscard]] WUPSStorageSubItem CreateSubItem(std::string_view key); + + [[nodiscard]] WUPSStorageSubItem GetSubItem(std::string_view key) const; + + [[nodiscard]] WUPSStorageSubItem GetOrCreateSubItem(std::string_view key); + +private: + wups_storage_item mHandle = {}; +}; + +#endif diff --git a/libraries/libwups/WUPSConfigItemBoolean.cpp b/libraries/libwups/WUPSConfigItemBoolean.cpp index fec1675..0c4270a 100644 --- a/libraries/libwups/WUPSConfigItemBoolean.cpp +++ b/libraries/libwups/WUPSConfigItemBoolean.cpp @@ -1,4 +1,5 @@ #include "wups/config/WUPSConfigItemBoolean.h" +#include "wups/config_api.h" #include #include #include diff --git a/libraries/libwups/WUPSConfigItemIntegerRange.cpp b/libraries/libwups/WUPSConfigItemIntegerRange.cpp index 6ee95e1..d9189cd 100644 --- a/libraries/libwups/WUPSConfigItemIntegerRange.cpp +++ b/libraries/libwups/WUPSConfigItemIntegerRange.cpp @@ -1,4 +1,5 @@ #include "wups/config/WUPSConfigItemIntegerRange.h" +#include "wups/config_api.h" #include #include #include diff --git a/libraries/libwups/WUPSConfigItemMultipleValues.cpp b/libraries/libwups/WUPSConfigItemMultipleValues.cpp index 7d51806..15d40a9 100644 --- a/libraries/libwups/WUPSConfigItemMultipleValues.cpp +++ b/libraries/libwups/WUPSConfigItemMultipleValues.cpp @@ -1,4 +1,5 @@ #include "wups/config/WUPSConfigItemMultipleValues.h" +#include "wups/config_api.h" #include #include #include diff --git a/libraries/libwups/WUPSConfigItemStub.cpp b/libraries/libwups/WUPSConfigItemStub.cpp index c8f977d..4c5c4eb 100644 --- a/libraries/libwups/WUPSConfigItemStub.cpp +++ b/libraries/libwups/WUPSConfigItemStub.cpp @@ -1,6 +1,8 @@ #include "wups/config/WUPSConfigItemStub.h" +#include "wups/config_api.h" #include #include +#include static int32_t WUPSConfigItemStub_getEmptyTextValue(void *context, char *out_buf, int32_t out_size) { memset(out_buf, 0, out_size); diff --git a/libraries/libwups/storage.cpp b/libraries/libwups/storage.cpp index bd5c2de..4d2ed02 100644 --- a/libraries/libwups/storage.cpp +++ b/libraries/libwups/storage.cpp @@ -2,27 +2,29 @@ #include struct wups_internal_functions_t { - OpenStorageFunction openfunction_ptr = nullptr; - CloseStorageFunction closefunction_ptr = nullptr; - DeleteItemFunction delete_item_function_ptr = nullptr; - CreateSubItemFunction create_sub_item_function_ptr = nullptr; - GetSubItemFunction get_sub_item_function_ptr = nullptr; - StoreItemFunction store_item_function_ptr = nullptr; - GetItemFunction get_item_function_ptr = nullptr; - GetItemSizeFunction get_item_size_function_ptr = nullptr; - char plugin_id[256]{}; - wups_storage_root_item __storageroot_item = nullptr; + WUPSStorage_SaveFunction save_function_ptr = nullptr; + WUPSStorage_ForceReloadFunction force_reload_function_ptr = nullptr; + WUPSStorage_WipeStorageFunction wipe_storage_function_ptr = nullptr; + WUPSStorage_DeleteItemFunction delete_item_function_ptr = nullptr; + WUPSStorage_CreateSubItemFunction create_sub_item_function_ptr = nullptr; + WUPSStorage_GetSubItemFunction get_sub_item_function_ptr = nullptr; + WUPSStorage_StoreItemFunction store_item_function_ptr = nullptr; + WUPSStorage_GetItemFunction get_item_function_ptr = nullptr; + WUPSStorage_GetItemSizeFunction get_item_size_function_ptr = nullptr; + wups_storage_root_item __storageroot_item = nullptr; }; static wups_internal_functions_t __internal_functions __attribute__((section(".data"))) = {}; -WUPSStorageError WUPS_InitStorage(wups_loader_init_storage_args_t args) { +WUPSStorageError WUPSStorageAPI_InitInternal(wups_loader_init_storage_args_t args) { if (args.version > WUPS_STORAGE_CUR_API_VERSION) { __internal_functions = {}; - return WUPS_STORAGE_ERROR_INVALID_VERSION; + return WUPS_STORAGE_ERROR_INTERNAL_INVALID_VERSION; } - __internal_functions.openfunction_ptr = args.open_storage_ptr; - __internal_functions.closefunction_ptr = args.close_storage_ptr; + __internal_functions.__storageroot_item = args.root_item; + __internal_functions.save_function_ptr = args.save_function_ptr; + __internal_functions.force_reload_function_ptr = args.force_reload_function_ptr; + __internal_functions.wipe_storage_function_ptr = args.wipe_storage_function_ptr; __internal_functions.delete_item_function_ptr = args.delete_item_function_ptr; __internal_functions.create_sub_item_function_ptr = args.create_sub_item_function_ptr; __internal_functions.get_sub_item_function_ptr = args.get_sub_item_function_ptr; @@ -30,220 +32,127 @@ WUPSStorageError WUPS_InitStorage(wups_loader_init_storage_args_t args) { __internal_functions.get_item_function_ptr = args.get_item_function_ptr; __internal_functions.get_item_size_function_ptr = args.get_item_size_function_ptr; - strncpy(__internal_functions.plugin_id, args.plugin_id, sizeof(__internal_functions.plugin_id) - 1); return WUPS_STORAGE_ERROR_SUCCESS; } -const char *WUPS_GetStorageStatusStr(WUPSStorageError status) { +const char *WUPSStorageAPI_GetStatusStr(WUPSStorageError status) { switch (status) { case WUPS_STORAGE_ERROR_SUCCESS: return "WUPS_STORAGE_ERROR_SUCCESS"; case WUPS_STORAGE_ERROR_INVALID_ARGS: return "WUPS_STORAGE_ERROR_INVALID_ARGS"; - case WUPS_STORAGE_ERROR_INVALID_POINTER: - return "WUPS_STORAGE_ERROR_INVALID_POINTER"; - case WUPS_STORAGE_ERROR_INVALID_VERSION: - return "WUPS_STORAGE_ERROR_INVALID_VERSION"; - case WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE: - return "WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE"; - case WUPS_STORAGE_ERROR_NOT_FOUND: - return "WUPS_STORAGE_ERROR_NOT_FOUND"; case WUPS_STORAGE_ERROR_MALLOC_FAILED: return "WUPS_STORAGE_ERROR_MALLOC_FAILED"; - case WUPS_STORAGE_ERROR_ALREADY_OPENED: - return "WUPS_STORAGE_ERROR_ALREADY_OPENED"; + case WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE: + return "WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE"; case WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL: return "WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL"; case WUPS_STORAGE_ERROR_ALREADY_EXISTS: return "WUPS_STORAGE_ERROR_ALREADY_EXISTS"; + case WUPS_STORAGE_ERROR_IO_ERROR: + return "WUPS_STORAGE_ERROR_IO_ERROR"; + case WUPS_STORAGE_ERROR_NOT_FOUND: + return "WUPS_STORAGE_ERROR_NOT_FOUND"; + case WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED: + return "WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED"; + case WUPS_STORAGE_ERROR_INTERNAL_INVALID_VERSION: + return "WUPS_STORAGE_ERROR_INTERNAL_INVALID_VERSION"; case WUPS_STORAGE_ERROR_UNKNOWN_ERROR: return "WUPS_STORAGE_ERROR_UNKNOWN_ERROR"; } return "WUPS_STORAGE_ERROR_UNKNOWN"; } -WUPSStorageError WUPS_OpenStorage(void) { - if (__internal_functions.openfunction_ptr == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_POINTER; +WUPSStorageError WUPSStorageAPI_SaveStorage(bool force) { + if (__internal_functions.save_function_ptr == nullptr) { + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; } - auto res = __internal_functions.openfunction_ptr(__internal_functions.plugin_id, &__internal_functions.__storageroot_item); - if (res != WUPS_STORAGE_ERROR_SUCCESS) { - __internal_functions.__storageroot_item = nullptr; + if (__internal_functions.__storageroot_item == nullptr) { + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; } - return res; + return __internal_functions.save_function_ptr(__internal_functions.__storageroot_item, force); } -WUPSStorageError WUPS_CloseStorage(void) { - if (__internal_functions.closefunction_ptr == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_POINTER; +WUPSStorageError WUPSStorageAPI_ForceReloadStorage() { + if (__internal_functions.force_reload_function_ptr == nullptr) { + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; } - auto res = __internal_functions.closefunction_ptr(__internal_functions.plugin_id); - if (res == WUPS_STORAGE_ERROR_SUCCESS) { - __internal_functions.__storageroot_item = nullptr; + if (__internal_functions.__storageroot_item == nullptr) { + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; } - return res; + return __internal_functions.force_reload_function_ptr(__internal_functions.__storageroot_item); } -WUPSStorageError WUPS_DeleteItem(wups_storage_item parent, const char *key) { +WUPSStorageError WUPSStorageAPI_WipeStorage() { + if (__internal_functions.wipe_storage_function_ptr == nullptr) { + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; + } + if (__internal_functions.__storageroot_item == nullptr) { + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; + } + return __internal_functions.wipe_storage_function_ptr(__internal_functions.__storageroot_item); +} + +WUPSStorageError WUPSStorageAPI_DeleteItem(wups_storage_item parent, const char *key) { if (__internal_functions.delete_item_function_ptr == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_POINTER; + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; + } + if (__internal_functions.__storageroot_item == nullptr) { + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; } return __internal_functions.delete_item_function_ptr(__internal_functions.__storageroot_item, parent, key); } -WUPSStorageError WUPS_CreateSubItem(wups_storage_item parent, const char *key, wups_storage_item *outItem) { +WUPSStorageError WUPSStorageAPI_CreateSubItem(wups_storage_item parent, const char *key, wups_storage_item *outItem) { if (__internal_functions.create_sub_item_function_ptr == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_POINTER; + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; + } + if (__internal_functions.__storageroot_item == nullptr) { + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; } return __internal_functions.create_sub_item_function_ptr(__internal_functions.__storageroot_item, parent, key, outItem); } -WUPSStorageError WUPS_GetSubItem(wups_storage_item parent, const char *key, wups_storage_item *outItem) { +WUPSStorageError WUPSStorageAPI_GetSubItem(wups_storage_item parent, const char *key, wups_storage_item *outItem) { if (__internal_functions.get_sub_item_function_ptr == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_POINTER; + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; + } + if (__internal_functions.__storageroot_item == nullptr) { + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; } return __internal_functions.get_sub_item_function_ptr(__internal_functions.__storageroot_item, parent, key, outItem); } -static inline WUPSStorageError WUPS_StoreItem(wups_storage_item parent, const char *key, WUPSStorageItemType type, void *data, uint32_t size) { +WUPSStorageError WUPSStorageAPI_StoreItem(wups_storage_item parent, const char *key, WUPSStorageItemType type, void *data, uint32_t size) { if (__internal_functions.store_item_function_ptr == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_POINTER; + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; + } + if (__internal_functions.__storageroot_item == nullptr) { + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; } return __internal_functions.store_item_function_ptr(__internal_functions.__storageroot_item, parent, key, type, data, size); } -WUPSStorageError WUPS_StoreString(wups_storage_item parent, const char *key, const char *value) { - if (value == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_ARGS; - } - return WUPS_StoreItem(parent, key, WUPS_STORAGE_ITEM_STRING, (void *) value, strlen(value)); -} - -WUPSStorageError WUPS_StoreBool(wups_storage_item parent, const char *key, bool value) { - return WUPS_StoreItem(parent, key, WUPS_STORAGE_ITEM_BOOL, (void *) &value, sizeof(bool)); -} - -WUPSStorageError WUPS_StoreInt(wups_storage_item parent, const char *key, int32_t value) { - return WUPS_StoreItem(parent, key, WUPS_STORAGE_ITEM_S32, (void *) &value, sizeof(int32_t)); -} - -WUPSStorageError WUPS_StoreS32(wups_storage_item parent, const char *key, int32_t value) { - return WUPS_StoreItem(parent, key, WUPS_STORAGE_ITEM_S32, (void *) &value, sizeof(int32_t)); -} - -WUPSStorageError WUPS_StoreS64(wups_storage_item parent, const char *key, int64_t value) { - return WUPS_StoreItem(parent, key, WUPS_STORAGE_ITEM_S64, (void *) &value, sizeof(int64_t)); -} - -WUPSStorageError WUPS_StoreU32(wups_storage_item parent, const char *key, uint32_t value) { - return WUPS_StoreItem(parent, key, WUPS_STORAGE_ITEM_U32, (void *) &value, sizeof(uint32_t)); -} - -WUPSStorageError WUPS_StoreU64(wups_storage_item parent, const char *key, uint64_t value) { - return WUPS_StoreItem(parent, key, WUPS_STORAGE_ITEM_U64, (void *) &value, sizeof(uint64_t)); -} - -WUPSStorageError WUPS_StoreFloat(wups_storage_item parent, const char *key, float value) { - return WUPS_StoreItem(parent, key, WUPS_STORAGE_ITEM_FLOAT, (void *) &value, sizeof(float)); -} - -WUPSStorageError WUPS_StoreDouble(wups_storage_item parent, const char *key, double value) { - return WUPS_StoreItem(parent, key, WUPS_STORAGE_ITEM_DOUBLE, (void *) &value, sizeof(double)); -} - -WUPSStorageError WUPS_StoreBinary(wups_storage_item parent, const char *key, const void *data, uint32_t size) { +WUPSStorageError WUPSStorageAPI_GetItem(wups_storage_item parent, const char *key, WUPSStorageItemType type, void *data, uint32_t maxSize, uint32_t *outSize) { if (data == nullptr) { return WUPS_STORAGE_ERROR_INVALID_ARGS; } - return WUPS_StoreItem(parent, key, WUPS_STORAGE_ITEM_BINARY, (void *) data, size); -} - -static inline WUPSStorageError WUPS_GetItem(wups_storage_item parent, const char *key, WUPSStorageItemType type, void *data, uint32_t maxSize, uint32_t *outSize) { if (__internal_functions.get_item_function_ptr == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_POINTER; + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; + } + if (__internal_functions.__storageroot_item == nullptr) { + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; } return __internal_functions.get_item_function_ptr(__internal_functions.__storageroot_item, parent, key, type, data, maxSize, outSize); } -WUPSStorageError WUPS_GetString(wups_storage_item parent, const char *key, char *outString, uint32_t maxSize, uint32_t *outSize) { - if (outString == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_ARGS; - } - return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_STRING, outString, maxSize, outSize); -} - -WUPSStorageError WUPS_GetBool(wups_storage_item parent, const char *key, bool *outValue) { - if (outValue == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_ARGS; - } - return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_BOOL, outValue, sizeof(*outValue), nullptr); -} - -WUPSStorageError WUPS_GetInt(wups_storage_item parent, const char *key, int32_t *outValue) { - if (outValue == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_ARGS; - } - return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_S32, outValue, sizeof(*outValue), nullptr); -} - -WUPSStorageError WUPS_GetS32(wups_storage_item parent, const char *key, int32_t *outValue) { - if (outValue == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_ARGS; - } - return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_S32, outValue, sizeof(*outValue), nullptr); -} - -WUPSStorageError WUPS_GetS64(wups_storage_item parent, const char *key, int64_t *outValue) { - if (outValue == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_ARGS; - } - return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_S64, outValue, sizeof(*outValue), nullptr); -} - -WUPSStorageError WUPS_GetU32(wups_storage_item parent, const char *key, uint32_t *outValue) { - if (outValue == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_ARGS; - } - return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_U32, outValue, sizeof(*outValue), nullptr); -} - -WUPSStorageError WUPS_GetU64(wups_storage_item parent, const char *key, uint64_t *outValue) { - if (outValue == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_ARGS; - } - return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_U64, outValue, sizeof(*outValue), nullptr); -} - -WUPSStorageError WUPS_GetFloat(wups_storage_item parent, const char *key, float *outValue) { - if (outValue == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_ARGS; - } - return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_FLOAT, outValue, sizeof(*outValue), nullptr); -} - -WUPSStorageError WUPS_GetDouble(wups_storage_item parent, const char *key, double *outValue) { - if (outValue == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_ARGS; - } - return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_DOUBLE, outValue, sizeof(*outValue), nullptr); -} - -WUPSStorageError WUPS_GetBinary(wups_storage_item parent, const char *key, void *outData, uint32_t maxSize, uint32_t *outValue) { - if (outData == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_ARGS; - } - - return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_BINARY, outData, maxSize, outValue); -} - -WUPSStorageError WUPS_GetItemSize(wups_storage_item parent, const char *key, uint32_t *outSize) { +WUPSStorageError WUPSStorageAPI_GetItemSize(wups_storage_item parent, const char *key, uint32_t *outSize) { if (outSize == nullptr) { return WUPS_STORAGE_ERROR_INVALID_ARGS; } - if (__internal_functions.get_item_size_function_ptr == nullptr) { - return WUPS_STORAGE_ERROR_INVALID_POINTER; + return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; } return __internal_functions.get_item_size_function_ptr(__internal_functions.__storageroot_item, parent, key, outSize); } diff --git a/libraries/libwups/storageCPP.cpp b/libraries/libwups/storageCPP.cpp new file mode 100644 index 0000000..5ffe46e --- /dev/null +++ b/libraries/libwups/storageCPP.cpp @@ -0,0 +1,136 @@ +#include +#include +#include +#include + +WUPSStorageError WUPSStorageAPI::DeleteItem(std::string_view key) noexcept { + WUPSStorageSubItem item(nullptr); + return item.DeleteItem(key); +} + +WUPSStorageError WUPSStorageAPI::SaveStorage(bool forceSave) { + return WUPSStorageAPI_SaveStorage(forceSave); +} + +WUPSStorageError WUPSStorageAPI::ForceReloadStorage() { + return WUPSStorageAPI_ForceReloadStorage(); +} + +WUPSStorageError WUPSStorageAPI::WipeStorage() { + return WUPSStorageAPI_WipeStorage(); +} + +std::optional WUPSStorageAPI::CreateSubItem(std::string_view key, WUPSStorageError &err) noexcept { + WUPSStorageSubItem item(nullptr); + return item.CreateSubItem(key, err); +} + +std::optional WUPSStorageAPI::GetSubItem(std::string_view key, WUPSStorageError &err) noexcept { + WUPSStorageSubItem item(nullptr); + return item.GetSubItem(key, err); +} + +std::optional WUPSStorageAPI::GetOrCreateSubItem(std::string_view key, WUPSStorageError &err) noexcept { + WUPSStorageSubItem item(nullptr); + return item.GetOrCreateSubItem(key, err); +} + +WUPSStorageSubItem WUPSStorageAPI::CreateSubItem(std::string_view key) { + WUPSStorageSubItem item(nullptr); + return item.CreateSubItem(key); +} + +WUPSStorageSubItem WUPSStorageAPI::GetSubItem(std::string_view key) { + WUPSStorageSubItem item(nullptr); + return item.GetSubItem(key); +} + +WUPSStorageSubItem WUPSStorageAPI::GetOrCreateSubItem(std::string_view key) { + WUPSStorageSubItem item(nullptr); + return item.GetOrCreateSubItem(key); +} + +std::string_view WUPSStorageAPI::GetStatusStr(const WUPSStorageError &err) noexcept { + return WUPSStorageAPI_GetStatusStr(err); +} + +WUPSStorageSubItem WUPSStorageAPI::GetRootItem() noexcept { + return WUPSStorageSubItem(nullptr); +} + +WUPSStorageError WUPSStorageAPI::GetItemSize(std::string_view key, uint32_t &outSize) noexcept { + WUPSStorageSubItem item(nullptr); + return item.GetItemSize(key, outSize); +} + + +WUPSStorageError WUPSStorageSubItem::DeleteItem(std::string_view key) noexcept { + return WUPSStorageAPI_DeleteItem(mHandle, key.data()); +} + +WUPSStorageError WUPSStorageSubItem::GetItemSize(std::string_view key, uint32_t &outSize) noexcept { + return WUPSStorageAPI_GetItemSize(mHandle, key.data(), &outSize); +} + +std::optional WUPSStorageSubItem::CreateSubItem(std::string_view key, WUPSStorageError &err) noexcept { + wups_storage_item outItem = {}; + err = WUPSStorageAPI_CreateSubItem(mHandle, key.data(), &outItem); + if (err != WUPS_STORAGE_ERROR_SUCCESS) { + return std::nullopt; + } + return WUPSStorageSubItem(outItem); +} + +std::optional WUPSStorageSubItem::GetSubItem(std::string_view key, WUPSStorageError &err) const noexcept { + wups_storage_item outItem = {}; + err = WUPSStorageAPI_GetSubItem(mHandle, key.data(), &outItem); + if (err != WUPS_STORAGE_ERROR_SUCCESS) { + return std::nullopt; + } + return WUPSStorageSubItem(outItem); +} + + +std::optional WUPSStorageSubItem::GetOrCreateSubItem(std::string_view key, WUPSStorageError &err) noexcept { + wups_storage_item outItem = {}; + err = WUPSStorageAPI_GetSubItem(mHandle, key.data(), &outItem); + if (err == WUPS_STORAGE_ERROR_NOT_FOUND) { + return CreateSubItem(key); + } + return WUPSStorageSubItem(outItem); +} + +WUPSStorageSubItem WUPSStorageSubItem::CreateSubItem(std::string_view key) { + WUPSStorageError err; + auto res = CreateSubItem(key, err); + if (!res) { + throw std::runtime_error(std::string("WUPSStorageSubItem::CreateSubItem(\"").append(key).append("\")").append(WUPSStorageAPI_GetStatusStr(err))); + } + return *res; +} + +WUPSStorageSubItem WUPSStorageSubItem::GetSubItem(std::string_view key) const { + WUPSStorageError err; + auto res = GetSubItem(key, err); + if (!res) { + throw std::runtime_error(std::string("WUPSStorageSubItem::GetSubItem(\"").append(key).append("\")").append(WUPSStorageAPI_GetStatusStr(err))); + } + return *res; +} + +WUPSStorageSubItem WUPSStorageSubItem::GetOrCreateSubItem(std::string_view key) { + WUPSStorageError err; + auto res = GetOrCreateSubItem(key, err); + if (!res) { + throw std::runtime_error(std::string("WUPSStorageSubItem::GetOrCreateSubItem(\"").append(key).append("\")").append(WUPSStorageAPI_GetStatusStr(err))); + } + return *res; +} + +bool WUPSStorageSubItem::operator==(const WUPSStorageSubItem &rhs) const { + return mHandle == rhs.mHandle; +} + +bool WUPSStorageSubItem::operator!=(const WUPSStorageSubItem &rhs) const { + return !(rhs == *this); +} diff --git a/plugins/example_plugin/src/main.c b/plugins/example_plugin/src/main.c index 766d0b3..b73c5c4 100644 --- a/plugins/example_plugin/src/main.c +++ b/plugins/example_plugin/src/main.c @@ -38,16 +38,10 @@ void logFSOpenChanged(ConfigItemBoolean *item, bool newValue) { DEBUG_FUNCTION_LINE_INFO("New value in logFSOpenChanged: %d", newValue); logFSOpen = newValue; // If the value has changed, we store it in the storage. - WUPS_StoreInt(NULL, LOG_FS_OPEN_CONFIG_ID, logFSOpen); + WUPSStorageAPI_StoreBool(NULL, LOG_FS_OPEN_CONFIG_ID, logFSOpen); } WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle root) { - // We open the storage, so we can persist the configuration the user did. - if (WUPS_OpenStorage() != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE("Failed to open storage"); - return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; - } - { // Let's create a new category called "Settings" WUPSConfigCategoryHandle settingsCategory; @@ -131,10 +125,7 @@ WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle ro } void ConfigMenuClosedCallback() { - // Save all changes - if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to close storage"); - } + WUPSStorageAPI_SaveStorage(false); } /** @@ -150,26 +141,21 @@ INITIALIZE_PLUGIN() { DEBUG_FUNCTION_LINE_ERR("Failed to init config api"); } - // Open storage to read values - WUPSStorageError storageRes = WUPS_OpenStorage(); - if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE("Failed to open storage %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); - } else { - // Try to get value from storage - if ((storageRes = WUPS_GetBool(NULL, LOG_FS_OPEN_CONFIG_ID, &logFSOpen)) == WUPS_STORAGE_ERROR_NOT_FOUND) { - // Add the value to the storage if it's missing. - if (WUPS_StoreBool(NULL, LOG_FS_OPEN_CONFIG_ID, logFSOpen) != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE("Failed to store bool"); - } - } else if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE("Failed to get bool %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); - } + WUPSStorageError storageRes; + // Try to get value from storage + if ((storageRes = WUPSStorageAPI_GetBool(NULL, LOG_FS_OPEN_CONFIG_ID, &logFSOpen)) == WUPS_STORAGE_ERROR_NOT_FOUND) { - // Close storage - if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE("Failed to close storage"); + // Add the value to the storage if it's missing. + if (WUPSStorageAPI_StoreBool(NULL, LOG_FS_OPEN_CONFIG_ID, logFSOpen) != WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("Failed to store bool"); } + } else if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("Failed to get bool %s (%d)", WUPSConfigAPI_GetStatusStr(storageRes), storageRes); + } else { + DEBUG_FUNCTION_LINE_ERR("Successfully read the value from storage: %d %s (%d)", logFSOpen, WUPSConfigAPI_GetStatusStr(storageRes), storageRes); } + WUPSStorageAPI_SaveStorage(false); + deinitLogging(); } diff --git a/plugins/example_plugin_cpp/src/main.cpp b/plugins/example_plugin_cpp/src/main.cpp index af62e94..632a7f4 100644 --- a/plugins/example_plugin_cpp/src/main.cpp +++ b/plugins/example_plugin_cpp/src/main.cpp @@ -55,7 +55,7 @@ void boolItemChanged(ConfigItemBoolean *item, bool newValue) { if (std::string_view(LOG_FS_OPEN_CONFIG_ID) == item->identifier) { sLogFSOpen = newValue; // If the value has changed, we store it in the storage. - WUPS_StoreInt(nullptr, item->identifier, newValue); + WUPSStorageAPI::Store(item->identifier, newValue); } else if (std::string_view(OTHER_EXAMPLE_BOOL_CONFIG_ID) == item->identifier) { DEBUG_FUNCTION_LINE_ERR("Other bool value has changed to %d", newValue); } else if (std::string_view(OTHER_EXAMPLE2_BOOL_CONFIG_ID) == item->identifier) { @@ -69,7 +69,7 @@ void integerRangeItemChanged(ConfigItemIntegerRange *item, int newValue) { if (std::string_view(LOG_FS_OPEN_CONFIG_ID) == item->identifier) { sIntegerRangeValue = newValue; // If the value has changed, we store it in the storage. - WUPS_StoreInt(nullptr, item->identifier, newValue); + WUPSStorageAPI::Store(item->identifier, newValue); } } @@ -79,16 +79,11 @@ void multipleValueItemChanged(ConfigItemIntegerRange *item, uint32_t newValue) { if (std::string_view(MULTIPLE_VALUES_EXAMPLE_CONFIG_ID) == item->identifier) { sExampleOptionValue = (ExampleOptions) newValue; // If the value has changed, we store it in the storage. - WUPS_StoreInt(nullptr, item->identifier, sExampleOptionValue); + WUPSStorageAPI::Store(item->identifier, sExampleOptionValue); } } WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle rootHandle) { - // We open the storage, so we can persist the configuration the user did. - if (WUPS_OpenStorage() != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE("Failed to open storage"); - return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; - } // To use the C++ API, we create new WUPSConfigCategory from the root handle! WUPSConfigCategory root = WUPSConfigCategory(rootHandle); @@ -189,10 +184,7 @@ WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle ro } void ConfigMenuClosedCallback() { - // Save all changes - if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to close storage"); - } + WUPSStorageAPI::SaveStorage(); } /** @@ -203,31 +195,19 @@ INITIALIZE_PLUGIN() { initLogging(); DEBUG_FUNCTION_LINE("INITIALIZE_PLUGIN of example_plugin!"); - WUPSConfigAPIOptionsV1 configOptions = {.name = "example_plugin"}; + WUPSConfigAPIOptionsV1 configOptions = {.name = "example_plugin_cpp"}; if (WUPSConfigAPI_Init(configOptions, ConfigMenuOpenedCallback, ConfigMenuClosedCallback) != WUPSCONFIG_API_RESULT_SUCCESS) { DEBUG_FUNCTION_LINE_ERR("Failed to init config api"); } - // Open storage to read values - WUPSStorageError storageRes = WUPS_OpenStorage(); - if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE("Failed to open storage %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); - } else { - // Try to get value from storage - if ((storageRes = WUPS_GetBool(nullptr, LOG_FS_OPEN_CONFIG_ID, &sLogFSOpen)) == WUPS_STORAGE_ERROR_NOT_FOUND) { - // Add the value to the storage if it's missing. - if (WUPS_StoreBool(nullptr, LOG_FS_OPEN_CONFIG_ID, sLogFSOpen) != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE("Failed to store bool"); - } - } else if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE("Failed to get bool %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); - } - - // Close storage - if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE("Failed to close storage"); - } + WUPSStorageError storageRes; + if ((storageRes = WUPSStorageAPI::GetOrStoreDefault(LOG_FS_OPEN_CONFIG_ID, sLogFSOpen, LOF_FS_OPEN_DEFAULT_VALUE)) != WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("GetOrStoreDefault failed: %s (%d)", WUPSStorageAPI_GetStatusStr(storageRes), storageRes); } + if ((storageRes = WUPSStorageAPI::SaveStorage()) != WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("GetOrStoreDefault failed: %s (%d)", WUPSStorageAPI_GetStatusStr(storageRes), storageRes); + } + deinitLogging(); } diff --git a/plugins/storage_test_plugin/src/test.cpp b/plugins/storage_test_plugin/src/test.cpp index c5ac9b5..6478911 100644 --- a/plugins/storage_test_plugin/src/test.cpp +++ b/plugins/storage_test_plugin/src/test.cpp @@ -2,178 +2,9 @@ #include "utils/logger.h" #include "utils/utils.h" #include +#include #include -#include - -extern const char wups_meta_storage_id[]; - -static std::string pluginPathCached; -static std::string getPluginConfigPath() { - if (!pluginPathCached.empty()) { - return pluginPathCached; - } - char environmentPath[0x100]; - memset(environmentPath, 0, sizeof(environmentPath)); - - auto handle = IOS_Open("/dev/mcp", IOS_OPEN_READ); - if (handle >= 0) { - int in = 0xF9; // IPC_CUSTOM_COPY_ENVIRONMENT_PATH - if (IOS_Ioctl(handle, 100, &in, sizeof(in), environmentPath, sizeof(environmentPath)) != IOS_ERROR_OK) { - return "fs:/vol/external01/wiiu/plugins/config"; - } - - IOS_Close(handle); - } - pluginPathCached = std::string(environmentPath).append("/plugins/config"); - return pluginPathCached; -}; - -struct CleanUpStorage { - CleanUpStorage() { - WUPS_CloseStorage(); - auto path = string_format("%s/%s.json", getPluginConfigPath().c_str(), &wups_meta_storage_id[0] + strlen("storage_id=")); - struct stat s {}; - if (stat(path.c_str(), &s) != 0) { - // File doesn't exist - return; - } - remove(path.c_str()); - } - ~CleanUpStorage() = default; -}; - -template -WUPSStorageError WUPS_Get(wups_storage_item parent, const char *key, T &outValue); - -template<> -WUPSStorageError WUPS_Get(wups_storage_item parent, const char *key, int32_t &outValue) { - return WUPS_GetS32(parent, key, &outValue); -} - -template<> -WUPSStorageError WUPS_Get(wups_storage_item parent, const char *key, int64_t &outValue) { - return WUPS_GetS64(parent, key, &outValue); -} - -template<> -WUPSStorageError WUPS_Get(wups_storage_item parent, const char *key, uint32_t &outValue) { - return WUPS_GetU32(parent, key, &outValue); -} - -template<> -WUPSStorageError WUPS_Get(wups_storage_item parent, const char *key, uint64_t &outValue) { - return WUPS_GetU64(parent, key, &outValue); -} - -template<> -WUPSStorageError WUPS_Get(wups_storage_item parent, const char *key, bool &outValue) { - return WUPS_GetBool(parent, key, &outValue); -} - -template<> -WUPSStorageError WUPS_Get(wups_storage_item parent, const char *key, float &outValue) { - return WUPS_GetFloat(parent, key, &outValue); -} - -template<> -WUPSStorageError WUPS_Get(wups_storage_item parent, const char *key, double &outValue) { - return WUPS_GetDouble(parent, key, &outValue); -} - -template<> -WUPSStorageError WUPS_Get>(wups_storage_item parent, const char *key, std::vector &outValue) { - uint32_t outSize = 0; - - if (outValue.empty()) { - uint32_t resizeToSize = 0; - auto r = WUPS_GetItemSize(parent, key, &resizeToSize); - if (r == WUPS_STORAGE_ERROR_SUCCESS) { - outValue.resize(resizeToSize); - } else { - return r; - } - } - - auto res = WUPS_GetBinary(parent, key, outValue.data(), outValue.size(), &outSize); - if (res == WUPS_STORAGE_ERROR_SUCCESS) { - outValue.resize(outSize); - } else { - outValue.resize(0); - } - return res; -} - -template<> -WUPSStorageError WUPS_Get(wups_storage_item parent, const char *key, std::string &outValue) { - uint32_t outSize = 0; - if (outValue.size() == 0) { - uint32_t resizeToSize = 0; - auto r = WUPS_GetItemSize(parent, key, &resizeToSize); - if (r == WUPS_STORAGE_ERROR_SUCCESS) { - outValue.resize(resizeToSize); - } else { - return r; - } - } - - auto res = WUPS_GetString(parent, key, outValue.data(), outValue.size(), &outSize); - if (res == WUPS_STORAGE_ERROR_SUCCESS) { - // outSize does count the null terminator as well, std::string's size() doesn't include a null terminator. - outValue.resize(strlen(outValue.c_str())); - } else { - outValue.resize(0); - } - return res; -} - -template -WUPSStorageError WUPS_Store(wups_storage_item parent, const char *key, const T &outValue); - -template<> -WUPSStorageError WUPS_Store(wups_storage_item parent, const char *key, const int32_t &outValue) { - return WUPS_StoreS32(parent, key, outValue); -} - -template<> -WUPSStorageError WUPS_Store(wups_storage_item parent, const char *key, const int64_t &outValue) { - return WUPS_StoreS64(parent, key, outValue); -} - -template<> -WUPSStorageError WUPS_Store(wups_storage_item parent, const char *key, const uint32_t &outValue) { - return WUPS_StoreU32(parent, key, outValue); -} - -template<> -WUPSStorageError WUPS_Store(wups_storage_item parent, const char *key, const uint64_t &outValue) { - return WUPS_StoreU64(parent, key, outValue); -} - -template<> -WUPSStorageError WUPS_Store(wups_storage_item parent, const char *key, const bool &outValue) { - return WUPS_StoreBool(parent, key, outValue); -} - -template<> -WUPSStorageError WUPS_Store(wups_storage_item parent, const char *key, const float &outValue) { - return WUPS_StoreFloat(parent, key, outValue); -} - -template<> -WUPSStorageError WUPS_Store(wups_storage_item parent, const char *key, const double &outValue) { - return WUPS_StoreDouble(parent, key, outValue); -} - -template<> -WUPSStorageError WUPS_Store>(wups_storage_item parent, const char *key, const std::vector &outValue) { - return WUPS_StoreBinary(parent, key, outValue.data(), outValue.size()); -} - -template<> -WUPSStorageError WUPS_Store(wups_storage_item parent, const char *key, const std::string &outValue) { - return WUPS_StoreString(parent, key, outValue.c_str()); -} - +#include template bool isEqual(const T &v1, const T &v2) { return v1 == v2; @@ -196,70 +27,55 @@ bool isEqual(const std::vector &v1, const std::vector &v2) { template void TestStorageItem(const char *key, const T &expectedVal) { - CleanUpStorage cleanup; - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); T val = {}; - auto r = WUPS_Get(nullptr, key, val); + auto r = WUPSStorageAPI::Get(key, val); REQUIRE(r == WUPS_STORAGE_ERROR_NOT_FOUND); REQUIRE(isEqual(val, T())); - r = WUPS_Store(nullptr, key, expectedVal); + r = WUPSStorageAPI::Store(key, expectedVal); REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); T readValue = {}; - r = WUPS_Get(nullptr, key, readValue); + r = WUPSStorageAPI::Get(key, readValue); REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); REQUIRE(isEqual(readValue, expectedVal)); // let's close storage to write to sd card - res = WUPS_CloseStorage(); + res = WUPSStorageAPI::SaveStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - // Open it back! - res = WUPS_OpenStorage(); + res = WUPSStorageAPI::ForceReloadStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); readValue = {}; - r = WUPS_Get(nullptr, key, readValue); + r = WUPSStorageAPI::Get(key, readValue); REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); REQUIRE(isEqual(readValue, expectedVal)); - - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Empty config: Get SubItem fails") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *subItemName = "subItem"; - wups_storage_item subItem = nullptr; - auto r = WUPS_GetSubItem(nullptr, subItemName, &subItem); - REQUIRE(r == WUPS_STORAGE_ERROR_NOT_FOUND); - REQUIRE(subItem == nullptr); - - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + WUPSStorageError err; + auto subItem = WUPSStorageAPI::GetSubItem(subItemName, err); + REQUIRE(err == WUPS_STORAGE_ERROR_NOT_FOUND); + REQUIRE(!subItem); } TEST_CASE("Empty config: Get getitem fails") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *subItemName = "item"; int readRes = 0; - auto r = WUPS_GetS32(nullptr, subItemName, &readRes); + auto r = WUPSStorageAPI::Get(subItemName, readRes); REQUIRE(r == WUPS_STORAGE_ERROR_NOT_FOUND); REQUIRE(readRes == 0); - - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Create S32 item") { @@ -330,31 +146,27 @@ TEST_CASE("Create string") { template void CheckItemSize(const char *key, const T &expectedVal, const uint32_t expectedItemSize) { - CleanUpStorage cleanup; - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - res = WUPS_Store(nullptr, key, expectedVal); + res = WUPSStorageAPI::Store(key, expectedVal); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); uint32_t itemSize = 0; - res = WUPS_GetItemSize(nullptr, key, &itemSize); + res = WUPSStorageAPI::GetItemSize(key, itemSize); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); REQUIRE(itemSize == expectedItemSize); - res = WUPS_CloseStorage(); + res = WUPSStorageAPI::SaveStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - res = WUPS_OpenStorage(); + res = WUPSStorageAPI::ForceReloadStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); itemSize = 0; - res = WUPS_GetItemSize(nullptr, key, &itemSize); + res = WUPSStorageAPI::GetItemSize(key, itemSize); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); REQUIRE(itemSize == expectedItemSize); - - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Test get size with string") { @@ -374,779 +186,621 @@ TEST_CASE("Test get size with binary") { } TEST_CASE("Test getSize fails with other type") { - CleanUpStorage cleanup; - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *key = "test"; - res = WUPS_Store(nullptr, key, 0); + res = WUPSStorageAPI::Store(key, 0); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); uint32_t itemSize = 0; - res = WUPS_GetItemSize(nullptr, key, &itemSize); + res = WUPSStorageAPI::GetItemSize(key, itemSize); REQUIRE(res == WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE); REQUIRE(itemSize == 0); - - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Delete non-existent item should fail") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - res = WUPS_DeleteItem(nullptr, "non_existent"); + res = WUPSStorageAPI::DeleteItem("non_existent"); REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Create subitem") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + constexpr auto *subItemName = "subItem"; - wups_storage_item subItem = nullptr; - auto r = WUPS_CreateSubItem(nullptr, subItemName, &subItem); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem != nullptr); + auto subItem = WUPSStorageAPI::CreateSubItem(subItemName, res); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(subItem.has_value()); - wups_storage_item readItem = nullptr; - r = WUPS_GetSubItem(nullptr, subItemName, &readItem); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem == readItem); + auto readItem = WUPSStorageAPI::GetSubItem(subItemName, res); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(readItem); + REQUIRE(*readItem == *subItem); - // Close to write the data to the storage - res = WUPS_CloseStorage(); + res = WUPSStorageAPI::SaveStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - // Parse data from json and try to read it - res = WUPS_OpenStorage(); + res = WUPSStorageAPI::ForceReloadStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - readItem = nullptr; - r = WUPS_GetSubItem(nullptr, subItemName, &readItem); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(readItem != nullptr); + readItem = WUPSStorageAPI::GetSubItem(subItemName, res); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(readItem); + REQUIRE(*readItem == *subItem); +} + +void storeNestedSubItem(int NEST_DEEP_SIZE) { + WUPSStorageError res; + std::optional subItem = WUPSStorageAPI::GetRootItem(); + REQUIRE(subItem); + + for (int i = 0; i < NEST_DEEP_SIZE; i++) { + auto subItemKey = string_format("subItem_%d", (i + 1)); + subItem = subItem->CreateSubItem(subItemKey, res); + REQUIRE(subItem); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + + res = subItem->Store("value", i); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + } +} + +void readNestedSubItem(int NEST_DEEP_SIZE) { + WUPSStorageError res; + std::optional subItem = WUPSStorageAPI::GetRootItem(); + REQUIRE(subItem); + + for (int i = 0; i < NEST_DEEP_SIZE; i++) { + auto subItemKey = string_format("subItem_%d", (i + 1)); + subItem = subItem->GetSubItem(subItemKey, res); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(subItem); + + int32_t readValue = -1; + res = subItem->Get("value", readValue); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(readValue == i); + } +} + +/** + * 1. Store "test" and make sure reading works + * 2. Make sure get "test" failes + * 3. Save storage + * 4. Store "test2" and make sure reading both "test" and "test2" works + * 5. Force reload + * 6. Make sure reading "test2" failes, but "test" still works + */ +TEST_CASE("Test ForceReload") { + auto res = WUPSStorageAPI::WipeStorage(); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + + constexpr auto *itemKey = "test"; + constexpr auto *itemKey2 = "test2"; + + // Write value and read it back + constexpr int writeValue = 0x13371337; + constexpr int writeValue2 = 0x13371338; + res = WUPSStorageAPI::Store(itemKey, writeValue); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + + int readValue = 0; + res = WUPSStorageAPI::Get(itemKey, readValue); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(readValue == writeValue); + + // Try to read a non-existing item + readValue = 0; + res = WUPSStorageAPI::Get(itemKey2, readValue); + REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); + REQUIRE(readValue == 0); + + // Force save + res = WUPSStorageAPI::SaveStorage(); + + // Write test 2 value and read it back + res = WUPSStorageAPI::Store(itemKey2, writeValue2); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + + readValue = 0; + res = WUPSStorageAPI::Get(itemKey2, readValue); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(readValue == writeValue2); + + res = WUPSStorageAPI::ForceReloadStorage(); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + + readValue = 0; + res = WUPSStorageAPI::Get(itemKey, readValue); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(readValue == writeValue); + + readValue = 0; + res = WUPSStorageAPI::Get(itemKey2, readValue); + REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); + REQUIRE(readValue == 0); } TEST_CASE("Create nested subitems") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto NEST_DEEP_SIZE = 10; - wups_storage_item parentSubItem = nullptr; - for (int i = 0; i < NEST_DEEP_SIZE; i++) { - auto subItemKey = string_format("subItem_%d", (i + 1)); - wups_storage_item subItem = nullptr; - auto r = WUPS_CreateSubItem(parentSubItem, subItemKey.c_str(), &subItem); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem != nullptr); + storeNestedSubItem(NEST_DEEP_SIZE); - r = WUPS_StoreS32(subItem, "value", i); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); + readNestedSubItem(NEST_DEEP_SIZE); - parentSubItem = subItem; - } - - parentSubItem = nullptr; - for (int i = 0; i < NEST_DEEP_SIZE; i++) { - auto subItemKey = string_format("subItem_%d", (i + 1)); - wups_storage_item subItem = nullptr; - auto r = WUPS_GetSubItem(parentSubItem, subItemKey.c_str(), &subItem); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem != nullptr); - - int readValue = -1; - r = WUPS_GetS32(subItem, "value", &readValue); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(readValue == i); - - parentSubItem = subItem; - } - - // Close to write the data to the storage - res = WUPS_CloseStorage(); + res = WUPSStorageAPI::SaveStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - // Parse data from json and try to read it - res = WUPS_OpenStorage(); + res = WUPSStorageAPI::ForceReloadStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - parentSubItem = nullptr; - for (int i = 0; i < NEST_DEEP_SIZE; i++) { - auto subItemKey = string_format("subItem_%d", (i + 1)); - wups_storage_item subItem = nullptr; - auto r = WUPS_GetSubItem(parentSubItem, subItemKey.c_str(), &subItem); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem != nullptr); + readNestedSubItem(NEST_DEEP_SIZE); +} - int readValue = -1; - r = WUPS_GetS32(subItem, "value", &readValue); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(readValue == i); +TEST_CASE("Check SaveStorage") { + auto res = WUPSStorageAPI::WipeStorage(); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - parentSubItem = subItem; - } + WUPSStorageAPI::Store("test", 1); + OSReport("Save after change\n"); + WUPSStorageAPI::SaveStorage(false); + OSReport("Save after no change\n"); + WUPSStorageAPI::SaveStorage(false); + WUPSStorageAPI::Store("test", 2); + WUPSStorageAPI::Store("test", 1); + OSReport("Save after no change\n"); + WUPSStorageAPI::SaveStorage(false); } TEST_CASE("Create and then delete subitem") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *subItemName = "subItem"; - wups_storage_item subItem = nullptr; - auto r = WUPS_CreateSubItem(nullptr, subItemName, &subItem); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem != nullptr); - - r = WUPS_DeleteItem(nullptr, subItemName); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - - wups_storage_item readSubItem = nullptr; - r = WUPS_GetSubItem(nullptr, subItemName, &readSubItem); - REQUIRE(r == WUPS_STORAGE_ERROR_NOT_FOUND); - REQUIRE(readSubItem == nullptr); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); + auto subItem = WUPSStorageAPI::CreateSubItem(subItemName, res); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(subItem); + + res = WUPSStorageAPI::DeleteItem(subItemName); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + + subItem = WUPSStorageAPI::GetSubItem(subItemName, res); + REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); + REQUIRE(!subItem); } TEST_CASE("Create delete subitem with writes") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *subItemName = "subItem"; - wups_storage_item subItem = nullptr; - auto r = WUPS_CreateSubItem(nullptr, subItemName, &subItem); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem != nullptr); + auto subItem = WUPSStorageAPI::CreateSubItem(subItemName, res); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(subItem); - // Close to write the data to the storage - res = WUPS_CloseStorage(); + res = WUPSStorageAPI::SaveStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - // read from json - res = WUPS_OpenStorage(); + res = WUPSStorageAPI::ForceReloadStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - r = WUPS_DeleteItem(nullptr, subItemName); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - - wups_storage_item readSubItem = nullptr; - r = WUPS_GetSubItem(nullptr, subItemName, &readSubItem); - REQUIRE(r == WUPS_STORAGE_ERROR_NOT_FOUND); - REQUIRE(readSubItem == nullptr); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); + res = WUPSStorageAPI::DeleteItem(subItemName); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - // read from json - res = WUPS_OpenStorage(); + auto readSubItem = WUPSStorageAPI::GetSubItem(subItemName, res); + REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); + REQUIRE(!readSubItem); + + res = WUPSStorageAPI::SaveStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - readSubItem = nullptr; - r = WUPS_GetSubItem(nullptr, subItemName, &readSubItem); - REQUIRE(r == WUPS_STORAGE_ERROR_NOT_FOUND); - REQUIRE(readSubItem == nullptr); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); + res = WUPSStorageAPI::ForceReloadStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + + readSubItem = WUPSStorageAPI::GetSubItem(subItemName, res); + REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); + REQUIRE(!readSubItem); } TEST_CASE("Create two sub item with same key fails") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *subItemName = "subItem"; - wups_storage_item subItem = nullptr; - auto r = WUPS_CreateSubItem(nullptr, subItemName, &subItem); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem != nullptr); - - subItem = nullptr; - r = WUPS_CreateSubItem(nullptr, subItemName, &subItem); - REQUIRE(r == WUPS_STORAGE_ERROR_ALREADY_EXISTS); - REQUIRE(subItem == nullptr); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); + auto subItem = WUPSStorageAPI::CreateSubItem(subItemName, res); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(subItem); + + subItem = WUPSStorageAPI::CreateSubItem(subItemName, res); + REQUIRE(res == WUPS_STORAGE_ERROR_ALREADY_EXISTS); + REQUIRE(!subItem); } TEST_CASE("Updating value of item by key works") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *itemName = "item"; int32_t value = 0x42424242; - res = WUPS_Store(nullptr, itemName, value); + res = WUPSStorageAPI::Store(itemName, value); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); int32_t newValue = 0x42424243; - res = WUPS_Store(nullptr, itemName, newValue); + res = WUPSStorageAPI::Store(itemName, newValue); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); int32_t readValue = 0; - res = WUPS_Get(nullptr, itemName, readValue); + res = WUPSStorageAPI::Get(itemName, readValue); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); REQUIRE(readValue == newValue); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Changing type of item works") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *itemName = "item"; std::string value = "This is just a random string and no binary data"; - res = WUPS_Store(nullptr, itemName, value); + res = WUPSStorageAPI::Store(itemName, value); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); float floatValue = 1337.4242f; - res = WUPS_Store(nullptr, itemName, floatValue); + res = WUPSStorageAPI::Store(itemName, floatValue); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); float readValue = 0.0f; - res = WUPS_Get(nullptr, itemName, readValue); + res = WUPSStorageAPI::Get(itemName, readValue); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); REQUIRE(readValue == floatValue); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Get (size) works after changing type to binary") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + constexpr auto *itemName = "item"; int32_t value = 12345678; - res = WUPS_Store(nullptr, itemName, value); + res = WUPSStorageAPI::Store(itemName, value); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); uint32_t itemSize = 0; - res = WUPS_GetItemSize(nullptr, itemName, &itemSize); + res = WUPSStorageAPI::GetItemSize(itemName, itemSize); REQUIRE(res == WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE); REQUIRE(itemSize == 0); std::vector binaryData = {8, 4, 5, 4, 12, 4, 2}; uint32_t binaryDataSize = binaryData.size(); - res = WUPS_Store>(nullptr, itemName, binaryData); + res = WUPSStorageAPI::Store>(itemName, binaryData); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); itemSize = 0; - res = WUPS_GetItemSize(nullptr, itemName, &itemSize); + res = WUPSStorageAPI::GetItemSize(itemName, itemSize); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); REQUIRE(itemSize == binaryDataSize); std::vector readBinary; - res = WUPS_Get>(nullptr, itemName, readBinary); + res = WUPSStorageAPI::Get>(itemName, readBinary); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); REQUIRE(isEqual(binaryData, readBinary)); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Change type from binary to int causes get size to fail") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + constexpr auto *itemName = "item"; std::vector binaryData = {8, 4, 5, 4, 12, 4, 2}; - res = WUPS_Store>(nullptr, itemName, binaryData); + res = WUPSStorageAPI::Store>(itemName, binaryData); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); int32_t value = 12345678; - res = WUPS_Store(nullptr, itemName, value); + res = WUPSStorageAPI::Store(itemName, value); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); uint32_t itemSize = 0; - res = WUPS_GetItemSize(nullptr, itemName, &itemSize); + res = WUPSStorageAPI::GetItemSize(itemName, itemSize); REQUIRE(res == WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE); REQUIRE(itemSize == 0); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Create item with same key as sub-item fails") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - constexpr auto *itemName = "item"; - wups_storage_item subItem = nullptr; - res = WUPS_CreateSubItem(nullptr, itemName, &subItem); + + constexpr auto *itemName = "item"; + auto subItem = WUPSStorageAPI::CreateSubItem(itemName, res); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(subItem); int32_t value = 0; - res = WUPS_Store(nullptr, itemName, value); + res = WUPSStorageAPI::Store(itemName, value); REQUIRE(res == WUPS_STORAGE_ERROR_ALREADY_EXISTS); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Create sub-item with same key as item fails") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *itemName = "item"; int32_t value = 0; - res = WUPS_Store(nullptr, itemName, value); + res = WUPSStorageAPI::Store(itemName, value); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - wups_storage_item subItem = nullptr; - res = WUPS_CreateSubItem(nullptr, itemName, &subItem); + auto subItem = WUPSStorageAPI::CreateSubItem(itemName, res); REQUIRE(res == WUPS_STORAGE_ERROR_ALREADY_EXISTS); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Make sure WUPS_GetSubItem only checks parent") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *subItemName = "subItem"; - wups_storage_item subItem = nullptr; - auto r = WUPS_CreateSubItem(nullptr, subItemName, &subItem); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem != nullptr); + auto subItem = WUPSStorageAPI::CreateSubItem(subItemName, res); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(subItem); constexpr auto *subItemName2 = "subItem2"; - wups_storage_item subItem2 = nullptr; - r = WUPS_CreateSubItem(subItem, subItemName2, &subItem2); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem2 != nullptr); + auto subItem2 = subItem->CreateSubItem(subItemName2, res); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(subItem2); // Make sure we can't get subItem2 from root. - wups_storage_item subItem2FromRoot = nullptr; - r = WUPS_GetSubItem(nullptr, subItemName2, &subItem2FromRoot); - REQUIRE(r == WUPS_STORAGE_ERROR_NOT_FOUND); - REQUIRE(subItem2FromRoot == nullptr); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + auto subItem2FromRoot = WUPSStorageAPI::GetSubItem(subItemName2, res); + REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); + REQUIRE(!subItem2FromRoot); } TEST_CASE("Make sure WUPS_GetItem only checks parent") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *subItemName = "subItem"; - wups_storage_item subItem = nullptr; - auto r = WUPS_CreateSubItem(nullptr, subItemName, &subItem); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem != nullptr); + auto subItem = WUPSStorageAPI::CreateSubItem(subItemName, res); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(subItem); int32_t value = 1337; constexpr auto *itemName = "item"; - r = WUPS_Store(subItem, itemName, value); - REQUIRE(r == WUPS_STORAGE_ERROR_SUCCESS); + res = subItem->Store(itemName, value); + REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); // Make sure we can't get item from root. int32_t readValue = 0; - r = WUPS_Get(nullptr, itemName, readValue); - REQUIRE(r == WUPS_STORAGE_ERROR_NOT_FOUND); + res = WUPSStorageAPI::Get(itemName, readValue); + REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); REQUIRE(readValue == 0); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Store string and load it as binary fails") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *itemName = "item"; std::string value = "This is just a random string and no binary data"; - res = WUPS_Store(nullptr, itemName, value); + res = WUPSStorageAPI::Store(itemName, value); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); std::vector readBinary; - res = WUPS_Get>(nullptr, itemName, readBinary); + res = WUPSStorageAPI::Get>(itemName, readBinary); REQUIRE(res == WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Get binary fails if buffer is too small") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *itemName = "item"; std::vector binaryData = {8, 4, 5, 4, 12, 4, 2}; - res = WUPS_Store>(nullptr, itemName, binaryData); + res = WUPSStorageAPI::Store>(itemName, binaryData); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); std::vector readBinaryData; - REQUIRE(binaryData.size() > 0); + REQUIRE(!binaryData.empty()); readBinaryData.resize(binaryData.size() - 1); // Make the buffer just a bit to small - res = WUPS_Get>(nullptr, itemName, readBinaryData); + res = WUPSStorageAPI::Get>(itemName, readBinaryData); REQUIRE(res == WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Get binary works with exact buffer size") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *itemName = "item"; std::vector binaryData = {8, 4, 5, 4, 12, 4, 2}; - res = WUPS_Store>(nullptr, itemName, binaryData); + res = WUPSStorageAPI::Store>(itemName, binaryData); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); std::vector readBinaryData; - REQUIRE(binaryData.size() > 0); - readBinaryData.resize(binaryData.size()); // Make the buffer just a bit to small - res = WUPS_Get>(nullptr, itemName, readBinaryData); + REQUIRE(!binaryData.empty()); + readBinaryData.resize(binaryData.size()); + res = WUPSStorageAPI::Get>(itemName, readBinaryData); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); REQUIRE(isEqual(binaryData, readBinaryData)); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } - TEST_CASE("Get string fails if buffer is too small") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *itemName = "item"; std::string strData = "Random string I just need for this test."; - res = WUPS_Store(nullptr, itemName, strData); + res = WUPSStorageAPI::Store(itemName, strData); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); std::string readStr; - REQUIRE(strData.size() > 0); + REQUIRE(!strData.empty()); // Make the buffer just a bit to small readStr.resize(strData.length() - 1); - res = WUPS_Get(nullptr, itemName, readStr); + res = WUPSStorageAPI::Get(itemName, readStr); REQUIRE(res == WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Get string works with exact buffer size") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); constexpr auto *itemName = "item"; std::string strData = "Random string I just need for this test."; - res = WUPS_Store(nullptr, itemName, strData); + res = WUPSStorageAPI::Store(itemName, strData); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); std::string readStr; - REQUIRE(strData.size() > 0); + REQUIRE(!strData.empty()); // We need to add one byte because of the null terminator readStr.resize(strData.length() + 1); - res = WUPS_Get(nullptr, itemName, readStr); + res = WUPSStorageAPI::Get(itemName, readStr); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); REQUIRE(isEqual(strData, readStr)); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("Create two sub-items, storing in first still works") { - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); // create subItem1 constexpr auto *subItem1Key = "subItem1"; - wups_storage_item subItem1 = nullptr; - res = WUPS_CreateSubItem(nullptr, subItem1Key, &subItem1); + auto subItem1 = WUPSStorageAPI::CreateSubItem(subItem1Key, res); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem1 != nullptr); + REQUIRE(subItem1); // create subItem2 constexpr auto *subItem2Key = "subItem2"; - wups_storage_item subItem2 = nullptr; - res = WUPS_CreateSubItem(nullptr, subItem2Key, &subItem2); + auto subItem2 = WUPSStorageAPI::CreateSubItem(subItem2Key, res); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem2 != nullptr); + REQUIRE(subItem2); constexpr auto *itemIn1Key = "item"; int32_t value = 13371337; - res = WUPS_Store(subItem1, itemIn1Key, value); + res = subItem1->Store(itemIn1Key, value); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); int readValue = 0; - res = WUPS_Get(subItem1, itemIn1Key, readValue); + res = subItem1->Get(itemIn1Key, readValue); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); REQUIRE(value == readValue); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } -TEST_CASE("Create sub-item with closed storage fails") { - // make sure storage is closed - CleanUpStorage cleanup; - - // create subItem1 - constexpr auto *subItem1Key = "subItem1"; - wups_storage_item subItem1 = nullptr; - auto res = WUPS_CreateSubItem(nullptr, subItem1Key, &subItem1); - REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); - REQUIRE(subItem1 == nullptr); -} - -TEST_CASE("Get sub item with closed storage fails") { - // make sure storage is closed - CleanUpStorage cleanup; - - // create subItem1 - constexpr auto *itemKey = "subItem"; - wups_storage_item subItem1 = nullptr; - auto res = WUPS_GetSubItem(nullptr, itemKey, &subItem1); - REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); - REQUIRE(subItem1 == 0); -} - -TEST_CASE("Get item with closed storage fails") { - // make sure storage is closed - CleanUpStorage cleanup; - - // create subItem1 - constexpr auto *itemKey = "item"; - int32_t value = 0; - auto res = WUPS_Get(nullptr, itemKey, value); - REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); - REQUIRE(value == 0); -} - -TEST_CASE("Store item with closed storage fails") { - // make sure storage is closed - CleanUpStorage cleanup; - - // create subItem1 - constexpr auto *itemKey = "item"; - int32_t value = 13371337; - auto res = WUPS_Store(nullptr, itemKey, value); - REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); -} - -TEST_CASE("get item size with closed storage fails") { - // make sure storage is closed - CleanUpStorage cleanup; - - // create subItem1 - constexpr auto *itemKey = "item"; - uint32_t itemSize = 0; - auto res = WUPS_GetItemSize(nullptr, itemKey, &itemSize); - REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); -} - - TEST_CASE("Create nested sub items, delete top one, accessing items of nested one should fail") { // make sure storage is closed - CleanUpStorage cleanup; - - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); // create subItem1 constexpr auto *subItem1Key = "subItem1"; - wups_storage_item subItem1 = nullptr; - res = WUPS_CreateSubItem(nullptr, subItem1Key, &subItem1); + auto subItem1 = WUPSStorageAPI::CreateSubItem(subItem1Key, res); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem1 != nullptr); + REQUIRE(subItem1); // create subItem2 - constexpr auto *subItem1_1Key = "subItem1.1"; - wups_storage_item subItem1_1 = nullptr; - res = WUPS_CreateSubItem(subItem1, subItem1_1Key, &subItem1_1); + constexpr auto *subItem1_1Key = "subItem1_1"; + auto subItem1_1 = subItem1->CreateSubItem(subItem1_1Key, res); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem1_1 != nullptr); + REQUIRE(subItem1_1); - // create subItem1 + // Store into subItem1 constexpr auto *itemKey = "item_in_1_1"; int32_t value = 13371337; - res = WUPS_Store(subItem1_1, itemKey, value); + res = subItem1_1->Store(itemKey, value); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); // delete subItem1 - res = WUPS_DeleteItem(nullptr, subItem1Key); + res = WUPSStorageAPI::DeleteItem(subItem1Key); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); int readValue = 0; - res = WUPS_Get(subItem1_1, itemKey, value); + res = subItem1_1->Get(itemKey, readValue); REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(readValue == 0); } TEST_CASE("Store item into deleted sub-item should fail") { // make sure storage is closed - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); // create subItem1 constexpr auto *subItem1Key = "subItem1"; - wups_storage_item subItem1 = nullptr; - res = WUPS_CreateSubItem(nullptr, subItem1Key, &subItem1); + auto subItem1 = WUPSStorageAPI::CreateSubItem(subItem1Key, res); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem1 != nullptr); + REQUIRE(subItem1); // delete subItem1 - res = WUPS_DeleteItem(nullptr, subItem1Key); + res = WUPSStorageAPI::DeleteItem(subItem1Key); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); // create subItem1 constexpr auto *itemKey = "item_in_1"; int32_t value = 13371337; - res = WUPS_Store(subItem1, itemKey, value); + res = subItem1->Store(itemKey, value); REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); } TEST_CASE("create sub-item of deleted sub-item should fail") { // make sure storage is closed - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); // create subItem1 constexpr auto *subItem1Key = "subItem1"; - wups_storage_item subItem1 = nullptr; - res = WUPS_CreateSubItem(nullptr, subItem1Key, &subItem1); + auto subItem1 = WUPSStorageAPI::CreateSubItem(subItem1Key, res); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem1 != nullptr); + REQUIRE(subItem1); // delete subItem1 - res = WUPS_DeleteItem(nullptr, subItem1Key); + res = WUPSStorageAPI::DeleteItem(subItem1Key); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); // create subItem1_1 constexpr auto *subItem1_1Key = "subItem1.1"; - wups_storage_item subItem1_1 = nullptr; - res = WUPS_CreateSubItem(subItem1, subItem1_1Key, &subItem1_1); + auto subItem1_1 = subItem1->CreateSubItem(subItem1_1Key, res); REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); - REQUIRE(subItem1 != nullptr); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(!subItem1_1); } - TEST_CASE("Load stored item from deleted sub-item should fail") { // make sure storage is closed - CleanUpStorage cleanup; - - auto res = WUPS_OpenStorage(); + auto res = WUPSStorageAPI::WipeStorage(); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); // create subItem1 constexpr auto *subItem1Key = "subItem1"; - wups_storage_item subItem1 = nullptr; - res = WUPS_CreateSubItem(nullptr, subItem1Key, &subItem1); + auto subItem1 = WUPSStorageAPI::CreateSubItem(subItem1Key, res); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); - REQUIRE(subItem1 != nullptr); + REQUIRE(subItem1); - // create subItem1 + // create item_in_1 constexpr auto *itemKey = "item_in_1"; int32_t value = 13371337; - res = WUPS_Store(subItem1, itemKey, value); + res = subItem1->Store(itemKey, value); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); // delete subItem1 - res = WUPS_DeleteItem(nullptr, subItem1Key); + res = WUPSStorageAPI::DeleteItem(subItem1Key); REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); // try to read value from deleted sub item int readValue = 0; - res = WUPS_Get(subItem1, itemKey, value); + res = subItem1->Get(itemKey, readValue); REQUIRE(res == WUPS_STORAGE_ERROR_NOT_FOUND); - - // Close to write the data to the storage - res = WUPS_CloseStorage(); - REQUIRE(res == WUPS_STORAGE_ERROR_SUCCESS); + REQUIRE(readValue == 0); } \ No newline at end of file