AuroraRuntime/Source/Registry/Registry.cpp
2021-06-30 17:35:02 +01:00

160 lines
3.9 KiB
C++

/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Registry.cpp
Date: 2021-6-13
Author: Reece
***/
#include <RuntimeInternal.hpp>
#include "Registry.hpp"
#include <nlohmann/json.hpp>
using json = nlohmann::json;
namespace Aurora::Registry
{
class FSRegistry : public IRegistry
{
public:
json document;
AuString path;
bool Init(const AuString &path);
bool KeyExists(const AuString &key, RegistryType &type);
bool GetOrCreateKey(const AuString &key, const RegistryValue &ref, RegistryValue &value);
bool GetKey(const AuString &key, RegistryValue &value);
bool SetKey(const AuString &key, const RegistryValue &value);
bool Save();
};
bool FSRegistry::Init(const AuString &path)
{
try
{
this->path = path;
AuString file;
if (!IO::FS::ReadString(path, file))
{
return IO::FS::WriteString(path, "{}");
}
document = json::parse(file);
}
catch (...)
{
return false;
}
return true;
}
bool FSRegistry::KeyExists(const AuString &key, RegistryType &type)
{
auto itrObject = document.find(key);
if (itrObject == document.end()) return false;
auto itrType = itrObject->find("type");
if (itrType == itrObject->end()) return false;
auto itrValue = itrObject->find("value");
if (itrValue == itrObject->end()) return false;
return true;
}
bool FSRegistry::GetOrCreateKey(const AuString &key, const RegistryValue &ref, RegistryValue &value)
{
if (GetKey(key, value))
{
return true;
}
return SetKey(key, ref);
}
bool FSRegistry::GetKey(const AuString &key, RegistryValue &value)
{
auto itrObject = document.find(key);
if (itrObject == document.end())
{
return false;
}
auto itrType = itrObject->find("type");
auto itrValue = itrObject->find("value");
if ((itrType == itrObject->end()) ||
(itrValue == itrObject->end()))
{
return false;
}
if (!itrValue->is_string())
{
return false;
}
if (!itrType->is_number_integer())
{
return false;
}
Parse::ParsableTag type = *itrType;
AuString strValue = *itrValue;
Parse::ParseValueEx parsedValue;
if (!Parse::ConsumeToken(type, strValue , parsedValue))
{
return false;
}
value.type = static_cast<Data::DataType>(type);
value.value = parsedValue;
return true;
}
bool FSRegistry::SetKey(const AuString &key, const RegistryValue &value)
{
json object {};
object["type"] = value.type;
AuString stringified;
Parse::SerializeToken(static_cast<Parse::ParsableTag>(value.type), value.value, stringified);
object["value"] = stringified;
document[key] = object;
return Save();
}
bool FSRegistry::Save()
{
if (!IO::FS::WriteString(path, document.dump(4)))
{
SysPushErrorIO("Couldn't write registry to: {}", path);
return false;
}
return true;
}
AUKN_SYM IRegistry *RegistryNew(ERegistrySource source, const AuString &name)
{
SysAssert(source == ERegistrySource::eFS, "Unknown registry type");
auto registry = _new FSRegistry();
if (!registry)
{
return nullptr;
}
if (!registry->Init(name))
{
delete registry;
return nullptr;
}
return registry;
}
AUKN_SYM void RegistryRelease(IRegistry *registry)
{
SafeDelete<FSRegistry *>(registry);
}
}