mirror of
https://github.com/wiiu-env/WiiUPluginSystem.git
synced 2025-01-11 09:09:06 +01:00
Rewrite of the StorageAPI
This commit is contained in:
parent
f0bf943f72
commit
58a2d3f734
9
Makefile
9
Makefile
@ -3,7 +3,7 @@ include $(TOPDIR)/share/wups_rules
|
|||||||
|
|
||||||
export WUPS_MAJOR := 0
|
export WUPS_MAJOR := 0
|
||||||
export WUPS_MINOR := 7
|
export WUPS_MINOR := 7
|
||||||
export WUPS_PATCH := 1
|
export WUPS_PATCH := 2
|
||||||
|
|
||||||
VERSION := $(WUPS_MAJOR).$(WUPS_MINOR).$(WUPS_PATCH)
|
VERSION := $(WUPS_MAJOR).$(WUPS_MINOR).$(WUPS_PATCH)
|
||||||
|
|
||||||
@ -16,8 +16,7 @@ VERSION := $(WUPS_MAJOR).$(WUPS_MINOR).$(WUPS_PATCH)
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := wups
|
TARGET := wups
|
||||||
#BUILD := build
|
#BUILD := build
|
||||||
SOURCES := libraries/libwups/ \
|
SOURCES := libraries/libwups/
|
||||||
libraries/libwups/utils
|
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include
|
INCLUDES := include
|
||||||
|
|
||||||
@ -104,10 +103,10 @@ lib:
|
|||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
|
||||||
release:
|
release:
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@$(shell [ ! -d 'release' ] && mkdir -p 'release')
|
||||||
|
|
||||||
debug:
|
debug:
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@$(shell [ ! -d 'debug' ] && mkdir -p 'debug')
|
||||||
|
|
||||||
lib/libwups.a : lib release $(SOURCES) $(INCLUDES)
|
lib/libwups.a : lib release $(SOURCES) $(INCLUDES)
|
||||||
@$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
|
@$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
|
||||||
|
@ -47,7 +47,7 @@ typedef enum wups_loader_hook_type_t {
|
|||||||
WUPS_LOADER_HOOK_GET_CONFIG,
|
WUPS_LOADER_HOOK_GET_CONFIG,
|
||||||
WUPS_LOADER_HOOK_CONFIG_CLOSED,
|
WUPS_LOADER_HOOK_CONFIG_CLOSED,
|
||||||
|
|
||||||
WUPS_LOADER_HOOK_INIT_STORAGE, /* Only for internal usage */
|
WUPS_LOADER_HOOK_INIT_STORAGE_DEPRECATED, /* Deprecated implementation */
|
||||||
|
|
||||||
WUPS_LOADER_HOOK_INIT_PLUGIN, /* Called when exiting the plugin loader */
|
WUPS_LOADER_HOOK_INIT_PLUGIN, /* Called when exiting the plugin loader */
|
||||||
WUPS_LOADER_HOOK_DEINIT_PLUGIN, /* Called when re-entering the plugin loader */
|
WUPS_LOADER_HOOK_DEINIT_PLUGIN, /* Called when re-entering the plugin loader */
|
||||||
@ -56,6 +56,8 @@ typedef enum wups_loader_hook_type_t {
|
|||||||
WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND, /* Called when an foreground is acquired */
|
WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND, /* Called when an foreground is acquired */
|
||||||
WUPS_LOADER_HOOK_APPLICATION_REQUESTS_EXIT, /* Called when an application wants to exit */
|
WUPS_LOADER_HOOK_APPLICATION_REQUESTS_EXIT, /* Called when an application wants to exit */
|
||||||
WUPS_LOADER_HOOK_APPLICATION_ENDS, /* Called when an application ends */
|
WUPS_LOADER_HOOK_APPLICATION_ENDS, /* Called when an application ends */
|
||||||
|
|
||||||
|
WUPS_LOADER_HOOK_INIT_STORAGE, /* Only for internal usage */
|
||||||
} wups_loader_hook_type_t;
|
} wups_loader_hook_type_t;
|
||||||
|
|
||||||
typedef struct wups_loader_hook_t {
|
typedef struct wups_loader_hook_t {
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define WUPS_VERSION_STR "0.7.1"
|
#define WUPS_VERSION_STR "0.7.2"
|
||||||
#define WUPS_PLUGIN_NAME(__plugin_name) \
|
#define WUPS_PLUGIN_NAME(__plugin_name) \
|
||||||
WUPS_META(name, __plugin_name); \
|
WUPS_META(name, __plugin_name); \
|
||||||
WUPS_META(wups, WUPS_VERSION_STR); \
|
WUPS_META(wups, WUPS_VERSION_STR); \
|
||||||
|
@ -7,48 +7,64 @@ extern "C" {
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef enum wups_storage_type_t_ {
|
|
||||||
WUPS_STORAGE_TYPE_INVALID,
|
|
||||||
WUPS_STORAGE_TYPE_STRING,
|
|
||||||
WUPS_STORAGE_TYPE_INT,
|
|
||||||
WUPS_STORAGE_TYPE_ITEM,
|
|
||||||
} wups_storage_type_t;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
WUPS_STORAGE_ERROR_SUCCESS = 0,
|
WUPS_STORAGE_ERROR_SUCCESS = 0,
|
||||||
WUPS_STORAGE_ERROR_NOT_OPENED = -1,
|
WUPS_STORAGE_ERROR_INVALID_ARGS = 1,
|
||||||
WUPS_STORAGE_ERROR_ALREADY_OPENED = -2,
|
WUPS_STORAGE_ERROR_INVALID_POINTER = 2,
|
||||||
WUPS_STORAGE_ERROR_INVALID_ARGS = -3,
|
WUPS_STORAGE_ERROR_INVALID_VERSION = 3,
|
||||||
WUPS_STORAGE_ERROR_NOT_FOUND = -4,
|
WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE = 4,
|
||||||
WUPS_STORAGE_ERROR_NOT_INITIALIZED = -5,
|
WUPS_STORAGE_ERROR_NOT_FOUND = 5,
|
||||||
WUPS_STORAGE_ERROR_INVALID_BACKEND_PARAMS = -6,
|
WUPS_STORAGE_ERROR_MALLOC_FAILED = 6,
|
||||||
WUPS_STORAGE_ERROR_INVALID_JSON = -7,
|
WUPS_STORAGE_ERROR_ALREADY_OPENED = 7,
|
||||||
WUPS_STORAGE_ERROR_IO = -8,
|
WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL = 8,
|
||||||
WUPS_STORAGE_ERROR_B64_DECODE_FAILED = -9,
|
WUPS_STORAGE_ERROR_ALREADY_EXISTS = 9,
|
||||||
WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL = -10,
|
WUPS_STORAGE_ERROR_UNKNOWN_ERROR = 10
|
||||||
WUPS_STORAGE_ERROR_MALLOC_FAILED = -11,
|
|
||||||
WUPS_STORAGE_ERROR_NOT_ACTIVE_CATEGORY = -13,
|
|
||||||
} WUPSStorageError;
|
} WUPSStorageError;
|
||||||
|
|
||||||
typedef struct wups_storage_item_t_ {
|
typedef enum {
|
||||||
char *key;
|
WUPS_STORAGE_ITEM_S32 = 0,
|
||||||
void *data;
|
WUPS_STORAGE_ITEM_S64 = 1,
|
||||||
uint32_t data_size;
|
WUPS_STORAGE_ITEM_U32 = 2,
|
||||||
uint32_t deleted;
|
WUPS_STORAGE_ITEM_U64 = 3,
|
||||||
wups_storage_type_t type;
|
WUPS_STORAGE_ITEM_STRING = 4,
|
||||||
} wups_storage_item_t;
|
WUPS_STORAGE_ITEM_BINARY = 5,
|
||||||
|
WUPS_STORAGE_ITEM_BOOL = 6,
|
||||||
|
WUPS_STORAGE_ITEM_FLOAT = 7,
|
||||||
|
WUPS_STORAGE_ITEM_DOUBLE = 8,
|
||||||
|
} WUPSStorageItemTypes;
|
||||||
|
|
||||||
typedef WUPSStorageError (*OpenStorageFunction)(const char *plugin_id, wups_storage_item_t *items);
|
typedef uint32_t WUPSStorageItemType;
|
||||||
typedef WUPSStorageError (*CloseStorageFunction)(const char *plugin_id, wups_storage_item_t *items);
|
|
||||||
|
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 uint32_t WUPS_STORAGE_API_VERSION;
|
||||||
|
#define WUPS_STORAGE_CUR_API_VERSION 0x02
|
||||||
|
|
||||||
typedef struct wups_loader_init_storage_args_t_ {
|
typedef struct wups_loader_init_storage_args_t_ {
|
||||||
|
WUPS_STORAGE_API_VERSION version;
|
||||||
OpenStorageFunction open_storage_ptr;
|
OpenStorageFunction open_storage_ptr;
|
||||||
CloseStorageFunction close_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;
|
const char *plugin_id;
|
||||||
} wups_loader_init_storage_args_t;
|
} wups_loader_init_storage_args_t;
|
||||||
|
|
||||||
/* called by backend */
|
/* called by backend */
|
||||||
void WUPS_InitStorage(wups_loader_init_storage_args_t args);
|
WUPSStorageError WUPS_InitStorage(wups_loader_init_storage_args_t args);
|
||||||
|
|
||||||
const char *WUPS_GetStorageStatusStr(WUPSStorageError status);
|
const char *WUPS_GetStorageStatusStr(WUPSStorageError status);
|
||||||
|
|
||||||
@ -59,24 +75,37 @@ WUPSStorageError WUPS_OpenStorage(void);
|
|||||||
WUPSStorageError WUPS_CloseStorage(void);
|
WUPSStorageError WUPS_CloseStorage(void);
|
||||||
|
|
||||||
/* deletes key from storage */
|
/* deletes key from storage */
|
||||||
WUPSStorageError WUPS_DeleteItem(wups_storage_item_t *parent, const char *key);
|
WUPSStorageError WUPS_DeleteItem(wups_storage_item parent, const char *key);
|
||||||
|
|
||||||
/* returns the size of key on success, or an error code */
|
WUPSStorageError WUPS_CreateSubItem(wups_storage_item parent, const char *key, wups_storage_item *outItem);
|
||||||
// TODO do we need this? what about binary data?
|
WUPSStorageError WUPS_GetSubItem(wups_storage_item parent, const char *key, wups_storage_item *outItem);
|
||||||
// int32_t WUPS_GetSize(const char* key);
|
|
||||||
|
|
||||||
WUPSStorageError WUPS_CreateSubItem(wups_storage_item_t *parent, const char *key, wups_storage_item_t **outItem);
|
WUPSStorageError WUPS_StoreString(wups_storage_item parent, const char *key, const char *string);
|
||||||
WUPSStorageError WUPS_GetSubItem(wups_storage_item_t *parent, const char *key, wups_storage_item_t **outItem);
|
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);
|
||||||
|
|
||||||
WUPSStorageError WUPS_StoreString(wups_storage_item_t *parent, const char *key, const char *string);
|
WUPSStorageError WUPS_GetString(wups_storage_item parent, const char *key, char *outString, uint32_t maxSize, uint32_t *outSize);
|
||||||
WUPSStorageError WUPS_StoreBool(wups_storage_item_t *parent, const char *key, bool value);
|
WUPSStorageError WUPS_GetBool(wups_storage_item parent, const char *key, bool *outValue);
|
||||||
WUPSStorageError WUPS_StoreInt(wups_storage_item_t *parent, const char *key, int32_t value);
|
WUPSStorageError WUPS_GetInt(wups_storage_item parent, const char *key, int32_t *outValue);
|
||||||
WUPSStorageError WUPS_StoreBinary(wups_storage_item_t *parent, const char *key, const void *data, uint32_t size);
|
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);
|
||||||
|
|
||||||
WUPSStorageError WUPS_GetString(wups_storage_item_t *parent, const char *key, char *outString, uint32_t maxSize);
|
/**
|
||||||
WUPSStorageError WUPS_GetBool(wups_storage_item_t *parent, const char *key, bool *outBool);
|
* Return the size of a stored string or binary item.
|
||||||
WUPSStorageError WUPS_GetInt(wups_storage_item_t *parent, const char *key, int32_t *outInt);
|
*/
|
||||||
WUPSStorageError WUPS_GetBinary(wups_storage_item_t *parent, const char *key, void *outData, uint32_t maxSize);
|
WUPSStorageError WUPS_GetItemSize(wups_storage_item parent, const char *key, uint32_t *outSize);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -2,632 +2,249 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <wups.h>
|
#include <wups.h>
|
||||||
|
|
||||||
#include "utils/base64.h"
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
static OpenStorageFunction openfunction_ptr __attribute__((section(".data"))) = nullptr;
|
static wups_internal_functions_t __internal_functions __attribute__((section(".data"))) = {};
|
||||||
static CloseStorageFunction closefunction_ptr __attribute__((section(".data"))) = nullptr;
|
|
||||||
static char plugin_id[256] __attribute__((section(".data")));
|
|
||||||
|
|
||||||
static uint32_t storage_initialized __attribute__((section(".data"))) = false;
|
WUPSStorageError WUPS_InitStorage(wups_loader_init_storage_args_t args) {
|
||||||
static uint32_t isOpened __attribute__((section(".data")));
|
if (args.version != WUPS_STORAGE_CUR_API_VERSION) {
|
||||||
static uint32_t isDirty __attribute__((section(".data")));
|
__internal_functions = {};
|
||||||
static wups_storage_item_t rootItem __attribute__((section(".data")));
|
return WUPS_STORAGE_ERROR_INVALID_VERSION;
|
||||||
|
}
|
||||||
|
__internal_functions.openfunction_ptr = args.open_storage_ptr;
|
||||||
|
__internal_functions.closefunction_ptr = args.close_storage_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;
|
||||||
|
__internal_functions.store_item_function_ptr = args.store_item_function_ptr;
|
||||||
|
__internal_functions.get_item_function_ptr = args.get_item_function_ptr;
|
||||||
|
__internal_functions.get_item_size_function_ptr = args.get_item_size_function_ptr;
|
||||||
|
|
||||||
static wups_storage_item_t *sActiveSubItem __attribute__((section(".data"))) = nullptr;
|
strncpy(__internal_functions.plugin_id, args.plugin_id, sizeof(__internal_functions.plugin_id) - 1);
|
||||||
|
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||||
void WUPS_InitStorage(wups_loader_init_storage_args_t args) {
|
|
||||||
openfunction_ptr = args.open_storage_ptr;
|
|
||||||
closefunction_ptr = args.close_storage_ptr;
|
|
||||||
strncpy(plugin_id, args.plugin_id, sizeof(plugin_id) - 1);
|
|
||||||
|
|
||||||
storage_initialized = true;
|
|
||||||
isOpened = false;
|
|
||||||
isDirty = false;
|
|
||||||
sActiveSubItem = nullptr;
|
|
||||||
|
|
||||||
rootItem.key = nullptr;
|
|
||||||
rootItem.data = nullptr;
|
|
||||||
rootItem.data_size = 0;
|
|
||||||
rootItem.deleted = false;
|
|
||||||
rootItem.type = WUPS_STORAGE_TYPE_ITEM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *WUPS_GetStorageStatusStr(WUPSStorageError status) {
|
const char *WUPS_GetStorageStatusStr(WUPSStorageError status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case WUPS_STORAGE_ERROR_SUCCESS:
|
case WUPS_STORAGE_ERROR_SUCCESS:
|
||||||
return "WUPS_STORAGE_ERROR_SUCCESS";
|
return "WUPS_STORAGE_ERROR_SUCCESS";
|
||||||
case WUPS_STORAGE_ERROR_NOT_OPENED:
|
|
||||||
return "WUPS_STORAGE_ERROR_NOT_OPENED";
|
|
||||||
case WUPS_STORAGE_ERROR_ALREADY_OPENED:
|
|
||||||
return "WUPS_STORAGE_ERROR_ALREADY_OPENED";
|
|
||||||
case WUPS_STORAGE_ERROR_INVALID_ARGS:
|
case WUPS_STORAGE_ERROR_INVALID_ARGS:
|
||||||
return "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:
|
case WUPS_STORAGE_ERROR_NOT_FOUND:
|
||||||
return "WUPS_STORAGE_ERROR_NOT_FOUND";
|
return "WUPS_STORAGE_ERROR_NOT_FOUND";
|
||||||
case WUPS_STORAGE_ERROR_NOT_INITIALIZED:
|
|
||||||
return "WUPS_STORAGE_ERROR_NOT_INITIALIZED";
|
|
||||||
case WUPS_STORAGE_ERROR_INVALID_BACKEND_PARAMS:
|
|
||||||
return "WUPS_STORAGE_ERROR_INVALID_BACKEND_PARAMS";
|
|
||||||
case WUPS_STORAGE_ERROR_INVALID_JSON:
|
|
||||||
return "WUPS_STORAGE_ERROR_INVALID_JSON";
|
|
||||||
case WUPS_STORAGE_ERROR_IO:
|
|
||||||
return "WUPS_STORAGE_ERROR_IO";
|
|
||||||
case WUPS_STORAGE_ERROR_B64_DECODE_FAILED:
|
|
||||||
return "WUPS_STORAGE_ERROR_B64_DECODE_FAILED";
|
|
||||||
case WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL:
|
|
||||||
return "WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL";
|
|
||||||
case WUPS_STORAGE_ERROR_MALLOC_FAILED:
|
case WUPS_STORAGE_ERROR_MALLOC_FAILED:
|
||||||
return "WUPS_STORAGE_ERROR_MALLOC_FAILED";
|
return "WUPS_STORAGE_ERROR_MALLOC_FAILED";
|
||||||
case WUPS_STORAGE_ERROR_NOT_ACTIVE_CATEGORY:
|
case WUPS_STORAGE_ERROR_ALREADY_OPENED:
|
||||||
return "WUPS_STORAGE_ERROR_NOT_ACTIVE_CATEGORY";
|
return "WUPS_STORAGE_ERROR_ALREADY_OPENED";
|
||||||
|
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_UNKNOWN_ERROR:
|
||||||
|
return "WUPS_STORAGE_ERROR_UNKNOWN_ERROR";
|
||||||
}
|
}
|
||||||
return "WUPS_STORAGE_ERROR_UNKNOWN";
|
return "WUPS_STORAGE_ERROR_UNKNOWN";
|
||||||
}
|
}
|
||||||
|
|
||||||
WUPSStorageError WUPS_OpenStorage(void) {
|
WUPSStorageError WUPS_OpenStorage(void) {
|
||||||
if (!storage_initialized) {
|
if (__internal_functions.openfunction_ptr == nullptr) {
|
||||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
return WUPS_STORAGE_ERROR_INVALID_POINTER;
|
||||||
}
|
}
|
||||||
|
auto res = __internal_functions.openfunction_ptr(__internal_functions.plugin_id, &__internal_functions.__storageroot_item);
|
||||||
if (isOpened) {
|
if (res != WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
return WUPS_STORAGE_ERROR_ALREADY_OPENED;
|
__internal_functions.__storageroot_item = nullptr;
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
WUPSStorageError result = openfunction_ptr(plugin_id, &rootItem);
|
|
||||||
|
|
||||||
if (result == WUPS_STORAGE_ERROR_SUCCESS || result == WUPS_STORAGE_ERROR_INVALID_JSON) {
|
|
||||||
isOpened = true;
|
|
||||||
isDirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void closeItem(wups_storage_item_t *item) {
|
|
||||||
if (!item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item->type == WUPS_STORAGE_TYPE_ITEM) {
|
|
||||||
auto *items = (wups_storage_item_t *) item->data;
|
|
||||||
for (uint32_t i = 0; i < item->data_size; i++) {
|
|
||||||
closeItem(&items[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(item->data);
|
|
||||||
free(item->key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WUPSStorageError WUPS_CloseStorage(void) {
|
WUPSStorageError WUPS_CloseStorage(void) {
|
||||||
if (!storage_initialized) {
|
if (__internal_functions.closefunction_ptr == nullptr) {
|
||||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
return WUPS_STORAGE_ERROR_INVALID_POINTER;
|
||||||
|
}
|
||||||
|
auto res = __internal_functions.closefunction_ptr(__internal_functions.plugin_id);
|
||||||
|
if (res == WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
|
__internal_functions.__storageroot_item = nullptr;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isOpened) {
|
WUPSStorageError WUPS_DeleteItem(wups_storage_item parent, const char *key) {
|
||||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
if (__internal_functions.delete_item_function_ptr == nullptr) {
|
||||||
|
return WUPS_STORAGE_ERROR_INVALID_POINTER;
|
||||||
|
}
|
||||||
|
return __internal_functions.delete_item_function_ptr(__internal_functions.__storageroot_item, parent, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
WUPSStorageError result = WUPS_STORAGE_ERROR_SUCCESS;
|
WUPSStorageError WUPS_CreateSubItem(wups_storage_item parent, const char *key, wups_storage_item *outItem) {
|
||||||
if (isDirty) {
|
if (__internal_functions.create_sub_item_function_ptr == nullptr) {
|
||||||
result = closefunction_ptr(plugin_id, &rootItem);
|
return WUPS_STORAGE_ERROR_INVALID_POINTER;
|
||||||
|
}
|
||||||
|
return __internal_functions.create_sub_item_function_ptr(__internal_functions.__storageroot_item, parent, key, outItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == WUPS_STORAGE_ERROR_SUCCESS) {
|
WUPSStorageError WUPS_GetSubItem(wups_storage_item parent, const char *key, wups_storage_item *outItem) {
|
||||||
isOpened = false;
|
if (__internal_functions.get_sub_item_function_ptr == nullptr) {
|
||||||
isDirty = false;
|
return WUPS_STORAGE_ERROR_INVALID_POINTER;
|
||||||
|
|
||||||
closeItem(&rootItem);
|
|
||||||
rootItem.data_size = 0;
|
|
||||||
rootItem.data = nullptr;
|
|
||||||
rootItem.key = nullptr;
|
|
||||||
}
|
}
|
||||||
sActiveSubItem = nullptr;
|
return __internal_functions.get_sub_item_function_ptr(__internal_functions.__storageroot_item, parent, key, outItem);
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WUPSStorageError WUPS_DeleteItem(wups_storage_item_t *parent, const char *key) {
|
static inline WUPSStorageError WUPS_StoreItem(wups_storage_item parent, const char *key, WUPSStorageItemType type, void *data, uint32_t size) {
|
||||||
if (!storage_initialized) {
|
if (__internal_functions.store_item_function_ptr == nullptr) {
|
||||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
return WUPS_STORAGE_ERROR_INVALID_POINTER;
|
||||||
|
}
|
||||||
|
return __internal_functions.store_item_function_ptr(__internal_functions.__storageroot_item, parent, key, type, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isOpened) {
|
WUPSStorageError WUPS_StoreString(wups_storage_item parent, const char *key, const char *value) {
|
||||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
if (value == nullptr) {
|
||||||
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
return WUPS_StoreItem(parent, key, WUPS_STORAGE_ITEM_STRING, (void *) value, strlen(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!key) {
|
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) {
|
||||||
|
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 __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_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parent) {
|
return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_STRING, outString, maxSize, outSize);
|
||||||
parent = &rootItem;
|
|
||||||
} else {
|
|
||||||
// We can only safely process items of a parent if the parent was the last
|
|
||||||
// item returned by WUPS_GetSubItem or WUPS_CreateSubItem
|
|
||||||
if (parent != sActiveSubItem) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_ACTIVE_CATEGORY;
|
|
||||||
}
|
}
|
||||||
if (parent->type != WUPS_STORAGE_TYPE_ITEM) {
|
|
||||||
|
WUPSStorageError WUPS_GetBool(wups_storage_item parent, const char *key, bool *outValue) {
|
||||||
|
if (outValue == nullptr) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_BOOL, outValue, sizeof(*outValue), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
isDirty = true;
|
WUPSStorageError WUPS_GetInt(wups_storage_item parent, const char *key, int32_t *outValue) {
|
||||||
|
if (outValue == nullptr) {
|
||||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
}
|
||||||
|
return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_S32, outValue, sizeof(*outValue), nullptr);
|
||||||
if (item->deleted || item->type == WUPS_STORAGE_TYPE_INVALID) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(item->key, key) == 0) {
|
WUPSStorageError WUPS_GetS32(wups_storage_item parent, const char *key, int32_t *outValue) {
|
||||||
free(item->data);
|
if (outValue == nullptr) {
|
||||||
free(item->key);
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
item->key = nullptr;
|
|
||||||
item->data = nullptr;
|
|
||||||
item->deleted = true;
|
|
||||||
if (sActiveSubItem == item) {
|
|
||||||
sActiveSubItem = nullptr;
|
|
||||||
}
|
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_S32, outValue, sizeof(*outValue), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// int32_t WUPS_GetSize(const char* key) {
|
WUPSStorageError WUPS_GetU32(wups_storage_item parent, const char *key, uint32_t *outValue) {
|
||||||
// if (!storage_initialized) {
|
if (outValue == nullptr) {
|
||||||
// return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
// }
|
|
||||||
|
|
||||||
// if (!isOpened) {
|
|
||||||
// return WUPS_STORAGE_ERROR_NOT_OPENED;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for (uint32_t i = 0; i < amount_of_items; i++) {
|
|
||||||
// wups_loader_storage_item_t* item = &items[i];
|
|
||||||
|
|
||||||
// if (item->pending_delete || item->type == WUPS_STORAGE_TYPE_INVALID) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (strcmp(item->key, key) == 0) {
|
|
||||||
// return item->data_size;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return WUPS_STORAGE_ERROR_NOT_FOUND;
|
|
||||||
// }
|
|
||||||
|
|
||||||
static wups_storage_item_t *addItem(wups_storage_item_t *parent, const char *key, wups_storage_type_t type, WUPSStorageError *error) {
|
|
||||||
wups_storage_item_t *foundItem = nullptr;
|
|
||||||
// First check for existing item with the same name.
|
|
||||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
|
||||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
|
||||||
|
|
||||||
if (item->key && strcmp(item->key, key) == 0) {
|
|
||||||
free(item->data);
|
|
||||||
foundItem = item;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_U32, outValue, sizeof(*outValue), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundItem) {
|
WUPSStorageError WUPS_GetU64(wups_storage_item parent, const char *key, uint64_t *outValue) {
|
||||||
// Then check if there are any deleted item we can override.
|
if (outValue == nullptr) {
|
||||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
}
|
||||||
|
return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_U64, outValue, sizeof(*outValue), nullptr);
|
||||||
if (item->deleted) {
|
|
||||||
free(item->data);
|
|
||||||
free(item->key);
|
|
||||||
item->data = nullptr;
|
|
||||||
item->key = nullptr;
|
|
||||||
|
|
||||||
item->key = strdup(key);
|
|
||||||
if (item->key == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foundItem = item;
|
WUPSStorageError WUPS_GetFloat(wups_storage_item parent, const char *key, float *outValue) {
|
||||||
break;
|
if (outValue == nullptr) {
|
||||||
}
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_FLOAT, outValue, sizeof(*outValue), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundItem) {
|
WUPSStorageError WUPS_GetDouble(wups_storage_item parent, const char *key, double *outValue) {
|
||||||
auto *newPtr = (wups_storage_item_t *) realloc(parent->data, (parent->data_size + 1) * sizeof(wups_storage_item_t));
|
if (outValue == nullptr) {
|
||||||
if (newPtr == nullptr) {
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
*error = WUPS_STORAGE_ERROR_MALLOC_FAILED;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
parent->data = newPtr;
|
|
||||||
|
|
||||||
foundItem = &((wups_storage_item_t *) parent->data)[parent->data_size];
|
|
||||||
memset(foundItem, 0, sizeof(wups_storage_item_t));
|
|
||||||
foundItem->deleted = true;
|
|
||||||
|
|
||||||
parent->data_size += 1;
|
|
||||||
|
|
||||||
foundItem->key = strdup(key);
|
|
||||||
if (foundItem->key == nullptr) {
|
|
||||||
*error = WUPS_STORAGE_ERROR_MALLOC_FAILED;
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_DOUBLE, outValue, sizeof(*outValue), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
foundItem->type = type;
|
WUPSStorageError WUPS_GetBinary(wups_storage_item parent, const char *key, void *outData, uint32_t maxSize, uint32_t *outValue) {
|
||||||
foundItem->deleted = false;
|
if (outData == nullptr) {
|
||||||
foundItem->data = nullptr;
|
|
||||||
foundItem->data_size = 0;
|
|
||||||
return foundItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
WUPSStorageError WUPS_CreateSubItem(wups_storage_item_t *parent, const char *key, wups_storage_item_t **outItem) {
|
|
||||||
if (!storage_initialized) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isOpened) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!key || !outItem) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parent) {
|
return WUPS_GetItem(parent, key, WUPS_STORAGE_ITEM_BINARY, outData, maxSize, outValue);
|
||||||
parent = &rootItem;
|
|
||||||
} else {
|
|
||||||
// We can only safely process items of a parent if the parent was the last
|
|
||||||
// item returned by WUPS_GetSubItem or WUPS_CreateSubItem
|
|
||||||
if (parent != sActiveSubItem) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_ACTIVE_CATEGORY;
|
|
||||||
}
|
|
||||||
if (parent->type != WUPS_STORAGE_TYPE_ITEM) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isDirty = true;
|
WUPSStorageError WUPS_GetItemSize(wups_storage_item parent, const char *key, uint32_t *outSize) {
|
||||||
|
if (outSize == nullptr) {
|
||||||
WUPSStorageError error;
|
|
||||||
wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_ITEM, &error);
|
|
||||||
if (item == nullptr) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
sActiveSubItem = item;
|
|
||||||
|
|
||||||
*outItem = item;
|
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
WUPSStorageError WUPS_GetSubItem(wups_storage_item_t *parent, const char *key, wups_storage_item_t **outItem) {
|
|
||||||
if (!storage_initialized) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isOpened) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!key || outItem == nullptr) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parent) {
|
if (__internal_functions.get_item_size_function_ptr == nullptr) {
|
||||||
parent = &rootItem;
|
return WUPS_STORAGE_ERROR_INVALID_POINTER;
|
||||||
} else {
|
|
||||||
// We can only safely process items of a parent if the parent was the last
|
|
||||||
// item returned by WUPS_GetSubItem or WUPS_CreateSubItem
|
|
||||||
if (parent != sActiveSubItem) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_ACTIVE_CATEGORY;
|
|
||||||
}
|
}
|
||||||
if (parent->type != WUPS_STORAGE_TYPE_ITEM) {
|
return __internal_functions.get_item_size_function_ptr(__internal_functions.__storageroot_item, parent, key, outSize);
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
|
||||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
|
||||||
|
|
||||||
if (item->deleted || item->type != WUPS_STORAGE_TYPE_ITEM) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(item->key, key) == 0) {
|
|
||||||
sActiveSubItem = item;
|
|
||||||
*outItem = item;
|
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
WUPSStorageError WUPS_StoreString(wups_storage_item_t *parent, const char *key, const char *string) {
|
|
||||||
if (!storage_initialized) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isOpened) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!key || !string) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parent) {
|
|
||||||
parent = &rootItem;
|
|
||||||
} else {
|
|
||||||
// We can only safely process items of a parent if the parent was the last
|
|
||||||
// item returned by WUPS_GetSubItem or WUPS_CreateSubItem
|
|
||||||
if (parent != sActiveSubItem) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_ACTIVE_CATEGORY;
|
|
||||||
}
|
|
||||||
if (parent->type != WUPS_STORAGE_TYPE_ITEM) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isDirty = true;
|
|
||||||
|
|
||||||
WUPSStorageError error;
|
|
||||||
wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_STRING, &error);
|
|
||||||
if (item == nullptr) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t size = strlen(string) + 1;
|
|
||||||
item->data = malloc(size);
|
|
||||||
if (item->data == nullptr) {
|
|
||||||
item->key = nullptr;
|
|
||||||
item->deleted = true;
|
|
||||||
return WUPS_STORAGE_ERROR_MALLOC_FAILED;
|
|
||||||
}
|
|
||||||
item->data_size = size;
|
|
||||||
strcpy((char *) item->data, string);
|
|
||||||
|
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
WUPSStorageError WUPS_StoreBool(wups_storage_item_t *parent, const char *key, bool value) {
|
|
||||||
return WUPS_StoreInt(parent, key, (int32_t) value);
|
|
||||||
}
|
|
||||||
|
|
||||||
WUPSStorageError WUPS_StoreInt(wups_storage_item_t *parent, const char *key, int32_t value) {
|
|
||||||
if (!storage_initialized) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isOpened) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!key) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parent) {
|
|
||||||
parent = &rootItem;
|
|
||||||
} else {
|
|
||||||
// We can only safely process items of a parent if the parent was the last
|
|
||||||
// item returned by WUPS_GetSubItem or WUPS_CreateSubItem
|
|
||||||
if (parent != sActiveSubItem) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_ACTIVE_CATEGORY;
|
|
||||||
}
|
|
||||||
if (parent->type != WUPS_STORAGE_TYPE_ITEM) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isDirty = true;
|
|
||||||
|
|
||||||
WUPSStorageError error;
|
|
||||||
wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_INT, &error);
|
|
||||||
if (item == nullptr) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
item->data = malloc(sizeof(int32_t));
|
|
||||||
if (item->data == nullptr) {
|
|
||||||
item->key = nullptr;
|
|
||||||
item->deleted = true;
|
|
||||||
return WUPS_STORAGE_ERROR_MALLOC_FAILED;
|
|
||||||
}
|
|
||||||
item->data_size = sizeof(int32_t);
|
|
||||||
*(int32_t *) item->data = value;
|
|
||||||
|
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
WUPSStorageError WUPS_StoreBinary(wups_storage_item_t *parent, const char *key, const void *data, uint32_t size) {
|
|
||||||
if (!storage_initialized) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isOpened) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!key || !data || size == 0) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parent) {
|
|
||||||
parent = &rootItem;
|
|
||||||
} else {
|
|
||||||
// We can only safely process items of a parent if the parent was the last
|
|
||||||
// item returned by WUPS_GetSubItem or WUPS_CreateSubItem
|
|
||||||
if (parent != sActiveSubItem) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_ACTIVE_CATEGORY;
|
|
||||||
}
|
|
||||||
if (parent->type != WUPS_STORAGE_TYPE_ITEM) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isDirty = true;
|
|
||||||
|
|
||||||
WUPSStorageError error;
|
|
||||||
wups_storage_item_t *item = addItem(parent, key, WUPS_STORAGE_TYPE_STRING, &error);
|
|
||||||
if (item == nullptr) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
item->data = b64_encode((const uint8_t *) data, size);
|
|
||||||
if (item->data == nullptr) {
|
|
||||||
item->key = nullptr;
|
|
||||||
item->deleted = true;
|
|
||||||
return WUPS_STORAGE_ERROR_MALLOC_FAILED;
|
|
||||||
}
|
|
||||||
item->data_size = strlen((char *) data) + 1;
|
|
||||||
|
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
WUPSStorageError WUPS_GetString(wups_storage_item_t *parent, const char *key, char *outString, uint32_t maxSize) {
|
|
||||||
if (!storage_initialized) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isOpened) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!key || !outString || maxSize == 0) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parent) {
|
|
||||||
parent = &rootItem;
|
|
||||||
} else {
|
|
||||||
// We can only safely process items of a parent if the parent was the last
|
|
||||||
// item returned by WUPS_GetSubItem or WUPS_CreateSubItem
|
|
||||||
if (parent != sActiveSubItem) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_ACTIVE_CATEGORY;
|
|
||||||
}
|
|
||||||
if (parent->type != WUPS_STORAGE_TYPE_ITEM) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
|
||||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
|
||||||
|
|
||||||
if (item->deleted || item->type != WUPS_STORAGE_TYPE_STRING) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(item->key, key) == 0) {
|
|
||||||
strncpy(outString, (char *) item->data, maxSize);
|
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
WUPSStorageError WUPS_GetBool(wups_storage_item_t *parent, const char *key, bool *outBool) {
|
|
||||||
int32_t out;
|
|
||||||
WUPSStorageError result = WUPS_GetInt(parent, key, &out);
|
|
||||||
if (result != WUPS_STORAGE_ERROR_SUCCESS) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
*outBool = out != 0;
|
|
||||||
|
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
WUPSStorageError WUPS_GetInt(wups_storage_item_t *parent, const char *key, int32_t *outInt) {
|
|
||||||
if (!storage_initialized) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isOpened) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!key || !outInt) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parent) {
|
|
||||||
parent = &rootItem;
|
|
||||||
} else {
|
|
||||||
// We can only safely process items of a parent if the parent was the last
|
|
||||||
// item returned by WUPS_GetSubItem or WUPS_CreateSubItem
|
|
||||||
if (parent != sActiveSubItem) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_ACTIVE_CATEGORY;
|
|
||||||
}
|
|
||||||
if (parent->type != WUPS_STORAGE_TYPE_ITEM) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
|
||||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
|
||||||
|
|
||||||
if (item->deleted || item->type != WUPS_STORAGE_TYPE_INT) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(item->key, key) == 0) {
|
|
||||||
*outInt = *(int32_t *) item->data;
|
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
WUPSStorageError WUPS_GetBinary(wups_storage_item_t *parent, const char *key, void *outData, uint32_t maxSize) {
|
|
||||||
if (!storage_initialized) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isOpened) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_OPENED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!key || !outData || maxSize == 0) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parent) {
|
|
||||||
parent = &rootItem;
|
|
||||||
} else {
|
|
||||||
// We can only safely process items of a parent if the parent was the last
|
|
||||||
// item returned by WUPS_GetSubItem or WUPS_CreateSubItem
|
|
||||||
if (parent != sActiveSubItem) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_ACTIVE_CATEGORY;
|
|
||||||
}
|
|
||||||
if (parent->type != WUPS_STORAGE_TYPE_ITEM) {
|
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < parent->data_size; i++) {
|
|
||||||
wups_storage_item_t *item = &((wups_storage_item_t *) parent->data)[i];
|
|
||||||
|
|
||||||
if (item->deleted || item->type != WUPS_STORAGE_TYPE_STRING) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(item->key, key) == 0) {
|
|
||||||
if (b64_decoded_size((char *) item->data) > maxSize) {
|
|
||||||
return WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b64_decode((char *) item->data, (uint8_t *) outData, item->data_size)) {
|
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
|
||||||
} else {
|
|
||||||
return WUPS_STORAGE_ERROR_B64_DECODE_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
|
||||||
}
|
}
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
#include "base64.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
||||||
|
|
||||||
size_t b64_encoded_size(size_t inlen) {
|
|
||||||
size_t ret;
|
|
||||||
|
|
||||||
ret = inlen;
|
|
||||||
if (inlen % 3 != 0)
|
|
||||||
ret += 3 - (inlen % 3);
|
|
||||||
ret /= 3;
|
|
||||||
ret *= 4;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *b64_encode(const uint8_t *in, size_t len) {
|
|
||||||
char *out;
|
|
||||||
size_t elen;
|
|
||||||
size_t i;
|
|
||||||
size_t j;
|
|
||||||
size_t v;
|
|
||||||
|
|
||||||
if (in == NULL || len == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
elen = b64_encoded_size(len);
|
|
||||||
out = (char *) malloc(elen + 1);
|
|
||||||
out[elen] = '\0';
|
|
||||||
|
|
||||||
for (i = 0, j = 0; i < len; i += 3, j += 4) {
|
|
||||||
v = in[i];
|
|
||||||
v = i + 1 < len ? v << 8 | in[i + 1] : v << 8;
|
|
||||||
v = i + 2 < len ? v << 8 | in[i + 2] : v << 8;
|
|
||||||
|
|
||||||
out[j] = b64chars[(v >> 18) & 0x3F];
|
|
||||||
out[j + 1] = b64chars[(v >> 12) & 0x3F];
|
|
||||||
if (i + 1 < len) {
|
|
||||||
out[j + 2] = b64chars[(v >> 6) & 0x3F];
|
|
||||||
} else {
|
|
||||||
out[j + 2] = '=';
|
|
||||||
}
|
|
||||||
if (i + 2 < len) {
|
|
||||||
out[j + 3] = b64chars[v & 0x3F];
|
|
||||||
} else {
|
|
||||||
out[j + 3] = '=';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t b64_decoded_size(const char *in) {
|
|
||||||
size_t len;
|
|
||||||
size_t ret;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (in == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
len = strlen(in);
|
|
||||||
ret = len / 4 * 3;
|
|
||||||
|
|
||||||
for (i = len; i-- > 0;) {
|
|
||||||
if (in[i] == '=') {
|
|
||||||
ret--;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const int b64invs[] = {
|
|
||||||
62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3,
|
|
||||||
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
|
||||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
|
|
||||||
|
|
||||||
static int b64_isvalidchar(char c) {
|
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
return 1;
|
|
||||||
if (c >= 'A' && c <= 'Z')
|
|
||||||
return 1;
|
|
||||||
if (c >= 'a' && c <= 'z')
|
|
||||||
return 1;
|
|
||||||
if (c == '+' || c == '/' || c == '=')
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int b64_decode(const char *in, uint8_t *out, size_t outlen) {
|
|
||||||
size_t len;
|
|
||||||
size_t i;
|
|
||||||
size_t j;
|
|
||||||
int v;
|
|
||||||
|
|
||||||
if (in == NULL || out == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
len = strlen(in);
|
|
||||||
if (outlen < b64_decoded_size(in) || len % 4 != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
if (!b64_isvalidchar(in[i])) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0, j = 0; i < len; i += 4, j += 3) {
|
|
||||||
v = b64invs[in[i] - 43];
|
|
||||||
v = (v << 6) | b64invs[in[i + 1] - 43];
|
|
||||||
v = in[i + 2] == '=' ? v << 6 : (v << 6) | b64invs[in[i + 2] - 43];
|
|
||||||
v = in[i + 3] == '=' ? v << 6 : (v << 6) | b64invs[in[i + 3] - 43];
|
|
||||||
|
|
||||||
out[j] = (v >> 16) & 0xFF;
|
|
||||||
if (in[i + 2] != '=')
|
|
||||||
out[j + 1] = (v >> 8) & 0xFF;
|
|
||||||
if (in[i + 3] != '=')
|
|
||||||
out[j + 2] = v & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// based on https://nachtimwald.com/2017/11/18/base64-encode-and-decode-in-c/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
size_t b64_encoded_size(size_t inlen);
|
|
||||||
char *b64_encode(const uint8_t *in, size_t len);
|
|
||||||
|
|
||||||
size_t b64_decoded_size(const char *in);
|
|
||||||
int b64_decode(const char *in, uint8_t *out, size_t outlen);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
Loading…
x
Reference in New Issue
Block a user