Created
February 9, 2020 15:27
-
-
Save SirKane/84f4d8bf1392a0a4b720087e414b4143 to your computer and use it in GitHub Desktop.
Generation 1 binary varmap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum class eSerializedVariantType_G1 : uint8_t | |
{ | |
Empty = 0, | |
VarMap, | |
BoolTrue, | |
BoolFalse, | |
Int32, | |
Int64, | |
Float, | |
Vec4f, | |
Vec4i, | |
Vec3f, | |
Vec3i, | |
Vec2f, | |
Vec2i, | |
String, | |
File, | |
Uid, | |
UidRef, | |
}; | |
static bool LoadValue(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value); | |
static bool Load_Empty(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
value = CVariant(); | |
return true; | |
} | |
static bool Load_VarMap(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
uint32_t i; | |
uint32_t intKeyedCount, variantKeyedCount; | |
CVarMapHandle hVarMap; | |
if (!reader.ReadVarU32_G1(intKeyedCount)) | |
{ | |
return false; | |
} | |
if (!reader.ReadVarU32_G1(variantKeyedCount)) | |
{ | |
return false; | |
} | |
if (intKeyedCount > 0x10000000 || | |
variantKeyedCount > 0x10000000) | |
{ | |
return false; | |
} | |
for (i = 0; i < intKeyedCount; i++) | |
{ | |
CVariant value; | |
if (!LoadValue(reader, strings, value)) | |
{ | |
return false; | |
} | |
hVarMap.Insert((int32_t)i, value); | |
} | |
for (i = 0; i < variantKeyedCount; i++) | |
{ | |
CVariant key, value; | |
if (!LoadValue(reader, strings, key)) | |
{ | |
return false; | |
} | |
if (!LoadValue(reader, strings, value)) | |
{ | |
return false; | |
} | |
hVarMap.Insert(key, value); | |
} | |
value = hVarMap; | |
return true; | |
} | |
static bool Load_Int32(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
int32_t readValue; | |
if (!reader.ReadVarS32_G1(readValue)) | |
{ | |
return false; | |
} | |
value = readValue; | |
return true; | |
} | |
static bool Load_Int64(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
int64_t readValue; | |
if (!reader.ReadS64(readValue)) | |
{ | |
return false; | |
} | |
value = readValue; | |
return true; | |
} | |
static bool Load_Float(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
float readValue; | |
if (!reader.ReadFloat(readValue)) | |
{ | |
return false; | |
} | |
value = readValue; | |
return true; | |
} | |
static bool Load_BoolTrue(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
value = true; | |
return true; | |
} | |
static bool Load_BoolFalse(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
value = false; | |
return true; | |
} | |
static bool Load_Vec4f(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
CVec4f readValue; | |
if (!reader.ReadFloat(readValue.x)) | |
{ | |
return false; | |
} | |
if (!reader.ReadFloat(readValue.y)) | |
{ | |
return false; | |
} | |
if (!reader.ReadFloat(readValue.z)) | |
{ | |
return false; | |
} | |
if (!reader.ReadFloat(readValue.w)) | |
{ | |
return false; | |
} | |
value = readValue; | |
return true; | |
} | |
static bool Load_Vec4i(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
CVec4i readValue; | |
if (!reader.ReadVarS32_G1(readValue.x)) | |
{ | |
return false; | |
} | |
if (!reader.ReadVarS32_G1(readValue.y)) | |
{ | |
return false; | |
} | |
if (!reader.ReadVarS32_G1(readValue.z)) | |
{ | |
return false; | |
} | |
if (!reader.ReadVarS32_G1(readValue.w)) | |
{ | |
return false; | |
} | |
value = readValue; | |
return true; | |
} | |
static bool Load_Vec3f(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
CVec3f readValue; | |
if (!reader.ReadFloat(readValue.x)) | |
{ | |
return false; | |
} | |
if (!reader.ReadFloat(readValue.y)) | |
{ | |
return false; | |
} | |
if (!reader.ReadFloat(readValue.z)) | |
{ | |
return false; | |
} | |
value = readValue; | |
return true; | |
} | |
static bool Load_Vec3i(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
CVec3i readValue; | |
if (!reader.ReadVarS32_G1(readValue.x)) | |
{ | |
return false; | |
} | |
if (!reader.ReadVarS32_G1(readValue.y)) | |
{ | |
return false; | |
} | |
if (!reader.ReadVarS32_G1(readValue.z)) | |
{ | |
return false; | |
} | |
value = readValue; | |
return true; | |
} | |
static bool Load_Vec2f(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
CVec2f readValue; | |
if (!reader.ReadFloat(readValue.x)) | |
{ | |
return false; | |
} | |
if (!reader.ReadFloat(readValue.y)) | |
{ | |
return false; | |
} | |
value = readValue; | |
return true; | |
} | |
static bool Load_Vec2i(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
CVec2i readValue; | |
if (!reader.ReadVarS32_G1(readValue.x)) | |
{ | |
return false; | |
} | |
if (!reader.ReadVarS32_G1(readValue.y)) | |
{ | |
return false; | |
} | |
value = readValue; | |
return true; | |
} | |
static bool Load_String(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
uint32_t stringIndex; | |
if (!reader.ReadVarU32_G1(stringIndex)) | |
{ | |
return false; | |
} | |
if (stringIndex >= strings.Size()) | |
{ | |
return false; | |
} | |
value = CVarString(strings[stringIndex]()); | |
return true; | |
} | |
static bool Load_File(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
uint32_t stringIndex; | |
if (!reader.ReadVarU32_G1(stringIndex)) | |
{ | |
return false; | |
} | |
if (stringIndex >= strings.Size()) | |
{ | |
return false; | |
} | |
value = CVarFile(strings[stringIndex]()); | |
return true; | |
} | |
static bool Load_UID(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
CUid uid; | |
if (!reader.ReadU64(uid.Uid.LowValue)) | |
{ | |
return false; | |
} | |
if (!reader.ReadU64(uid.Uid.HighValue)) | |
{ | |
return false; | |
} | |
value = uid; | |
return true; | |
} | |
static bool Load_UIDRef(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
CUidRef uid; | |
if (!reader.ReadU64(uid.Uid.LowValue)) | |
{ | |
return false; | |
} | |
if (!reader.ReadU64(uid.Uid.HighValue)) | |
{ | |
return false; | |
} | |
value = uid; | |
return true; | |
} | |
static bool LoadValue(CBinaryVarMapReader &reader, | |
TDynArray<CStringA> &strings, CVariant &value) | |
{ | |
uint8_t valueType; | |
if (!reader.ReadU8(valueType)) | |
{ | |
return false; | |
} | |
eSerializedVariantType_G1 type = (eSerializedVariantType_G1)valueType; | |
switch (type) | |
{ | |
case eSerializedVariantType_G1::Empty: | |
{ | |
return Load_Empty(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::VarMap: | |
{ | |
return Load_VarMap(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::BoolTrue: | |
{ | |
return Load_BoolTrue(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::BoolFalse: | |
{ | |
return Load_BoolFalse(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::Int32: | |
{ | |
return Load_Int32(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::Int64: | |
{ | |
return Load_Int64(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::Float: | |
{ | |
return Load_Float(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::Vec4f: | |
{ | |
return Load_Vec4f(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::Vec4i: | |
{ | |
return Load_Vec4i(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::Vec3f: | |
{ | |
return Load_Vec3f(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::Vec3i: | |
{ | |
return Load_Vec3i(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::Vec2f: | |
{ | |
return Load_Vec2f(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::Vec2i: | |
{ | |
return Load_Vec2i(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::String: | |
{ | |
return Load_String(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::File: | |
{ | |
return Load_File(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::Uid: | |
{ | |
return Load_UID(reader, strings, value); | |
} | |
case eSerializedVariantType_G1::UidRef: | |
{ | |
return Load_UIDRef(reader, strings, value); | |
} | |
default: | |
{ | |
return false; | |
} | |
} | |
} | |
static bool LoadValueFromReader(CBinaryVarMapReader &reader, CVariant &outValue) | |
{ | |
uint32_t stringCount, i; | |
TDynArray<CStringA> strings; | |
const uint32_t expectedMagic = | |
((uint32_t)0xFF << 0) | | |
((uint32_t)'B' << 8) | | |
((uint32_t)'V' << 16) | | |
((uint32_t)'M' << 24); | |
uint32_t magic; | |
if (!reader.ReadU32(magic)) | |
{ | |
return false; | |
} | |
if (magic != expectedMagic) | |
{ | |
return false; | |
} | |
if (!reader.ReadVarU32_G1(stringCount)) | |
{ | |
return false; | |
} | |
strings.Resize(stringCount); | |
for (i = 0; i < stringCount; i++) | |
{ | |
uint32_t stringLength; | |
if (!reader.ReadVarU32_G1(stringLength)) | |
{ | |
return false; | |
} | |
CStringA &string = strings[i]; | |
string.Resize(stringLength); | |
if (!reader.ReadRaw(string.GetBuffer(), stringLength)) | |
{ | |
return false; | |
} | |
} | |
outValue = CVariant(); | |
return LoadValue(reader, strings, outValue); | |
} | |
bool LoadVariant_G1(const void* pData, size_t length, CVariant &outVariant) | |
{ | |
if (pData == nullptr || | |
length < 4) | |
{ | |
return false; | |
} | |
CBinaryVarMapReader reader(pData, length); | |
return LoadValueFromReader(reader, outVariant); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bool CBinaryVarMapReader::ReadVarU32_G1(uint32_t &value) | |
{ | |
byte_t length; | |
if (SizeLeft() < 1) | |
{ | |
return false; | |
} | |
value = *(m_pCurrent++); | |
length = value & 0xC0; | |
if (length == 0xC0) | |
{ | |
if (SizeLeft() < sizeof(uint32_t)) | |
{ | |
return false; | |
} | |
value = | |
(uint32_t(m_pCurrent[1])) | | |
(uint32_t(m_pCurrent[2]) << 8) | | |
(uint32_t(m_pCurrent[3]) << 16) | | |
(uint32_t(m_pCurrent[4]) << 24); | |
m_pCurrent += sizeof(uint32_t); | |
} | |
else | |
{ | |
switch (length) | |
{ | |
case 0x40: | |
length = 1; | |
break; | |
case 0x80: | |
length = 3; | |
break; | |
default: | |
length = 0; | |
} | |
value &= 0x3F; | |
if (SizeLeft() < length) | |
{ | |
return false; | |
} | |
for (uint8_t shift = 6; | |
length != 0; | |
length--, shift += 8) | |
{ | |
value |= *(m_pCurrent++) << shift; | |
} | |
} | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment