Merge pull request #14 from wildex999/Byaml

ksys/utils/byaml: First iteration of implementation.
This commit is contained in:
Léo Lam
2020-11-14 14:08:36 +01:00
committed by GitHub
25 changed files with 858 additions and 142 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
#include <prim/seadScopedLock.h>
#include "KingSystem/ActorSystem/actActorParamMgr.h"
#include "KingSystem/ActorSystem/actActorTemplate.h"
#include "KingSystem/Utils/Byaml.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
namespace ksys::act {
@@ -1,6 +1,6 @@
#include "KingSystem/ActorSystem/actActorTemplate.h"
#include "KingSystem/ActorSystem/actActorParamMgr.h"
#include "KingSystem/Utils/Byaml.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/SafeDelete.h"
namespace ksys::act {
+1 -1
View File
@@ -1,5 +1,5 @@
#include "KingSystem/Ecosystem/ecoLevelSensor.h"
#include "KingSystem/Utils/Byaml.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
namespace ksys::eco {
+1 -1
View File
@@ -12,7 +12,7 @@
#include "KingSystem/GameData/gdtTriggerParam.h"
#include "KingSystem/Resource/resHandle.h"
#include "KingSystem/System/KingEditor.h"
#include "KingSystem/Utils/Byaml.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/Types.h"
namespace sead {
+1 -1
View File
@@ -2,7 +2,7 @@
#include <prim/seadSafeString.h>
#include "KingSystem/Map/mapTypes.h"
#include "KingSystem/Utils/Byaml.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
namespace ksys::map {
@@ -1,7 +1,7 @@
#include "KingSystem/Resource/resResourceGameData.h"
#include <type_traits>
#include "KingSystem/GameData/gdtManager.h"
#include "KingSystem/Utils/Byaml.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/HeapUtil.h"
namespace ksys::res {
@@ -3,7 +3,7 @@
#include <codec/seadHashCRC32.h>
#include <prim/seadContainerIterator.h>
#include "KingSystem/GameData/gdtManager.h"
#include "KingSystem/Utils/Byaml.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
namespace ksys::res {
-1
View File
@@ -1 +0,0 @@
#include "KingSystem/Utils/Byaml.h"
+396
View File
@@ -0,0 +1,396 @@
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/Byaml/ByamlArrayIter.h"
#include "KingSystem/Utils/Byaml/ByamlData.h"
#include "KingSystem/Utils/Byaml/ByamlHashIter.h"
#include "KingSystem/Utils/Byaml/ByamlLocal.h"
#include "KingSystem/Utils/Byaml/ByamlStringTableIter.h"
#include "math/seadMathCalcCommon.h"
namespace al {
ByamlIter::ByamlIter() : mData(nullptr), mRootNode(nullptr) {}
ByamlIter::ByamlIter(const u8* data) {
mData = data;
mRootNode = nullptr;
if (mData) {
if (ByamlLocalUtil::verifiByaml(mData)) {
const ByamlHeader* header = reinterpret_cast<const ByamlHeader*>(mData);
u32 data_root_offset = header->getDataOffset();
if (data_root_offset) {
mRootNode = &mData[data_root_offset];
}
} else {
mData = nullptr;
mRootNode = nullptr;
}
}
}
ByamlIter::ByamlIter(const u8* data, const u8* root_node) : mData(data), mRootNode(root_node) {}
ByamlIter::ByamlIter(const ByamlIter& other) : mData(other.mData), mRootNode(other.mRootNode) {}
void ByamlIter::Set(const ByamlIter& other) {
if (this != &other) {
*this = other;
}
}
bool ByamlIter::isValid() const {
return mData != nullptr;
}
bool ByamlIter::isTypeHash() const {
const ByamlContainerHeader* node = reinterpret_cast<const ByamlContainerHeader*>(mRootNode);
return node && node->getType() == ByamlType::Hash;
}
bool ByamlIter::isTypeArray() const {
const ByamlContainerHeader* node = reinterpret_cast<const ByamlContainerHeader*>(mRootNode);
return node && node->getType() == ByamlType::Array;
}
bool ByamlIter::isTypeContainer() const {
return isTypeArray() || isTypeHash();
}
bool ByamlIter::isExistKey(const char* key) const {
if (!mRootNode) {
return false;
}
if (!isTypeHash()) {
return false;
}
const s32 index = getKeyIndex(key);
if (index < 0) {
return 0;
}
ByamlHashIter node_hash(mRootNode);
return node_hash.findPair(index);
}
s32 ByamlIter::getKeyIndex(const char* key) const {
const ByamlStringTableIter table = ByamlLocalUtil::getHashKeyTableIter(mData);
return table.findStringIndex(key);
}
s32 ByamlIter::getSize() const {
if (!mRootNode) {
return 0;
}
if (isTypeContainer()) {
return ByamlLocalUtil::getContainerSize(mRootNode);
}
return 0;
}
ByamlIter ByamlIter::getIterByIndex(s32 index) const {
ByamlData data;
if (!getByamlDataByIndex(&data, index)) {
return ByamlIter();
}
return getIterFromData(data);
}
ByamlIter ByamlIter::getIterByKey(const char* key) const {
ByamlData data;
if (!getByamlDataByKey(&data, key)) {
return ByamlIter();
}
return getIterFromData(data);
}
ByamlIter ByamlIter::getIterFromData(const ByamlData& data) const {
if (data.getType() == ByamlType::Hash || data.getType() == ByamlType::Array) {
return ByamlIter(mData, &mData[data.getValue()]);
}
if (data.getType() == ByamlType::Null) {
return ByamlIter(mData, nullptr);
}
return ByamlIter();
}
bool ByamlIter::getByamlDataByIndex(ByamlData* data, s32 index) const {
if (isTypeArray()) {
ByamlArrayIter array_node(mRootNode);
return array_node.getDataByIndex(data, index);
} else if (isTypeHash()) {
ByamlHashIter hash_node(mRootNode);
return hash_node.getDataByIndex(data, index);
}
return false;
}
bool ByamlIter::getByamlDataByKey(ByamlData* data, const char* key) const {
if (!isTypeHash()) {
return false;
}
auto* header = reinterpret_cast<const al::ByamlHeader*>(mData);
const s32 offset = header->getHashKeyTableOffset();
if (!offset) {
return false;
}
const ByamlStringTableIter table = ByamlStringTableIter(&mData[offset]);
ByamlHashIter hash_node(mRootNode);
const s32 size = hash_node.getSize();
if (size < 1) {
return false;
}
// Binary Search
const ByamlHashPair* pair;
s32 start = 0;
s32 end = size;
s32 index;
while (true) {
if (start >= end) {
return false;
}
index = (start + end) / 2;
pair = hash_node.getPairByIndex(index);
const char* str = table.getString(pair->getKey());
s32 result = std::strcmp(key, str);
if (result == 0)
break;
if (result > 0)
start = index + 1;
else if (result < 0)
end = index;
}
data->set(pair);
return true;
}
bool ByamlIter::getByamlDataAndKeyNameByIndex(ByamlData* data, const char** key, s32 index) const {
if (!isTypeHash()) {
return false;
}
const ByamlHashIter hash_iter(mRootNode);
const ByamlHashPair* pair = hash_iter.getPairByIndex(index);
if (!pair) {
return false;
}
if (data) {
data->set(pair);
}
ByamlStringTableIter table_iter = ByamlLocalUtil::getHashKeyTableIter(mData);
*key = table_iter.getString(pair->getKey());
return true;
}
bool ByamlIter::getKeyName(const char** key, s32 index) const {
if (!mRootNode) {
return false;
}
if (!isTypeHash()) {
return false;
}
ByamlHashIter hash_node(mRootNode);
const ByamlHashPair* pair = hash_node.getPairByIndex(index);
if (!pair) {
return false;
}
const ByamlStringTableIter hash_table = ByamlLocalUtil::getHashKeyTableIter(mData);
*key = hash_table.getString(pair->getKey());
return true;
}
bool ByamlIter::tryGetIterByIndex(ByamlIter* iter, s32 index) const {
iter->Set(getIterByIndex(index));
return iter->isValid();
}
bool ByamlIter::tryGetIterByKey(ByamlIter* iter, const char* key) const {
iter->Set(getIterByKey(key));
return iter->isValid();
}
bool ByamlIter::tryGetIterAndKeyNameByIndex(ByamlIter* iter, const char** key, s32 index) const {
ByamlData data;
if (!getByamlDataAndKeyNameByIndex(&data, key, index)) {
*key = nullptr;
return tryGetIterByIndex(iter, index);
}
iter->Set(getIterFromData(data));
return true;
}
bool ByamlIter::tryGetStringByIndex(const char** value, s32 index) const {
ByamlData data;
if (!getByamlDataByIndex(&data, index)) {
return false;
}
return tryConvertString(value, &data);
}
bool ByamlIter::tryGetStringByKey(const char** value, const char* key) const {
ByamlData data;
if (!getByamlDataByKey(&data, key)) {
return false;
}
return tryConvertString(value, &data);
}
bool ByamlIter::tryConvertString(const char** value, const ByamlData* data) const {
if (data->getType() != ByamlType::String) {
return false;
}
const auto string_table = ByamlLocalUtil::getStringTableIter(mData);
*value = string_table.getString(data->getValue());
return true;
}
bool ByamlIter::tryGetIntByIndex(s32* value, s32 index) const {
ByamlData data;
if (!getByamlDataByIndex(&data, index)) {
return false;
}
return tryConvertInt(value, &data);
}
bool ByamlIter::tryGetIntByKey(s32* value, const char* key) const {
ByamlData data;
if (!getByamlDataByKey(&data, key)) {
return false;
}
return tryConvertInt(value, &data);
}
bool ByamlIter::tryConvertInt(s32* value, const ByamlData* data) const {
if (data->getType() != ByamlType::Int) {
return false;
}
*value = data->getValue();
return true;
}
bool ByamlIter::tryGetUIntByIndex(u32* value, s32 index) const {
ByamlData data;
if (!getByamlDataByIndex(&data, index)) {
return false;
}
return tryConvertUInt(value, &data);
}
bool ByamlIter::tryGetUIntByKey(u32* value, const char* key) const {
ByamlData data;
if (!getByamlDataByKey(&data, key)) {
return false;
}
return tryConvertUInt(value, &data);
}
bool ByamlIter::tryConvertUInt(u32* value, const ByamlData* data) const {
if (data->getType() == ByamlType::Int) {
s32 signed_value = data->getValue<s32>();
if (signed_value < 0) {
*value = 0;
return false;
} else {
*value = signed_value;
return true;
}
} else if (data->getType() == ByamlType::UInt) {
*value = data->getValue();
return true;
}
return false;
}
bool ByamlIter::tryGetFloatByIndex(f32* value, s32 index) const {
ByamlData data;
if (!getByamlDataByIndex(&data, index)) {
return false;
}
return tryConvertFloat(value, &data);
}
bool ByamlIter::tryGetFloatByKey(f32* value, const char* key) const {
ByamlData data;
if (!getByamlDataByKey(&data, key)) {
return false;
}
return tryConvertFloat(value, &data);
}
bool ByamlIter::tryConvertFloat(f32* value, const ByamlData* data) const {
if (data->getType() != ByamlType::Float) {
return false;
}
*value = data->getValue<f32>();
return true;
}
bool ByamlIter::tryGetBoolByIndex(bool* value, s32 index) const {
ByamlData data;
if (!getByamlDataByIndex(&data, index)) {
return false;
}
return tryConvertBool(value, &data);
}
bool ByamlIter::tryGetBoolByKey(bool* value, const char* key) const {
ByamlData data;
if (!getByamlDataByKey(&data, key)) {
return false;
}
return tryConvertBool(value, &data);
}
bool ByamlIter::tryConvertBool(bool* value, const ByamlData* data) const {
if (data->getType() != ByamlType::Bool) {
return false;
}
*value = data->getValue() != 0;
return true;
}
bool ByamlIter::isEqualData(const ByamlIter& other) const {
if (!mData || !other.mData) {
return false;
}
return mData == other.mData && mRootNode == other.mRootNode;
}
} // namespace al
@@ -4,12 +4,14 @@
#include <basis/seadTypes.h>
#include <math/seadVector.h>
#include <prim/seadEndian.h>
#include <prim/seadSizedEnum.h>
#include "KingSystem/Utils/Types.h"
namespace al {
struct ByamlData;
struct ByamlHashPair;
enum class ByamlType {
Invalid = 0,
@@ -39,7 +41,8 @@ public:
ByamlIter(const u8* data, const u8* root_node);
ByamlIter(const ByamlIter& other);
ByamlIter& operator=(const ByamlIter& rhs);
ByamlIter& operator=(const ByamlIter& rhs) = default;
void Set(const ByamlIter& other);
bool isValid() const;
bool isTypeHash() const;
@@ -51,11 +54,13 @@ public:
s32 getSize() const;
void getByamlDataByIndex(ByamlData* data, s32 index) const;
bool getByamlDataByKey(ByamlData* data, const char* key) const;
bool getByamlDataByKeyIndex(ByamlData* data, s32 index) const;
ByamlIter getIterByIndex(s32 index) const;
ByamlIter getIterByKey(const char* key) const;
ByamlIter getIterFromData(const ByamlData& data) const;
bool getByamlDataByIndex(ByamlData* data, s32 index) const;
bool getByamlDataByKey(ByamlData* data, const char* key) const;
bool getByamlDataAndKeyNameByIndex(ByamlData* data, const char** key, s32 index) const;
bool getKeyName(const char** key, s32 index) const;
bool tryGetIterByIndex(ByamlIter* iter, s32 index) const;
@@ -68,6 +73,7 @@ public:
bool tryGetIntByIndex(s32* value, s32 index) const;
bool tryGetIntByKey(s32* value, const char* key) const;
bool tryConvertInt(s32* value, const ByamlData* data) const;
bool tryGetUIntByIndex(u32* value, s32 index) const;
bool tryGetUIntByKey(u32* value, const char* key) const;
@@ -75,9 +81,11 @@ public:
bool tryGetFloatByIndex(f32* value, s32 index) const;
bool tryGetFloatByKey(f32* value, const char* key) const;
bool tryConvertFloat(f32* value, const ByamlData* data) const;
bool tryGetBoolByIndex(bool* value, s32 index) const;
bool tryGetBoolByKey(bool* value, const char* key) const;
bool tryConvertBool(bool* value, const ByamlData* data) const;
bool isEqualData(const ByamlIter& other) const;
@@ -86,50 +94,13 @@ private:
const u8* mRootNode = nullptr;
};
class ByamlStringTableIter {
public:
explicit ByamlStringTableIter(const u8* data) : mData(data) {}
const char* getString(s32 index) const;
s32 findStringIndex(const char* string) const;
private:
const u8* mData;
};
class ByamlArrayIter {
public:
explicit ByamlArrayIter(const u8* data);
const u8* getDataTable() const;
bool getDataByIndex(ByamlData* data, s32 index);
private:
const u8* mData;
};
class ByamlHashIter {
public:
explicit ByamlHashIter(const u8* data);
s32 getSize() const;
const u8* getPairTable() const;
bool getDataByIndex(ByamlData* data, s32 index) const;
bool getDataByKey(ByamlData* data, s32 key_index) const;
const u8* findPair(s32 key_index) const;
const u8* getPairByIndex(s32 index) const;
private:
const u8* mData;
};
struct ByamlHeader {
u16 getTag() const;
bool isInvertHeader() const;
u16 getVersion() const;
u16 getHashKeyTableOffset() const;
u16 getStringTableOffset() const;
u16 getDataOffset() const;
u16 getVersion() const { return version; };
u32 getHashKeyTableOffset() const { return hash_key_table_offset; };
u32 getStringTableOffset() const { return string_table_offset; };
u32 getDataOffset() const { return data_offset; };
u16 magic;
u16 version;
@@ -140,32 +111,15 @@ struct ByamlHeader {
KSYS_CHECK_SIZE_NX150(ByamlHeader, 0x10);
struct ByamlContainerHeader {
ByamlType getType() const;
u32 getCount(bool byteswap) const;
ByamlType getType() const {
// Type is only the first byte
return ByamlType(*reinterpret_cast<const u8*>(&type_and_size));
}
u32 getCount() const { return type_and_size >> 8; };
u32 type_and_size;
};
struct ByamlHashPair {
u32 getKey(bool byteswap) const;
ByamlType getType() const;
u32 getValue(bool byteswap) const;
u32 name_and_type;
u32 value;
};
struct ByamlData {
u32 getValue() const { return value; }
ByamlType getType() const { return type; }
void set(const ByamlHashPair* pair, bool byteswap);
void set(u8, u32, bool byteswap);
u32 value = 0;
sead::SizedEnum<ByamlType, u8> type = ByamlType::Invalid;
};
bool tryGetByamlS32(s32* value, const ByamlIter& iter, const char* key);
bool tryGetByamlU32(u32* value, const ByamlIter& iter, const char* key);
bool tryGetByamlF32(f32* value, const ByamlIter& iter, const char* key);
@@ -0,0 +1,29 @@
#include "KingSystem/Utils/Byaml/ByamlArrayIter.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/Byaml/ByamlData.h"
#include "KingSystem/Utils/Byaml/ByamlLocal.h"
namespace al {
ByamlArrayIter::ByamlArrayIter(const u8* data) {
mData = data;
}
const u32* ByamlArrayIter::getDataTable() const {
return reinterpret_cast<const u32*>(&mData[TypeTableOffset + getDataOffset()]);
}
bool ByamlArrayIter::getDataByIndex(ByamlData* data, s32 index) {
if (index < 0) {
return false;
}
if (index >= ByamlLocalUtil::getContainerSize(mData)) {
return false;
}
data->setType(ByamlType(mData[TypeTableOffset + index]));
data->setValue(getDataTable()[index]);
return true;
}
} // namespace al
@@ -0,0 +1,28 @@
#pragma once
#include <basis/seadTypes.h>
#include <math/seadMathCalcCommon.h>
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/Byaml/ByamlLocal.h"
namespace al {
class ByamlArrayIter {
public:
explicit ByamlArrayIter(const u8* data);
const u32* getDataTable() const;
bool getDataByIndex(ByamlData* data, s32 index);
private:
s32 getDataOffset() const {
const s32 size = ByamlLocalUtil::getContainerSize(mData);
return sead::Mathu::roundUp(size, 4);
}
static constexpr s32 TypeTableOffset = 4;
const u8* mData;
};
} // namespace al
+7
View File
@@ -0,0 +1,7 @@
#include "KingSystem/Utils/Byaml/ByamlData.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
namespace al {
ByamlData::ByamlData() = default;
} // namespace al
+45
View File
@@ -0,0 +1,45 @@
#pragma once
#include <basis/seadTypes.h>
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/Byaml/ByamlHashIter.h"
namespace al {
struct ByamlData {
ByamlData();
template <typename T = u32>
T getValue() const {
return *reinterpret_cast<const T*>(&mValue);
}
ByamlType getType() const { return mType; }
void set(const ByamlHashPair* pair) {
mType = pair->getType();
mValue = pair->getValue();
}
template <typename T = u32>
void set(const ByamlType& type, const T& value) {
mType = type;
mValue = *reinterpret_cast<const u32*>(&value);
}
void setType(const ByamlType& type) { mType = type; }
template <typename T = u32>
void setValue(const T& value) {
mValue = *reinterpret_cast<const u32*>(&value);
}
void clear() {
mValue = 0;
mType = ByamlType::Invalid;
}
private:
u32 mValue = 0;
sead::SizedEnum<ByamlType, u8> mType = ByamlType::Invalid;
};
} // namespace al
@@ -0,0 +1,110 @@
#include "KingSystem/Utils/Byaml/ByamlHashIter.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/Byaml/ByamlData.h"
#include "KingSystem/Utils/Byaml/ByamlLocal.h"
namespace al {
ByamlHashIter::ByamlHashIter(const u8* data) {
mData = data;
}
s32 ByamlHashIter::getSize() const {
if (!mData) {
return 0;
}
return ByamlLocalUtil::getContainerSize(mData);
}
const ByamlHashPair* ByamlHashIter::getPairTable() const {
if (!mData) {
return nullptr;
}
return reinterpret_cast<const ByamlHashPair*>(&mData[mTableOffset]);
}
bool ByamlHashIter::getDataByIndex(ByamlData* data, s32 index) const {
if (!mData) {
return false;
}
if (ByamlLocalUtil::getContainerSize(mData) == 0) {
return false;
}
const ByamlHashPair* pair_table = getPairTable();
const ByamlHashPair* pair = &pair_table[index];
if (!pair) // This seems wrong, this can never be null?
{
return false;
}
data->set(pair);
return true;
}
bool ByamlHashIter::getDataByKey(ByamlData* data, s32 key_index) const {
if (getSize() == 0) {
return false;
}
const ByamlHashPair* pair = findPair(key_index);
if (!pair) {
return false;
}
data->set(pair);
return true;
}
const ByamlHashPair* ByamlHashIter::findPair(s32 key_index) const {
const ByamlHashPair* pair_table = getPairTable();
if (!pair_table) {
return nullptr;
}
if (ByamlLocalUtil::getContainerSize(mData) == 0) {
return nullptr;
}
// Binary Search
s32 start = 0;
s32 end = getSize();
s32 index;
const ByamlHashPair* pair;
while (true) {
if (start >= end) {
return nullptr;
}
index = (start + end) / 2;
pair = &pair_table[index];
s32 result = key_index - pair->getKey();
if (result == 0)
break;
if (result > 0)
start = index + 1;
else if (result < 0)
end = index;
}
return pair;
}
const ByamlHashPair* ByamlHashIter::getPairByIndex(s32 index) const {
if (index < 0) {
return nullptr;
}
if (getSize() <= index) {
return nullptr;
}
const ByamlHashPair* pair_table = getPairTable();
return pair_table + index;
}
} // namespace al
@@ -0,0 +1,38 @@
#pragma once
#include <basis/seadTypes.h>
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "prim/seadEndian.h"
namespace al {
struct ByamlData;
struct ByamlHashPair;
class ByamlHashIter {
public:
explicit ByamlHashIter(const u8* data);
s32 getSize() const;
const ByamlHashPair* getPairTable() const;
bool getDataByIndex(ByamlData* data, s32 index) const;
bool getDataByKey(ByamlData* data, s32 key_index) const;
const ByamlHashPair* findPair(s32 key_index) const;
const ByamlHashPair* getPairByIndex(s32 index) const;
private:
const u8* mData;
static constexpr s32 mTableOffset = 4;
};
struct ByamlHashPair {
u32 getKey() const { return mKeyAndType & 0xFFFFFF; }
ByamlType getType() const { return ByamlType(mKeyAndType >> 24); }
u32 getValue() const { return mValue; }
u32 mKeyAndType;
u32 mValue;
};
} // namespace al
@@ -0,0 +1,3 @@
#include "KingSystem/Utils/Byaml/ByamlLocal.h"
namespace al::ByamlLocalUtil {} // namespace al::ByamlLocalUtil
+38
View File
@@ -0,0 +1,38 @@
#pragma once
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/Byaml/ByamlStringTableIter.h"
#include <basis/seadTypes.h>
namespace al::ByamlLocalUtil {
inline ByamlStringTableIter getHashKeyTableIter(const u8* data) {
auto* header = reinterpret_cast<const al::ByamlHeader*>(data);
const u8* ptr = &data[header->getHashKeyTableOffset()];
return ByamlStringTableIter(ptr);
}
inline ByamlStringTableIter getStringTableIter(const u8* data) {
auto* header = reinterpret_cast<const al::ByamlHeader*>(data);
const u8* ptr = &data[header->getStringTableOffset()];
return ByamlStringTableIter(ptr);
}
inline s32 getContainerSize(const u8* data) {
auto* node = reinterpret_cast<const al::ByamlContainerHeader*>(data);
return node->getCount();
}
inline al::ByamlType getType(const u8* data) {
auto* node = reinterpret_cast<const al::ByamlContainerHeader*>(data);
return node->getType();
}
const char* getDataTypeString(s32 type);
bool verifiByaml(const u8* data);
bool verifiByamlHeader(const u8* data);
bool verifiByamlStringTable(const u8* data);
} // namespace al::ByamlLocalUtil
@@ -0,0 +1,50 @@
#include "KingSystem/Utils/Byaml/ByamlStringTableIter.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
#include "KingSystem/Utils/Byaml/ByamlLocal.h"
namespace al {
ByamlStringTableIter::ByamlStringTableIter(const u8* data) {
mData = data;
}
ByamlStringTableIter::ByamlStringTableIter(const ByamlStringTableIter& other) {
mData = other.mData;
}
const char* ByamlStringTableIter::getString(s32 index) const {
const u32* string_offset_array = getStringOffsetArray();
return reinterpret_cast<const char*>(&mData[string_offset_array[index]]);
}
s32 ByamlStringTableIter::findStringIndex(const char* string) const {
const u32* string_offset_array = getStringOffsetArray();
u32 table_size = ByamlLocalUtil::getContainerSize(mData);
if (table_size == 0) {
return -1;
}
// Binary Search
s32 start = 0;
s32 end = table_size;
s32 index;
while (true) {
if (start >= end) {
return -1;
}
index = (start + end) / 2;
const char* str = reinterpret_cast<const char*>(&mData[string_offset_array[index]]);
s32 result = std::strcmp(string, str);
if (result == 0)
break;
if (result > 0)
start = index + 1;
else if (result < 0)
end = index;
}
return index;
}
} // namespace al
@@ -0,0 +1,27 @@
#pragma once
#include <basis/seadTypes.h>
namespace al {
class ByamlStringTableIter {
public:
explicit ByamlStringTableIter(const u8* data);
ByamlStringTableIter(const ByamlStringTableIter& other);
const char* getString(s32 index) const;
s32 findStringIndex(const char* string) const;
bool isValid() const { return mData != nullptr; }
const u32* getStringOffsetArray() const {
return reinterpret_cast<const u32*>(&mData[TableOffset]);
}
private:
const u8* mData;
static constexpr u32 TableOffset = 4u;
};
} // namespace al
@@ -1,4 +1,4 @@
#include "KingSystem/Utils/Byaml.h"
#include "KingSystem/Utils/Byaml/Byaml.h"
namespace al {
-1
View File
@@ -1 +0,0 @@
#include "KingSystem/Utils/ByamlLocal.h"
-16
View File
@@ -1,16 +0,0 @@
#pragma once
#include <basis/seadTypes.h>
namespace alByamlLocalUtil {
const char* getDataTypeString(s32 type);
const u8* getHashKeyTable(const u8* data);
const u8* getStringTable(const u8* data);
bool verifiByaml(const u8* data);
bool verifiByamlHeader(const u8* data);
bool verifiByamlStringTable(const u8* data);
} // namespace alByamlLocalUtil
+14 -5
View File
@@ -21,11 +21,20 @@ target_sources(uking PRIVATE
Thread/TaskThread.cpp
Thread/TaskThread.h
Byaml.cpp
Byaml.h
ByamlLocal.cpp
ByamlLocal.h
ByamlUtil.cpp
Byaml/Byaml.cpp
Byaml/Byaml.h
Byaml/ByamlArrayIter.cpp
Byaml/ByamlArrayIter.h
Byaml/ByamlData.cpp
Byaml/ByamlData.h
Byaml/ByamlStringTableIter.cpp
Byaml/ByamlStringTableIter.h
Byaml/ByamlHashIter.cpp
Byaml/ByamlHashIter.h
Byaml/ByamlLocal.cpp
Byaml/ByamlLocal.h
Byaml/ByamlUtil.cpp
Debug.h
FixedString.h
HashUtil.h