WiiUPluginLoaderBackend/source/utils/StorageUtils.cpp

147 lines
5.0 KiB
C++
Raw Normal View History

#include "StorageUtils.h"
2023-08-16 10:08:44 +02:00
#include "NotificationsUtils.h"
2023-08-14 11:32:16 +02:00
#include "StringTools.h"
#include "fs/CFile.hpp"
#include "fs/FSUtils.h"
#include "utils.h"
2022-02-04 16:25:44 +01:00
#include "utils/json.hpp"
#include "utils/logger.h"
2023-08-16 10:08:44 +02:00
#include <notifications/notifications.h>
2021-09-25 14:26:18 +02:00
static void processJson(wups_storage_item_t *items, nlohmann::json json) {
if (items == nullptr) {
return;
}
2022-02-04 16:25:44 +01:00
items->data = (wups_storage_item_t *) malloc(json.size() * sizeof(wups_storage_item_t));
items->data_size = json.size();
uint32_t index = 0;
for (auto it = json.begin(); it != json.end(); ++it) {
2021-09-25 14:26:18 +02:00
wups_storage_item_t *item = &((wups_storage_item_t *) items->data)[index];
2022-02-04 16:25:44 +01:00
item->type = WUPS_STORAGE_TYPE_INVALID;
item->deleted = false;
2022-02-04 16:25:44 +01:00
item->data = nullptr;
item->key = nullptr;
2021-09-25 14:26:18 +02:00
item->key = (char *) malloc(it.key().size() + 1);
strcpy(item->key, it.key().c_str());
if (it.value().is_string()) {
2022-02-04 16:25:44 +01:00
item->type = WUPS_STORAGE_TYPE_STRING;
uint32_t size = it.value().get<std::string>().size() + 1;
item->data = malloc(size);
item->data_size = size;
2021-09-25 14:26:18 +02:00
strcpy((char *) item->data, it.value().get<std::string>().c_str());
} else if (it.value().is_number_integer()) {
2022-02-04 16:25:44 +01:00
item->type = WUPS_STORAGE_TYPE_INT;
item->data = malloc(sizeof(int32_t));
item->data_size = sizeof(int32_t);
2021-09-25 14:26:18 +02:00
*(int32_t *) item->data = it.value().get<int32_t>();
} else if (it.value().is_object()) {
if (it.value().size() > 0) {
item->type = WUPS_STORAGE_TYPE_ITEM;
processJson(item, it.value());
}
} else {
2022-04-22 22:55:53 +02:00
DEBUG_FUNCTION_LINE_ERR("Unknown type %s for value %s", it.value().type_name(), it.key().c_str());
}
index++;
}
}
2022-08-26 21:55:09 +02:00
WUPSStorageError StorageUtils::OpenStorage(const char *plugin_id, wups_storage_item_t *items) {
if (!plugin_id || !items) {
return WUPS_STORAGE_ERROR_INVALID_BACKEND_PARAMS;
}
std::string filePath = getPluginPath() + "/config/" + plugin_id + ".json";
nlohmann::json j;
CFile file(filePath, CFile::ReadOnly);
if (file.isOpen() && file.size() > 0) {
auto *json_data = (uint8_t *) memalign(0x40, ROUNDUP(file.size() + 1, 0x40));
json_data[file.size()] = '\0';
file.read(json_data, file.size());
file.close();
j = nlohmann::json::parse(json_data, nullptr, false);
2022-08-26 21:58:58 +02:00
free(json_data);
if (j == nlohmann::detail::value_t::discarded || j.empty() || !j.is_object()) {
2023-08-14 11:32:16 +02:00
std::string errorMessage = string_format("Corrupted plugin storage detected: \"%s\". You have to reconfigure the plugin.", plugin_id);
DEBUG_FUNCTION_LINE_ERR("%s", errorMessage.c_str());
remove(filePath.c_str());
2023-08-16 10:08:44 +02:00
DisplayErrorNotificationMessage(errorMessage, 10.0f);
2023-08-14 11:32:16 +02:00
return WUPS_STORAGE_ERROR_SUCCESS;
}
} else { // empty or no config exists yet
return WUPS_STORAGE_ERROR_SUCCESS;
}
processJson(items, j["storageitems"]);
return WUPS_STORAGE_ERROR_SUCCESS;
}
2021-09-25 14:26:18 +02:00
static nlohmann::json processItems(wups_storage_item_t *items) {
nlohmann::json json;
if (!items) {
return json;
}
for (uint32_t i = 0; i < items->data_size; i++) {
2021-09-25 14:26:18 +02:00
wups_storage_item_t *item = &((wups_storage_item_t *) items->data)[i];
if (item->deleted || item->type == WUPS_STORAGE_TYPE_INVALID || !item->data || !item->key) {
continue;
}
if (item->type == WUPS_STORAGE_TYPE_STRING) {
2021-09-25 14:26:18 +02:00
json[item->key] = (const char *) item->data;
} else if (item->type == WUPS_STORAGE_TYPE_INT) {
2021-09-25 14:26:18 +02:00
json[item->key] = *(int32_t *) item->data;
} else if (item->type == WUPS_STORAGE_TYPE_ITEM) {
json[item->key] = processItems(item);
} else {
2022-04-22 22:55:53 +02:00
DEBUG_FUNCTION_LINE_ERR("Saving type %d not implemented", item->type);
}
}
return json;
}
2022-08-26 21:55:09 +02:00
WUPSStorageError StorageUtils::CloseStorage(const char *plugin_id, wups_storage_item_t *items) {
if (!plugin_id || !items) {
return WUPS_STORAGE_ERROR_INVALID_BACKEND_PARAMS;
}
std::string folderPath = getPluginPath() + "/config/";
2022-02-04 16:25:44 +01:00
std::string filePath = folderPath + plugin_id + ".json";
FSUtils::CreateSubfolder(folderPath);
CFile file(filePath, CFile::WriteOnly);
if (!file.isOpen()) {
2022-04-22 22:55:53 +02:00
DEBUG_FUNCTION_LINE_ERR("Cannot create file %s", filePath.c_str());
return WUPS_STORAGE_ERROR_IO;
};
nlohmann::json j;
j["storageitems"] = processItems(items);
2023-08-14 11:32:16 +02:00
std::string jsonString = j.dump(4, ' ', false, nlohmann::json::error_handler_t::ignore);
2022-08-26 21:58:58 +02:00
auto writeResult = file.write((const uint8_t *) jsonString.c_str(), jsonString.size());
file.close();
2022-08-26 21:58:58 +02:00
if (writeResult != (int32_t) jsonString.size()) {
return WUPS_STORAGE_ERROR_IO;
}
return WUPS_STORAGE_ERROR_SUCCESS;
}