2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-05-31 05:27:42 +00:00

refactor: implement base x64 fastfile loading for iw4

This commit is contained in:
Jan 2025-05-03 17:31:17 +01:00
parent b9af8d1214
commit 46de4f9be0
No known key found for this signature in database
GPG Key ID: 44B581F78FF5C57C
44 changed files with 1033 additions and 333 deletions

View File

@ -132,11 +132,52 @@ namespace IW3
}; };
typedef char cbrushedge_t; typedef char cbrushedge_t;
typedef float vec2_t[2];
typedef float vec3_t[3];
typedef float vec4_t[4];
typedef tdef_align32(128) unsigned int raw_uint128; typedef tdef_align32(128) unsigned int raw_uint128;
union vec2_t
{
float v[2];
struct
{
float x;
float y;
};
};
union vec3_t
{
struct
{
float x;
float y;
float z;
};
float v[3];
};
union vec4_t
{
float v[4];
struct
{
float x;
float y;
float z;
float w;
};
struct
{
float r;
float g;
float b;
float a;
};
};
struct XModelPiece struct XModelPiece
{ {
XModel* model; XModel* model;

View File

@ -161,9 +161,50 @@ namespace IW4
typedef tdef_align32(128) unsigned int raw_uint128; typedef tdef_align32(128) unsigned int raw_uint128;
typedef unsigned char cbrushedge_t; typedef unsigned char cbrushedge_t;
typedef unsigned short r_index_t; typedef unsigned short r_index_t;
typedef float vec2_t[2];
typedef float vec3_t[3]; union vec2_t
typedef float vec4_t[4]; {
float v[2];
struct
{
float x;
float y;
};
};
union vec3_t
{
struct
{
float x;
float y;
float z;
};
float v[3];
};
union vec4_t
{
float v[4];
struct
{
float x;
float y;
float z;
float w;
};
struct
{
float r;
float g;
float b;
float a;
};
};
struct PhysPreset struct PhysPreset
{ {

View File

@ -5650,7 +5650,10 @@ namespace T6
uint16_t _2[1]; uint16_t _2[1];
}; };
typedef tdef_align32(4) int16_t XQuat2[2]; struct type_align32(4) XQuat2
{
int16_t value[2];
};
struct type_align32(4) XAnimDeltaPartQuatDataFrames2 struct type_align32(4) XAnimDeltaPartQuatDataFrames2
{ {
@ -5676,7 +5679,10 @@ namespace T6
uint16_t _2[1]; uint16_t _2[1];
}; };
typedef tdef_align32(4) int16_t XQuat[4]; struct type_align32(4) XQuat
{
int16_t value[4];
};
struct type_align32(4) XAnimDeltaPartQuatDataFrames struct type_align32(4) XAnimDeltaPartQuatDataFrames
{ {

View File

@ -382,8 +382,8 @@ namespace
for (auto i = 0u; i < originalGraphKnotCount; i++) for (auto i = 0u; i < originalGraphKnotCount; i++)
{ {
const auto& commonKnot = graph.knots[i]; const auto& commonKnot = graph.knots[i];
originalGraphKnots[i][0] = static_cast<float>(commonKnot.x); originalGraphKnots[i].x = static_cast<float>(commonKnot.x);
originalGraphKnots[i][1] = static_cast<float>(commonKnot.y); originalGraphKnots[i].y = static_cast<float>(commonKnot.y);
} }
graphKnots = originalGraphKnots; graphKnots = originalGraphKnots;

View File

@ -231,8 +231,8 @@ namespace IW4
for (auto i = 0u; i < originalKnotCount; i++) for (auto i = 0u; i < originalKnotCount; i++)
{ {
auto& knot = graph.knots[i]; auto& knot = graph.knots[i];
knot.x = originalKnots[i][0]; knot.x = originalKnots[i].x;
knot.y = originalKnots[i][1]; knot.y = originalKnots[i].y;
} }
return graph; return graph;

View File

@ -2,6 +2,7 @@
#include "Domain/Definition/ArrayDeclarationModifier.h" #include "Domain/Definition/ArrayDeclarationModifier.h"
#include "Domain/Definition/PointerDeclarationModifier.h" #include "Domain/Definition/PointerDeclarationModifier.h"
#include "Domain/Definition/TypedefDefinition.h"
#include "MemberComputations.h" #include "MemberComputations.h"
#include <algorithm> #include <algorithm>
@ -71,7 +72,7 @@ std::vector<DeclarationModifier*> DeclarationModifierComputations::GetFollowingD
return following; return following;
} }
std::vector<int> DeclarationModifierComputations::GetArrayIndices() const const std::vector<int>& DeclarationModifierComputations::GetArrayIndices() const
{ {
return m_modifier_indices; return m_modifier_indices;
} }
@ -241,6 +242,15 @@ const IEvaluation* DeclarationModifierComputations::GetDynamicArraySizeEvaluatio
return dynamic_cast<ArrayDeclarationModifier*>(declarationModifier)->m_dynamic_size_evaluation.get(); return dynamic_cast<ArrayDeclarationModifier*>(declarationModifier)->m_dynamic_size_evaluation.get();
} }
bool DeclarationModifierComputations::HasPointerModifier() const
{
return std::ranges::any_of(m_information->m_member->m_type_declaration->m_declaration_modifiers,
[](const std::unique_ptr<DeclarationModifier>& modifier)
{
return modifier->GetType() == DeclarationModifierType::POINTER;
});
}
unsigned DeclarationModifierComputations::GetAlignment() const unsigned DeclarationModifierComputations::GetAlignment() const
{ {
const auto following = GetFollowingDeclarationModifiers(); const auto following = GetFollowingDeclarationModifiers();

View File

@ -13,7 +13,7 @@ public:
[[nodiscard]] DeclarationModifier* GetDeclarationModifier() const; [[nodiscard]] DeclarationModifier* GetDeclarationModifier() const;
[[nodiscard]] DeclarationModifier* GetNextDeclarationModifier() const; [[nodiscard]] DeclarationModifier* GetNextDeclarationModifier() const;
[[nodiscard]] std::vector<DeclarationModifier*> GetFollowingDeclarationModifiers() const; [[nodiscard]] std::vector<DeclarationModifier*> GetFollowingDeclarationModifiers() const;
[[nodiscard]] std::vector<int> GetArrayIndices() const; [[nodiscard]] const std::vector<int>& GetArrayIndices() const;
[[nodiscard]] bool IsArray() const; [[nodiscard]] bool IsArray() const;
[[nodiscard]] int GetArraySize() const; [[nodiscard]] int GetArraySize() const;
[[nodiscard]] bool HasDynamicArrayCount() const; [[nodiscard]] bool HasDynamicArrayCount() const;
@ -26,6 +26,7 @@ public:
[[nodiscard]] const IEvaluation* GetPointerArrayCountEvaluation() const; [[nodiscard]] const IEvaluation* GetPointerArrayCountEvaluation() const;
[[nodiscard]] bool IsDynamicArray() const; [[nodiscard]] bool IsDynamicArray() const;
[[nodiscard]] const IEvaluation* GetDynamicArraySizeEvaluation() const; [[nodiscard]] const IEvaluation* GetDynamicArraySizeEvaluation() const;
[[nodiscard]] bool HasPointerModifier() const;
[[nodiscard]] unsigned GetAlignment() const; [[nodiscard]] unsigned GetAlignment() const;
private: private:

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "Utils/ClassUtils.h" #include <cstdint>
enum class DeclarationModifierType enum class DeclarationModifierType : std::uint8_t
{ {
POINTER, POINTER,
ARRAY ARRAY

View File

@ -5,13 +5,13 @@
#include <cassert> #include <cassert>
TypeDeclaration::TypeDeclaration(const DataDefinition* type) TypeDeclaration::TypeDeclaration(const DataDefinition* type)
: m_flags(0), : m_is_const(false),
m_size(0),
m_alignment(0),
m_is_const(false),
m_has_custom_bit_size(false), m_has_custom_bit_size(false),
m_type(type), m_type(type),
m_custom_bit_size(0) m_custom_bit_size(0),
m_flags(0),
m_size(0),
m_alignment(0)
{ {
assert(m_type != nullptr); assert(m_type != nullptr);
} }

View File

@ -0,0 +1,19 @@
#include "Architecture.h"
#include <cassert>
unsigned GetPointerSizeForArchitecture(const Architecture architecture)
{
switch (architecture)
{
case Architecture::X86:
return sizeof(uint32_t);
case Architecture::X64:
return sizeof(uint64_t);
default:
assert(false);
return sizeof(uint32_t);
}
}

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
enum class Architecture #include <cstdint>
enum class Architecture : std::uint8_t
{ {
UNKNOWN, UNKNOWN,
X86, X86,
@ -14,3 +16,5 @@ static constexpr Architecture OWN_ARCHITECTURE =
Architecture::X64 Architecture::X64
#endif #endif
; ;
extern unsigned GetPointerSizeForArchitecture(Architecture architecture);

View File

@ -21,6 +21,7 @@ RenderingUsedType::RenderingUsedType(const DataDefinition* type, StructureInform
RenderingContext::RenderingContext(std::string game, const Architecture gameArchitecture, std::vector<const FastFileBlock*> fastFileBlocks) RenderingContext::RenderingContext(std::string game, const Architecture gameArchitecture, std::vector<const FastFileBlock*> fastFileBlocks)
: m_game(std::move(game)), : m_game(std::move(game)),
m_architecture_mismatch(gameArchitecture != OWN_ARCHITECTURE), m_architecture_mismatch(gameArchitecture != OWN_ARCHITECTURE),
m_pointer_size(GetPointerSizeForArchitecture(gameArchitecture)),
m_blocks(std::move(fastFileBlocks)), m_blocks(std::move(fastFileBlocks)),
m_asset(nullptr), m_asset(nullptr),
m_has_actions(false), m_has_actions(false),

View File

@ -31,6 +31,7 @@ public:
std::string m_game; std::string m_game;
bool m_architecture_mismatch; bool m_architecture_mismatch;
unsigned m_pointer_size;
std::vector<const FastFileBlock*> m_blocks; std::vector<const FastFileBlock*> m_blocks;
StructureInformation* m_asset; StructureInformation* m_asset;

View File

@ -136,18 +136,6 @@ std::string
return str.str(); return str.str();
} }
std::string BaseTemplate::MakeMemberAccess(const std::string& variableName,
StructureInformation* info,
const MemberInformation* member,
const DeclarationModifierComputations& modifier)
{
std::ostringstream str;
str << variableName << "->" << member->m_member->m_name;
MakeArrayIndicesInternal(modifier, str);
return str.str();
}
std::string BaseTemplate::MakeTypeDecl(const TypeDeclaration* decl) std::string BaseTemplate::MakeTypeDecl(const TypeDeclaration* decl)
{ {
std::ostringstream str; std::ostringstream str;

View File

@ -29,10 +29,6 @@ protected:
static std::string MakeMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier); static std::string MakeMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier);
static std::string static std::string
MakeWrittenMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier); MakeWrittenMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier);
static std::string MakeMemberAccess(const std::string& variableName,
StructureInformation* info,
const MemberInformation* member,
const DeclarationModifierComputations& modifier);
static std::string MakeTypeDecl(const TypeDeclaration* decl); static std::string MakeTypeDecl(const TypeDeclaration* decl);
static std::string MakeFollowingReferences(const std::vector<DeclarationModifier*>& modifiers); static std::string MakeFollowingReferences(const std::vector<DeclarationModifier*>& modifiers);
static std::string MakeArrayIndices(const DeclarationModifierComputations& modifierComputations); static std::string MakeArrayIndices(const DeclarationModifierComputations& modifierComputations);

View File

@ -6,6 +6,7 @@
#include "Utils/StringUtils.h" #include "Utils/StringUtils.h"
#include <cassert> #include <cassert>
#include <iostream>
#include <sstream> #include <sstream>
namespace namespace
@ -61,7 +62,8 @@ namespace
// Method Declarations // Method Declarations
for (const auto* type : m_env.m_used_types) for (const auto* type : m_env.m_used_types)
{ {
if (type->m_info && type->m_type == type->m_info->m_definition && !type->m_info->m_has_matching_cross_platform_structure) if (type->m_info && type->m_type == type->m_info->m_definition && !type->m_info->m_has_matching_cross_platform_structure
&& (type->m_is_context_asset || !StructureComputations(type->m_info).IsAsset()))
{ {
PrintFillStructMethodDeclaration(type->m_info); PrintFillStructMethodDeclaration(type->m_info);
} }
@ -104,7 +106,8 @@ namespace
// Variable Declarations: type varType; // Variable Declarations: type varType;
for (const auto* type : m_env.m_used_types) for (const auto* type : m_env.m_used_types)
{ {
if (type->m_info && !type->m_info->m_definition->m_anonymous && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset()) if (type->m_info && !type->m_info->m_definition->m_anonymous
&& (!type->m_info->m_is_leaf || !type->m_info->m_has_matching_cross_platform_structure) && !StructureComputations(type->m_info).IsAsset())
{ {
LINE(VariableDecl(type->m_type)) LINE(VariableDecl(type->m_type))
} }
@ -148,6 +151,7 @@ namespace
LINE("") LINE("")
LINE("#include <cassert>") LINE("#include <cassert>")
LINE("#include <cstring>") LINE("#include <cstring>")
LINE("#include <type_traits>")
LINE("") LINE("")
LINEF("using namespace {0};", m_env.m_game) LINEF("using namespace {0};", m_env.m_game)
@ -158,7 +162,8 @@ namespace
for (const auto* type : m_env.m_used_types) for (const auto* type : m_env.m_used_types)
{ {
if (type->m_info && type->m_type == type->m_info->m_definition && !type->m_info->m_has_matching_cross_platform_structure) if (type->m_info && type->m_type == type->m_info->m_definition && !type->m_info->m_has_matching_cross_platform_structure
&& (type->m_is_context_asset || !StructureComputations(type->m_info).IsAsset()))
{ {
LINE("") LINE("")
PrintFillStructMethod(type->m_info); PrintFillStructMethod(type->m_info);
@ -317,6 +322,251 @@ namespace
LINE("}") LINE("}")
} }
[[nodiscard]] size_t SizeForDeclModifierLevel(const MemberInformation& memberInfo, const size_t level) const
{
const auto& declModifiers = memberInfo.m_member->m_type_declaration->m_declaration_modifiers;
if (declModifiers.empty())
return memberInfo.m_member->m_type_declaration->GetSize();
if (level == 0)
return memberInfo.m_member->m_type_declaration->GetSize();
size_t currentSize = memberInfo.m_member->m_type_declaration->m_type->GetSize();
const auto end = declModifiers.rbegin() + (declModifiers.size() - level);
for (auto i = declModifiers.rbegin(); i != end; ++i)
{
if ((*i)->GetType() == DeclarationModifierType::POINTER)
currentSize = m_env.m_pointer_size;
else
currentSize *= dynamic_cast<ArrayDeclarationModifier*>(i->get())->m_size;
}
return currentSize;
}
[[nodiscard]] size_t
OffsetForMemberModifier(const MemberInformation& memberInfo, const DeclarationModifierComputations& modifier, const size_t nestedBaseOffset) const
{
size_t curOffset = memberInfo.m_member->m_offset;
const auto& declModifiers = memberInfo.m_member->m_type_declaration->m_declaration_modifiers;
auto curDeclModifier = declModifiers.begin();
auto curLevel = 0u;
for (const auto index : modifier.GetArrayIndices())
{
if (index > 0)
curOffset += index * SizeForDeclModifierLevel(memberInfo, curLevel + 1);
curLevel++;
}
return curOffset + nestedBaseOffset;
}
void PrintFillStruct_Member_DynamicArray(const StructureInformation& structInfo,
const MemberInformation& memberInfo,
const DeclarationModifierComputations& modifier,
const size_t nestedBaseOffset)
{
LINEF("const auto dynamicArraySize = {0};", MakeEvaluation(modifier.GetDynamicArraySizeEvaluation()))
LINE("if (dynamicArraySize > 0)")
LINE("{")
m_intendation++;
const auto callFillForMember = memberInfo.m_type && !memberInfo.m_type->m_has_matching_cross_platform_structure;
if (callFillForMember)
{
LINEF("{0} = &{1}[0];", MakeTypeVarName(memberInfo.m_member->m_type_declaration->m_type), MakeMemberAccess(&structInfo, &memberInfo, modifier))
LINEF("FillStruct_{0}(fillAccessor.AtOffset({1}));",
MakeSafeTypeName(memberInfo.m_member->m_type_declaration->m_type),
OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset))
}
else
{
LINEF("fillAccessor.Fill({0}[0], {1});", MakeMemberAccess(&structInfo, &memberInfo, modifier), memberInfo.m_member->m_offset)
}
LINEF("const auto dynamicFill = m_stream.LoadWithFill({0} * static_cast<size_t>(dynamicArraySize - 1));",
memberInfo.m_member->m_type_declaration->GetSize())
LINEF("for (auto i = 1u; i < dynamicArraySize; i++)", structInfo.m_definition->m_name, memberInfo.m_member->m_name)
LINE("{")
m_intendation++;
if (callFillForMember)
{
LINEF("{0} = &{1}[i];", MakeTypeVarName(memberInfo.m_member->m_type_declaration->m_type), MakeMemberAccess(&structInfo, &memberInfo, modifier))
LINEF("FillStruct_{0}(dynamicFill.AtOffset((i - 1u) * {1}));",
MakeSafeTypeName(memberInfo.m_member->m_type_declaration->m_type),
memberInfo.m_member->m_type_declaration->GetSize())
}
else
{
LINEF("dynamicFill.Fill({0}[i], (i - 1u) * {1});",
MakeMemberAccess(&structInfo, &memberInfo, modifier),
memberInfo.m_member->m_type_declaration->GetSize())
}
m_intendation--;
LINE("}")
m_intendation--;
LINE("}")
}
void PrintFillStruct_Member_PointerArray(const StructureInformation& structInfo,
const MemberInformation& memberInfo,
const DeclarationModifierComputations& modifier,
const size_t nestedBaseOffset)
{
if (modifier.IsArray())
{
LINEF("for (auto i = 0u; i < std::extent_v<decltype({0}::{1})>; i++)", structInfo.m_definition->m_name, memberInfo.m_member->m_name)
m_intendation++;
LINEF("fillAccessor.FillPtr({0}[i], {1} + {2} * i);",
MakeMemberAccess(&structInfo, &memberInfo, modifier),
OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset),
m_env.m_pointer_size)
m_intendation--;
}
else
{
LINEF("fillAccessor.FillPtr({0}, {1});",
MakeMemberAccess(&structInfo, &memberInfo, modifier),
OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset))
}
}
void PrintFillStruct_Member_EmbeddedArray(const StructureInformation& structInfo,
const MemberInformation& memberInfo,
const DeclarationModifierComputations& modifier,
const size_t nestedBaseOffset)
{
if (memberInfo.m_type && !memberInfo.m_type->m_has_matching_cross_platform_structure)
{
LINEF("for (auto i = 0u; i < std::extent_v<decltype({0}::{1})>; i++)", structInfo.m_definition->m_name, memberInfo.m_member->m_name)
LINE("{")
m_intendation++;
LINEF("{0} = &{1}[i];", MakeTypeVarName(memberInfo.m_member->m_type_declaration->m_type), MakeMemberAccess(&structInfo, &memberInfo, modifier))
LINEF("FillStruct_{0}(fillAccessor.AtOffset({1} + i * {2}));",
MakeSafeTypeName(memberInfo.m_member->m_type_declaration->m_type),
OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset),
memberInfo.m_member->m_type_declaration->m_type->GetSize())
m_intendation--;
LINE("}")
}
else
{
LINEF("fillAccessor.FillArray({0}, {1});",
MakeMemberAccess(&structInfo, &memberInfo, modifier),
OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset))
}
}
void PrintFillStruct_Member_Embedded(const StructureInformation& structInfo,
const MemberInformation& memberInfo,
const DeclarationModifierComputations& modifier,
const size_t nestedBaseOffset)
{
const auto hasAnonymousType = memberInfo.m_type && memberInfo.m_type->m_definition->m_anonymous;
if (!hasAnonymousType)
{
if (memberInfo.m_type && !memberInfo.m_type->m_has_matching_cross_platform_structure)
{
LINEF("{0} = &{1};", MakeTypeVarName(memberInfo.m_member->m_type_declaration->m_type), MakeMemberAccess(&structInfo, &memberInfo, modifier))
LINEF("FillStruct_{0}(fillAccessor.AtOffset({1}));",
MakeSafeTypeName(memberInfo.m_member->m_type_declaration->m_type),
OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset))
}
else
{
LINEF("fillAccessor.Fill({0}, {1});",
MakeMemberAccess(&structInfo, &memberInfo, modifier),
OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset))
}
}
else if (memberInfo.m_member->m_name.empty())
{
const auto anonymousMemberOffset = memberInfo.m_member->m_offset + nestedBaseOffset;
for (const auto& anonymousMember : memberInfo.m_type->m_ordered_members)
{
PrintFillStruct_Member(structInfo, *anonymousMember, DeclarationModifierComputations(anonymousMember.get()), anonymousMemberOffset);
}
}
else
{
LINEF("#error Unsupported anonymous struct with name: {0}", memberInfo.m_member->m_name);
}
}
void PrintFillStruct_Member_ReferenceArray(const StructureInformation& info,
const MemberInformation& member,
const DeclarationModifierComputations& modifier,
const size_t nestedBaseOffset)
{
for (const auto& entry : modifier.GetArrayEntries())
{
PrintFillStruct_Member(info, member, entry, nestedBaseOffset);
}
}
// nestedBaseOffset: Base offset in case member is part of a nested anonymous sub-struct
void PrintFillStruct_Member(const StructureInformation& structInfo,
const MemberInformation& memberInfo,
const DeclarationModifierComputations& modifier,
const size_t nestedBaseOffset)
{
if (modifier.IsDynamicArray())
{
PrintFillStruct_Member_DynamicArray(structInfo, memberInfo, modifier, nestedBaseOffset);
}
else if (modifier.IsSinglePointer() || modifier.IsArrayPointer())
{
LINEF("fillAccessor.FillPtr({0}, {1});",
MakeMemberAccess(&structInfo, &memberInfo, modifier),
OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset))
}
else if (modifier.IsPointerArray())
{
PrintFillStruct_Member_PointerArray(structInfo, memberInfo, modifier, nestedBaseOffset);
}
else if (modifier.IsArray() && modifier.GetNextDeclarationModifier() == nullptr)
{
PrintFillStruct_Member_EmbeddedArray(structInfo, memberInfo, modifier, nestedBaseOffset);
}
else if (modifier.GetDeclarationModifier() == nullptr)
{
PrintFillStruct_Member_Embedded(structInfo, memberInfo, modifier, nestedBaseOffset);
}
else if (modifier.IsArray())
{
PrintFillStruct_Member_ReferenceArray(structInfo, memberInfo, modifier, nestedBaseOffset);
}
else
{
assert(false);
LINEF("#error PrintFillStruct_Member failed @ {0}", memberInfo.m_member->m_name)
}
}
void PrintFillStruct_Struct(const StructureInformation& info)
{
const auto* dynamicMember = StructureComputations(&info).GetDynamicMember();
for (const auto& member : info.m_ordered_members)
{
const MemberComputations computations(member.get());
if (computations.ShouldIgnore() || member.get() == dynamicMember)
continue;
PrintFillStruct_Member(info, *member, DeclarationModifierComputations(member.get()), 0u);
}
// Always fill dynamic members last
if (dynamicMember)
PrintFillStruct_Member(info, *dynamicMember, DeclarationModifierComputations(dynamicMember), 0u);
}
void PrintFillStructMethod(const StructureInformation* info) void PrintFillStructMethod(const StructureInformation* info)
{ {
LINEF("void {0}::FillStruct_{1}(const ZoneStreamFillReadAccessor& fillAccessor)", LINEF("void {0}::FillStruct_{1}(const ZoneStreamFillReadAccessor& fillAccessor)",
@ -326,14 +576,7 @@ namespace
LINE("{") LINE("{")
m_intendation++; m_intendation++;
for (const auto& member : info->m_ordered_members) PrintFillStruct_Struct(*info);
{
const MemberComputations computations(member.get());
if (computations.ShouldIgnore())
continue;
LINEF("// FillStruct_{0}();", MakeSafeTypeName(member->m_member->m_type_declaration->m_type))
}
m_intendation--; m_intendation--;
LINE("}") LINE("}")
@ -341,7 +584,11 @@ namespace
void PrintLoadPtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info) const void PrintLoadPtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info) const
{ {
LINEF("*{0} = m_stream.Alloc<{1}>({2});", MakeTypePtrVarName(def), def->GetFullName(), def->GetAlignment()) LINEF("*{0} = m_stream.{1}<{2}>({3});",
MakeTypePtrVarName(def),
m_env.m_architecture_mismatch ? "AllocOutOfBlock" : "Alloc",
def->GetFullName(),
def->GetAlignment())
if (info && !info->m_is_leaf) if (info && !info->m_is_leaf)
{ {
@ -369,7 +616,8 @@ namespace
{ {
if (reusable) if (reusable)
{ {
LINEF("if (*{0} == PTR_FOLLOWING)", MakeTypePtrVarName(def)) LINEF("const auto zonePtrType = GetZonePointerType(*{0});", MakeTypePtrVarName(def))
LINEF("if (zonePtrType == ZonePointerType::FOLLOWING)", MakeTypePtrVarName(def))
LINE("{") LINE("{")
m_intendation++; m_intendation++;
@ -406,9 +654,25 @@ namespace
LINE("") LINE("")
LINE("if (atStreamStart)") LINE("if (atStreamStart)")
m_intendation++;
LINEF("m_stream.Load<{0}*>({1}, count);", def->GetFullName(), MakeTypePtrVarName(def)) if (m_env.m_architecture_mismatch)
m_intendation--; {
LINE("{")
m_intendation++;
LINEF("const auto ptrArrayFill = m_stream.LoadWithFill({0} * count);", m_env.m_pointer_size)
LINE("for (size_t index = 0; index < count; index++)")
m_intendation++;
LINEF("ptrArrayFill.FillPtr({0}[index], {1} * index);", MakeTypePtrVarName(def), m_env.m_pointer_size)
m_intendation--;
m_intendation--;
LINE("}")
}
else
{
m_intendation++;
LINEF("m_stream.Load<{0}*>({1}, count);", def->GetFullName(), MakeTypePtrVarName(def))
m_intendation--;
}
LINE("") LINE("")
LINEF("{0}** var = {1};", def->GetFullName(), MakeTypePtrVarName(def)) LINEF("{0}** var = {1};", def->GetFullName(), MakeTypePtrVarName(def))
@ -436,17 +700,45 @@ namespace
LINEF("assert({0} != nullptr);", MakeTypeVarName(def)) LINEF("assert({0} != nullptr);", MakeTypeVarName(def))
LINE("") LINE("")
LINE("if (atStreamStart)") LINE("if (atStreamStart)")
m_intendation++;
LINEF("m_stream.Load<{0}>({1}, count);", def->GetFullName(), MakeTypeVarName(def)) if (info->m_has_matching_cross_platform_structure)
m_intendation--; {
m_intendation++;
LINEF("m_stream.Load<{0}>({1}, count);", info->m_definition->GetFullName(), MakeTypeVarName(def))
m_intendation--;
}
else
{
LINE("{")
m_intendation++;
LINEF("const auto arrayFill = m_stream.LoadWithFill({0} * count);", def->GetSize())
LINEF("auto* arrayStart = {0};", MakeTypeVarName(def))
LINEF("auto* var = {0};", MakeTypeVarName(def))
LINE("for (size_t index = 0; index < count; index++)")
LINE("{")
m_intendation++;
LINEF("{0} = var;", MakeTypeVarName(def))
LINEF("FillStruct_{0}(arrayFill.AtOffset(0 + {1} * index));", info->m_definition->m_name, def->GetSize())
LINE("var++;")
m_intendation--;
LINE("}")
LINEF("{0} = arrayStart;", MakeTypeVarName(def))
m_intendation--;
LINE("}")
}
LINE("") LINE("")
LINEF("{0}* var = {1};", def->GetFullName(), MakeTypeVarName(def)) LINEF("auto* var = {0};", MakeTypeVarName(def))
LINE("for (size_t index = 0; index < count; index++)") LINE("for (size_t index = 0; index < count; index++)")
LINE("{") LINE("{")
m_intendation++; m_intendation++;
LINEF("{0} = var;", MakeTypeVarName(info->m_definition)) LINEF("{0} = var;", MakeTypeVarName(def))
LINEF("Load_{0}(false);", info->m_definition->m_name) LINEF("Load_{0}(false);", info->m_definition->m_name)
LINE("var++;") LINE("var++;")
@ -575,7 +867,7 @@ namespace
{ {
LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier)) LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
if (computations.IsAfterPartialLoad()) if (computations.IsAfterPartialLoad() && !m_env.m_architecture_mismatch)
{ {
LINEF("LoadArray_{0}(true, {1});", MakeSafeTypeName(member->m_member->m_type_declaration->m_type), arraySizeStr) LINEF("LoadArray_{0}(true, {1});", MakeSafeTypeName(member->m_member->m_type_declaration->m_type), arraySizeStr)
} }
@ -596,7 +888,7 @@ namespace
LINE(MakeCustomActionCall(member->m_post_load_action.get())) LINE(MakeCustomActionCall(member->m_post_load_action.get()))
} }
} }
else if (computations.IsAfterPartialLoad()) else if (computations.IsAfterPartialLoad() && !m_env.m_architecture_mismatch)
{ {
LINEF("m_stream.Load<{0}{1}>({2}, {3});", LINEF("m_stream.Load<{0}{1}>({2}, {3});",
MakeTypeDecl(member->m_member->m_type_declaration.get()), MakeTypeDecl(member->m_member->m_type_declaration.get()),
@ -611,11 +903,12 @@ namespace
if (member->m_type && !member->m_type->m_is_leaf) if (member->m_type && !member->m_type->m_is_leaf)
{ {
LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier)) LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
LINEF("LoadArray_{0}(true, {1});", LINEF("LoadArray_{0}({1}, {2});",
MakeSafeTypeName(member->m_member->m_type_declaration->m_type), MakeSafeTypeName(member->m_member->m_type_declaration->m_type),
m_env.m_architecture_mismatch ? "false" : "true",
MakeEvaluation(modifier.GetDynamicArraySizeEvaluation())) MakeEvaluation(modifier.GetDynamicArraySizeEvaluation()))
} }
else else if (info->m_has_matching_cross_platform_structure)
{ {
LINEF("m_stream.Load<{0}{1}>({2}, {3});", LINEF("m_stream.Load<{0}{1}>({2}, {3});",
MakeTypeDecl(member->m_member->m_type_declaration.get()), MakeTypeDecl(member->m_member->m_type_declaration.get()),
@ -632,7 +925,7 @@ namespace
{ {
LINEF("{0} = &{1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier)) LINEF("{0} = &{1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
if (computations.IsAfterPartialLoad()) if (computations.IsAfterPartialLoad() && !m_env.m_architecture_mismatch)
{ {
LINEF("Load_{0}(true);", MakeSafeTypeName(member->m_member->m_type_declaration->m_type)) LINEF("Load_{0}(true);", MakeSafeTypeName(member->m_member->m_type_declaration->m_type))
} }
@ -653,7 +946,7 @@ namespace
LINE(MakeCustomActionCall(member->m_post_load_action.get())) LINE(MakeCustomActionCall(member->m_post_load_action.get()))
} }
} }
else if (computations.IsAfterPartialLoad()) else if (computations.IsAfterPartialLoad() && !m_env.m_architecture_mismatch)
{ {
LINEF("m_stream.Load<{0}{1}>(&{2});", LINEF("m_stream.Load<{0}{1}>(&{2});",
MakeTypeDecl(member->m_member->m_type_declaration.get()), MakeTypeDecl(member->m_member->m_type_declaration.get()),
@ -775,39 +1068,58 @@ namespace
return; return;
} }
const MemberComputations computations(member);
if (computations.IsInTempBlock())
{
LINEF("{0}* ptr = {1};", member->m_member->m_type_declaration->m_type->GetFullName(), MakeMemberAccess(info, member, modifier))
}
const auto typeDecl = MakeTypeDecl(member->m_member->m_type_declaration.get()); const auto typeDecl = MakeTypeDecl(member->m_member->m_type_declaration.get());
const auto followingReferences = MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()); const auto followingReferences = MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers());
const auto allocOutOfBlock =
(member->m_type && !member->m_type->m_has_matching_cross_platform_structure) || loadType == MemberLoadType::POINTER_ARRAY;
LINE_STARTF("{0} = m_stream.", MakeMemberAccess(info, member, modifier))
if (allocOutOfBlock)
LINE_MIDDLE("AllocOutOfBlock")
else
LINE_MIDDLE("Alloc")
LINE_MIDDLEF("<{0}{1}>(", typeDecl, followingReferences)
// This used to use `alignof()` to calculate alignment but due to inconsistencies between compilers and bugs discovered in MSVC // This used to use `alignof()` to calculate alignment but due to inconsistencies between compilers and bugs discovered in MSVC
// (Alignment specified via `__declspec(align())` showing as correct via intellisense but is incorrect when compiled for types that have a larger // (Alignment specified via `__declspec(align())` showing as correct via intellisense but is incorrect when compiled for types that have a larger
// alignment than the specified value) this was changed to make ZoneCodeGenerator calculate what is supposed to be used as alignment when // alignment than the specified value) this was changed to make ZoneCodeGenerator calculate what is supposed to be used as alignment when
// allocating. This is more reliable when being used with different compilers and the value used can be seen in the source code directly // allocating. This is more reliable when being used with different compilers and the value used can be seen in the source code directly
if (member->m_alloc_alignment) if (member->m_alloc_alignment)
{ {
LINEF("{0} = m_stream.Alloc<{1}{2}>({3});", LINE_MIDDLE(MakeEvaluation(member->m_alloc_alignment.get()))
MakeMemberAccess(info, member, modifier),
typeDecl,
followingReferences,
MakeEvaluation(member->m_alloc_alignment.get()))
} }
else else
{ {
LINEF("{0} = m_stream.Alloc<{1}{2}>({3});", MakeMemberAccess(info, member, modifier), typeDecl, followingReferences, modifier.GetAlignment()) LINE_MIDDLEF("{0}", modifier.GetAlignment())
} }
if (allocOutOfBlock && modifier.IsArrayPointer())
LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetArrayPointerCountEvaluation()))
else if (allocOutOfBlock && modifier.IsPointerArray())
LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetPointerArrayCountEvaluation()))
LINE_END(");")
const MemberComputations computations(member);
if (computations.IsInTempBlock()) if (computations.IsInTempBlock())
{ {
LINE("") LINE("")
LINEF("{0}** toInsert = nullptr;", member->m_member->m_type_declaration->m_type->GetFullName())
LINE("if (ptr == PTR_INSERT)") if (m_env.m_architecture_mismatch)
LINE("uintptr_t toInsertLookupEntry = 0;")
else
LINEF("{0}** toInsert = nullptr;", member->m_member->m_type_declaration->m_type->GetFullName())
LINE("if (zonePtrType == ZonePointerType::INSERT)")
m_intendation++; m_intendation++;
LINEF("toInsert = m_stream.InsertPointerNative<{0}>();", member->m_member->m_type_declaration->m_type->GetFullName())
if (m_env.m_architecture_mismatch)
LINE("toInsertLookupEntry = m_stream.InsertPointerAliasLookup();")
else
LINEF("toInsert = m_stream.InsertPointerNative<{0}>();", member->m_member->m_type_declaration->m_type->GetFullName())
m_intendation--; m_intendation--;
LINE("") LINE("")
} }
@ -817,9 +1129,15 @@ namespace
if (computations.IsInTempBlock()) if (computations.IsInTempBlock())
{ {
LINE("") LINE("")
LINE("if (toInsert != nullptr)") LINE("if (zonePtrType == ZonePointerType::INSERT)")
m_intendation++; m_intendation++;
LINEF("*toInsert = {0}->{1};", MakeTypeVarName(info->m_definition), member->m_member->m_name)
if (m_env.m_architecture_mismatch)
LINEF(
"m_stream.SetInsertedPointerAliasLookup(toInsertLookupEntry, {0}->{1});", MakeTypeVarName(info->m_definition), member->m_member->m_name)
else
LINEF("*toInsert = {0}->{1};", MakeTypeVarName(info->m_definition), member->m_member->m_name)
m_intendation--; m_intendation--;
} }
} }
@ -850,10 +1168,12 @@ namespace
return; return;
} }
LINEF("const auto zonePtrType = GetZonePointerType({0});", MakeMemberAccess(info, member, modifier))
const MemberComputations computations(member); const MemberComputations computations(member);
if (computations.IsInTempBlock()) if (computations.IsInTempBlock())
{ {
LINEF("if ({0} == PTR_FOLLOWING || {0} == PTR_INSERT)", MakeMemberAccess(info, member, modifier)) LINE("if (zonePtrType == ZonePointerType::FOLLOWING || zonePtrType == ZonePointerType::INSERT)")
LINE("{") LINE("{")
m_intendation++; m_intendation++;
@ -872,7 +1192,7 @@ namespace
} }
else else
{ {
LINEF("if ({0} == PTR_FOLLOWING)", MakeMemberAccess(info, member, modifier)) LINE("if (zonePtrType == ZonePointerType::FOLLOWING)")
LINE("{") LINE("{")
m_intendation++; m_intendation++;
@ -1123,10 +1443,9 @@ namespace
LINE("") LINE("")
LINE("if (atStreamStart)") LINE("if (atStreamStart)")
m_intendation++;
if (info->m_has_matching_cross_platform_structure) if (info->m_has_matching_cross_platform_structure)
{ {
m_intendation++;
if (dynamicMember == nullptr) if (dynamicMember == nullptr)
{ {
LINEF("m_stream.Load<{0}>({1}); // Size: {2}", LINEF("m_stream.Load<{0}>({1}); // Size: {2}",
@ -1141,20 +1460,12 @@ namespace
MakeTypeVarName(info->m_definition), MakeTypeVarName(info->m_definition),
dynamicMember->m_member->m_name) dynamicMember->m_member->m_name)
} }
m_intendation--;
} }
else else
{ {
LINE("{")
m_intendation++;
LINEF("{0} = m_memory.Alloc<{1}>();", MakeTypeVarName(info->m_definition), info->m_definition->m_name)
LINEF("FillStruct_{0}(m_stream.LoadWithFill({1}));", MakeSafeTypeName(info->m_definition), info->m_definition->GetSize()) LINEF("FillStruct_{0}(m_stream.LoadWithFill({1}));", MakeSafeTypeName(info->m_definition), info->m_definition->GetSize())
m_intendation--;
LINE("}")
} }
m_intendation--;
} }
else else
{ {
@ -1197,10 +1508,17 @@ namespace
LINEF("assert({0} != nullptr);", MakeTypePtrVarName(info->m_definition)) LINEF("assert({0} != nullptr);", MakeTypePtrVarName(info->m_definition))
LINE("") LINE("")
LINE("if (atStreamStart)") if (!m_env.m_architecture_mismatch)
m_intendation++; {
LINEF("m_stream.Load<{0}*>({1});", info->m_definition->GetFullName(), MakeTypePtrVarName(info->m_definition)) LINE("if (atStreamStart)")
m_intendation--; m_intendation++;
LINEF("m_stream.Load<{0}*>({1});", info->m_definition->GetFullName(), MakeTypePtrVarName(info->m_definition))
m_intendation--;
}
else
{
LINE("assert(!atStreamStart);");
}
LINE("") LINE("")
if (inTemp) if (inTemp)
@ -1213,23 +1531,21 @@ namespace
LINE("{") LINE("{")
m_intendation++; m_intendation++;
LINEF("const auto zonePtrType = GetZonePointerType(*{0});", MakeTypePtrVarName(info->m_definition))
if (inTemp) if (inTemp)
{ {
LINEF("if (*{0} == PTR_FOLLOWING || *{0} == PTR_INSERT)", MakeTypePtrVarName(info->m_definition)) LINEF("if (zonePtrType == ZonePointerType::FOLLOWING || zonePtrType == ZonePointerType::INSERT)", MakeTypePtrVarName(info->m_definition))
} }
else else
{ {
LINEF("if (*{0} == PTR_FOLLOWING)", MakeTypePtrVarName(info->m_definition)) LINEF("if (zonePtrType == ZonePointerType::FOLLOWING)", MakeTypePtrVarName(info->m_definition))
} }
LINE("{") LINE("{")
m_intendation++; m_intendation++;
if (inTemp) LINEF("*{0} = m_stream.{1}<{2}>({3});",
{
LINEF("{0}* ptr = *{1};", info->m_definition->GetFullName(), MakeTypePtrVarName(info->m_definition))
}
LINEF("*{0} = m_stream.Alloc<{1}>({2});",
MakeTypePtrVarName(info->m_definition), MakeTypePtrVarName(info->m_definition),
m_env.m_architecture_mismatch ? "AllocOutOfBlock" : "Alloc",
info->m_definition->GetFullName(), info->m_definition->GetFullName(),
info->m_definition->GetAlignment()) info->m_definition->GetAlignment())
@ -1237,7 +1553,7 @@ namespace
{ {
LINE("") LINE("")
LINEF("{0}** toInsert = nullptr;", info->m_definition->GetFullName()) LINEF("{0}** toInsert = nullptr;", info->m_definition->GetFullName())
LINE("if (ptr == PTR_INSERT)") LINE("if (zonePtrType == ZonePointerType::INSERT)")
m_intendation++; m_intendation++;
LINEF("toInsert = m_stream.InsertPointerNative<{0}>();", info->m_definition->GetFullName()) LINEF("toInsert = m_stream.InsertPointerNative<{0}>();", info->m_definition->GetFullName())
m_intendation--; m_intendation--;
@ -1293,7 +1609,14 @@ namespace
if (inTemp) if (inTemp)
{ {
LINEF("*{0} = m_stream.ConvertOffsetToAliasNative(*{0});", MakeTypePtrVarName(info->m_definition)) if (info->m_has_matching_cross_platform_structure)
{
LINEF("*{0} = m_stream.ConvertOffsetToAliasNative(*{0});", MakeTypePtrVarName(info->m_definition))
}
else
{
LINEF("*{0} = m_stream.ConvertOffsetToPointerRedirect(*{0});", MakeTypePtrVarName(info->m_definition))
}
} }
else else
{ {
@ -1328,7 +1651,7 @@ namespace
LINE("assert(pAsset != nullptr);") LINE("assert(pAsset != nullptr);")
LINE("") LINE("")
LINEF("{0} marker(m_zone);", MarkerClassName(m_env.m_asset)) LINEF("{0} marker(m_zone);", MarkerClassName(m_env.m_asset))
LINE("marker.Mark(*pAsset);") LINE("// marker.Mark(*pAsset); // TODO")
LINE("") LINE("")
LINEF("auto* reallocatedAsset = m_zone.Memory().Alloc<{0}>();", info->m_definition->GetFullName()) LINEF("auto* reallocatedAsset = m_zone.Memory().Alloc<{0}>();", info->m_definition->GetFullName())
LINEF("std::memcpy(reallocatedAsset, *pAsset, sizeof({0}));", info->m_definition->GetFullName()) LINEF("std::memcpy(reallocatedAsset, *pAsset, sizeof({0}));", info->m_definition->GetFullName())

View File

@ -12,22 +12,6 @@ namespace
bool CalculateFieldsIfNecessary(IDataRepository* repository, const DataDefinition* definition); bool CalculateFieldsIfNecessary(IDataRepository* repository, const DataDefinition* definition);
bool CalculateFields(IDataRepository* repository, TypeDeclaration* declaration); bool CalculateFields(IDataRepository* repository, TypeDeclaration* declaration);
unsigned GetPointerSizeForArchitecture(const Architecture architecture)
{
switch (architecture)
{
case Architecture::X86:
return sizeof(uint32_t);
case Architecture::X64:
return sizeof(uint64_t);
default:
assert(false);
return sizeof(uint32_t);
}
}
bool CalculateAlign(IDataRepository* repository, TypeDeclaration* declaration) bool CalculateAlign(IDataRepository* repository, TypeDeclaration* declaration)
{ {
auto hasPointerModifier = false; auto hasPointerModifier = false;

View File

@ -1,34 +1,23 @@
#include "XBlock.h" #include "XBlock.h"
#include <cassert> XBlock::XBlock(std::string name, const unsigned index, const XBlockType type)
: m_name(std::move(name)),
XBlock::XBlock(const std::string& name, const int index, const Type type) m_index(index),
m_type(type),
m_buffer_size(0u)
{ {
m_name = name;
m_index = index;
m_type = type;
m_buffer = nullptr;
m_buffer_size = 0;
}
XBlock::~XBlock()
{
delete[] m_buffer;
m_buffer = nullptr;
} }
void XBlock::Alloc(const size_t blockSize) void XBlock::Alloc(const size_t blockSize)
{ {
delete[] m_buffer;
if (blockSize > 0) if (blockSize > 0)
{ {
m_buffer = new uint8_t[blockSize]; m_buffer = std::make_unique<uint8_t[]>(blockSize);
m_buffer_size = blockSize; m_buffer_size = blockSize;
} }
else else
{ {
m_buffer = nullptr; m_buffer.reset();
m_buffer_size = 0; m_buffer_size = 0;
} }
} }

View File

@ -1,27 +1,29 @@
#pragma once #pragma once
#include <cstddef>
#include <cstdint> #include <cstdint>
#include <memory>
#include <string> #include <string>
enum class XBlockType : std::uint8_t
{
BLOCK_TYPE_TEMP,
BLOCK_TYPE_RUNTIME,
BLOCK_TYPE_DELAY,
BLOCK_TYPE_NORMAL
};
class XBlock class XBlock
{ {
public: public:
enum class Type XBlock(std::string name, unsigned index, XBlockType type);
{
BLOCK_TYPE_TEMP, void Alloc(size_t blockSize);
BLOCK_TYPE_RUNTIME,
BLOCK_TYPE_DELAY,
BLOCK_TYPE_NORMAL
};
std::string m_name; std::string m_name;
unsigned m_index; unsigned m_index;
Type m_type; XBlockType m_type;
uint8_t* m_buffer; std::unique_ptr<uint8_t[]> m_buffer;
size_t m_buffer_size; size_t m_buffer_size;
XBlock(const std::string& name, int index, Type type);
~XBlock();
void Alloc(size_t blockSize);
}; };

View File

@ -48,7 +48,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
if (varScriptStringList->strings != nullptr) if (varScriptStringList->strings != nullptr)
{ {
assert(varScriptStringList->strings == PTR_FOLLOWING); assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING);
varScriptStringList->strings = m_stream.Alloc<const char*>(alignof(const char*)); varScriptStringList->strings = m_stream.Alloc<const char*>(alignof(const char*));
varXString = varScriptStringList->strings; varXString = varScriptStringList->strings;
@ -146,7 +146,7 @@ void ContentLoader::Load()
if (assetList.assets != nullptr) if (assetList.assets != nullptr)
{ {
assert(assetList.assets == PTR_FOLLOWING); assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING);
assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset)); assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset));
varXAsset = assetList.assets; varXAsset = assetList.assets;

View File

@ -44,15 +44,15 @@ namespace
{ {
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type) #define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF #undef XBLOCK_DEF
} }
@ -92,7 +92,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
}, },
32u, 32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK)); ZoneConstants::INSERT_BLOCK,
zonePtr->Memory()));
return zoneLoader; return zoneLoader;
} }

View File

@ -71,9 +71,9 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
if (varScriptStringList->strings != nullptr) if (varScriptStringList->strings != nullptr)
{ {
assert(varScriptStringList->strings == PTR_FOLLOWING); assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING);
varScriptStringList->strings = m_stream.Alloc<const char*>(4); varScriptStringList->strings = m_stream.AllocOutOfBlock<const char*>(4, varScriptStringList->count);
varXString = varScriptStringList->strings; varXString = varScriptStringList->strings;
LoadXStringArray(true, varScriptStringList->count); LoadXStringArray(true, varScriptStringList->count);
@ -156,7 +156,16 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
assert(varXAsset != nullptr); assert(varXAsset != nullptr);
if (atStreamStart) if (atStreamStart)
m_stream.Load<XAsset>(varXAsset, count); {
const auto fill = m_stream.LoadWithFill(8u * count);
for (size_t index = 0; index < count; index++)
{
fill.Fill(varXAsset[index].type, 8u * index);
fill.FillPtr(varXAsset[index].header.data, 8u * index + 4u);
fill.InsertPointerRedirect(m_stream.AllocRedirectEntry(varXAsset[index].header.data), 8u * index + 4u);
}
}
for (size_t index = 0; index < count; index++) for (size_t index = 0; index < count; index++)
{ {
@ -179,9 +188,9 @@ void ContentLoader::Load()
if (assetList.assets != nullptr) if (assetList.assets != nullptr)
{ {
assert(assetList.assets == PTR_FOLLOWING); assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING);
assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset)); assetList.assets = m_stream.AllocOutOfBlock<XAsset>(4, assetList.assetCount);
varXAsset = assetList.assets; varXAsset = assetList.assets;
LoadXAssetArray(true, assetList.assetCount); LoadXAssetArray(true, assetList.assetCount);
} }

View File

@ -80,14 +80,14 @@ namespace
{ {
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type) #define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_CALLBACK, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF #undef XBLOCK_DEF
} }
@ -208,13 +208,14 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
// Start of the zone content // Start of the zone content
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent( zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
[&zonePtr](ZoneInputStream& stream) [zonePtr](ZoneInputStream& stream)
{ {
return std::make_unique<ContentLoader>(*zonePtr, stream); return std::make_unique<ContentLoader>(*zonePtr, stream);
}, },
32u, 32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK)); ZoneConstants::INSERT_BLOCK,
zonePtr->Memory()));
return zoneLoader; return zoneLoader;
} }

View File

@ -63,7 +63,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
if (varScriptStringList->strings != nullptr) if (varScriptStringList->strings != nullptr)
{ {
assert(varScriptStringList->strings == PTR_FOLLOWING); assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING);
varScriptStringList->strings = m_stream.Alloc<const char*>(alignof(const char*)); varScriptStringList->strings = m_stream.Alloc<const char*>(alignof(const char*));
varXString = varScriptStringList->strings; varXString = varScriptStringList->strings;
@ -175,7 +175,7 @@ void ContentLoader::Load()
if (assetList.assets != nullptr) if (assetList.assets != nullptr)
{ {
assert(assetList.assets == PTR_FOLLOWING); assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING);
assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset)); assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset));
varXAsset = assetList.assets; varXAsset = assetList.assets;

View File

@ -63,15 +63,15 @@ namespace
{ {
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type) #define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF #undef XBLOCK_DEF
} }
@ -191,7 +191,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
}, },
32u, 32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK)); ZoneConstants::INSERT_BLOCK,
zonePtr->Memory()));
return zoneLoader; return zoneLoader;
} }

View File

@ -55,7 +55,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
if (varScriptStringList->strings != nullptr) if (varScriptStringList->strings != nullptr)
{ {
assert(varScriptStringList->strings == PTR_FOLLOWING); assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING);
varScriptStringList->strings = m_stream.Alloc<const char*>(alignof(const char*)); varScriptStringList->strings = m_stream.Alloc<const char*>(alignof(const char*));
varXString = varScriptStringList->strings; varXString = varScriptStringList->strings;
@ -159,7 +159,7 @@ void ContentLoader::Load()
if (assetList.assets != nullptr) if (assetList.assets != nullptr)
{ {
assert(assetList.assets == PTR_FOLLOWING); assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING);
assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset)); assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset));
varXAsset = assetList.assets; varXAsset = assetList.assets;

View File

@ -46,13 +46,13 @@ namespace
{ {
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type) #define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF #undef XBLOCK_DEF
} }
@ -92,7 +92,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
}, },
32u, 32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK)); ZoneConstants::INSERT_BLOCK,
zonePtr->Memory()));
return zoneLoader; return zoneLoader;
} }

View File

@ -71,7 +71,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
if (varScriptStringList->strings != nullptr) if (varScriptStringList->strings != nullptr)
{ {
assert(varScriptStringList->strings == PTR_FOLLOWING); assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING);
varScriptStringList->strings = m_stream.Alloc<const char*>(alignof(const char*)); varScriptStringList->strings = m_stream.Alloc<const char*>(alignof(const char*));
varXString = varScriptStringList->strings; varXString = varScriptStringList->strings;
@ -188,7 +188,7 @@ void ContentLoader::Load()
if (assetList.depends != nullptr) if (assetList.depends != nullptr)
{ {
assert(assetList.depends == PTR_FOLLOWING); assert(GetZonePointerType(assetList.depends) == ZonePointerType::FOLLOWING);
assetList.depends = m_stream.Alloc<const char*>(alignof(const char*)); assetList.depends = m_stream.Alloc<const char*>(alignof(const char*));
varXString = assetList.depends; varXString = assetList.depends;
@ -197,7 +197,7 @@ void ContentLoader::Load()
if (assetList.assets != nullptr) if (assetList.assets != nullptr)
{ {
assert(assetList.assets == PTR_FOLLOWING); assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING);
assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset)); assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset));
varXAsset = assetList.assets; varXAsset = assetList.assets;

View File

@ -93,14 +93,14 @@ namespace
{ {
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type) #define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlock::Type::BLOCK_TYPE_RUNTIME)); zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlock::Type::BLOCK_TYPE_RUNTIME)); zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlockType::BLOCK_TYPE_RUNTIME));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlock::Type::BLOCK_TYPE_DELAY)); zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlockType::BLOCK_TYPE_DELAY));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlock::Type::BLOCK_TYPE_DELAY)); zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlockType::BLOCK_TYPE_DELAY));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlock::Type::BLOCK_TYPE_NORMAL)); zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF #undef XBLOCK_DEF
} }
@ -210,7 +210,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
}, },
32u, 32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK)); ZoneConstants::INSERT_BLOCK,
zonePtr->Memory()));
if (isSecure) if (isSecure)
{ {

View File

@ -1,15 +1,22 @@
#include "ContentLoaderBase.h" #include "ContentLoaderBase.h"
#include <cassert> #include <cassert>
#include <cstdint>
const void* ContentLoaderBase::PTR_FOLLOWING = reinterpret_cast<void*>(-1); #include <limits>
const void* ContentLoaderBase::PTR_INSERT = reinterpret_cast<void*>(-2);
ContentLoaderBase::ContentLoaderBase(Zone& zone, ZoneInputStream& stream) ContentLoaderBase::ContentLoaderBase(Zone& zone, ZoneInputStream& stream)
: varXString(nullptr), : varXString(nullptr),
m_zone(zone), m_zone(zone),
m_memory(zone.Memory()), m_memory(zone.Memory()),
m_stream(stream) m_stream(stream),
// -1
m_zone_ptr_following(
reinterpret_cast<const void*>(std::numeric_limits<std::uintptr_t>::max() >> ((sizeof(std::uintptr_t) * 8u) - stream.GetPointerBitCount()))),
// -2
m_zone_ptr_insert(
reinterpret_cast<const void*>((std::numeric_limits<std::uintptr_t>::max() >> ((sizeof(std::uintptr_t) * 8u) - stream.GetPointerBitCount())) - 1u))
{ {
} }
@ -22,9 +29,9 @@ void ContentLoaderBase::LoadXString(const bool atStreamStart) const
if (*varXString != nullptr) if (*varXString != nullptr)
{ {
if (*varXString == PTR_FOLLOWING) if (GetZonePointerType(*varXString) == ZonePointerType::FOLLOWING)
{ {
*varXString = m_stream.Alloc<const char>(alignof(const char)); *varXString = m_stream.Alloc<const char>(1);
m_stream.LoadNullTerminated(const_cast<char*>(*varXString)); m_stream.LoadNullTerminated(const_cast<char*>(*varXString));
} }
else else
@ -39,7 +46,12 @@ void ContentLoaderBase::LoadXStringArray(const bool atStreamStart, const size_t
assert(varXString != nullptr); assert(varXString != nullptr);
if (atStreamStart) if (atStreamStart)
m_stream.Load<const char*>(varXString, count); {
const auto fill = m_stream.LoadWithFill(4u * count);
for (size_t index = 0; index < count; index++)
fill.FillPtr(varXString[index], 4u * index);
}
for (size_t index = 0; index < count; index++) for (size_t index = 0; index < count; index++)
{ {
@ -47,3 +59,13 @@ void ContentLoaderBase::LoadXStringArray(const bool atStreamStart, const size_t
varXString++; varXString++;
} }
} }
ZonePointerType ContentLoaderBase::GetZonePointerType(const void* zonePtr) const
{
if (zonePtr == m_zone_ptr_following)
return ZonePointerType::FOLLOWING;
if (zonePtr == m_zone_ptr_insert)
return ZonePointerType::INSERT;
return ZonePointerType::OFFSET;
}

View File

@ -3,12 +3,17 @@
#include "Zone/Stream/ZoneInputStream.h" #include "Zone/Stream/ZoneInputStream.h"
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include <cstdint>
enum class ZonePointerType : std::uint8_t
{
FOLLOWING,
INSERT,
OFFSET
};
class ContentLoaderBase class ContentLoaderBase
{ {
protected:
static const void* PTR_FOLLOWING;
static const void* PTR_INSERT;
public: public:
virtual ~ContentLoaderBase() = default; virtual ~ContentLoaderBase() = default;
ContentLoaderBase(const ContentLoaderBase& other) = default; ContentLoaderBase(const ContentLoaderBase& other) = default;
@ -22,9 +27,20 @@ protected:
void LoadXString(bool atStreamStart) const; void LoadXString(bool atStreamStart) const;
void LoadXStringArray(bool atStreamStart, size_t count); void LoadXStringArray(bool atStreamStart, size_t count);
[[nodiscard]] ZonePointerType GetZonePointerType(const void* zonePtr) const;
template<typename T> [[nodiscard]] ZonePointerType GetZonePointerType(T* zonePtr) const
{
return GetZonePointerType(reinterpret_cast<const void*>(zonePtr));
}
const char** varXString; const char** varXString;
Zone& m_zone; Zone& m_zone;
MemoryManager& m_memory; MemoryManager& m_memory;
ZoneInputStream& m_stream; ZoneInputStream& m_stream;
private:
const void* m_zone_ptr_following;
const void* m_zone_ptr_insert;
}; };

View File

@ -0,0 +1,19 @@
#include "InvalidAliasLookupException.h"
#include <format>
InvalidAliasLookupException::InvalidAliasLookupException(const size_t lookupIndex, const size_t lookupCount)
: m_lookup_index(lookupIndex),
m_lookup_count(lookupCount)
{
}
std::string InvalidAliasLookupException::DetailedMessage()
{
return std::format("Tried to resolve zone alias lookup {} when there are only {} entries in the lookup", m_lookup_index, m_lookup_count);
}
char const* InvalidAliasLookupException::what() const noexcept
{
return "Tried to resolve invalid zone alias lookup";
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "LoadingException.h"
#include "Zone/XBlock.h"
class InvalidAliasLookupException final : public LoadingException
{
public:
InvalidAliasLookupException(size_t lookupIndex, size_t lookupCount);
std::string DetailedMessage() override;
[[nodiscard]] char const* what() const noexcept override;
private:
size_t m_lookup_index;
size_t m_lookup_count;
};

View File

@ -4,7 +4,7 @@
namespace namespace
{ {
constexpr uint64_t MAX_XBLOCK_SIZE = 0x3C000000; constexpr uint64_t MAX_XBLOCK_SIZE = 0x3C000000; // ~1GB
class StepAllocXBlocks final : public ILoadingStep class StepAllocXBlocks final : public ILoadingStep
{ {

View File

@ -10,17 +10,20 @@ namespace
StepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory, StepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
const unsigned pointerBitCount, const unsigned pointerBitCount,
const unsigned offsetBlockBitCount, const unsigned offsetBlockBitCount,
const block_t insertBlock) const block_t insertBlock,
MemoryManager& memory)
: m_entry_point_factory(std::move(entryPointFactory)), : m_entry_point_factory(std::move(entryPointFactory)),
m_pointer_bit_count(pointerBitCount), m_pointer_bit_count(pointerBitCount),
m_offset_block_bit_count(offsetBlockBitCount), m_offset_block_bit_count(offsetBlockBitCount),
m_insert_block(insertBlock) m_insert_block(insertBlock),
m_memory(memory)
{ {
} }
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
{ {
const auto inputStream = ZoneInputStream::Create(m_pointer_bit_count, m_offset_block_bit_count, zoneLoader.m_blocks, m_insert_block, stream); const auto inputStream =
ZoneInputStream::Create(m_pointer_bit_count, m_offset_block_bit_count, zoneLoader.m_blocks, m_insert_block, stream, m_memory);
const auto entryPoint = m_entry_point_factory(*inputStream); const auto entryPoint = m_entry_point_factory(*inputStream);
assert(entryPoint); assert(entryPoint);
@ -33,6 +36,7 @@ namespace
unsigned m_pointer_bit_count; unsigned m_pointer_bit_count;
unsigned m_offset_block_bit_count; unsigned m_offset_block_bit_count;
block_t m_insert_block; block_t m_insert_block;
MemoryManager& m_memory;
}; };
} // namespace } // namespace
@ -41,8 +45,9 @@ namespace step
std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory, std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
const unsigned pointerBitCount, const unsigned pointerBitCount,
const unsigned offsetBlockBitCount, const unsigned offsetBlockBitCount,
const block_t insertBlock) const block_t insertBlock,
MemoryManager& memory)
{ {
return std::make_unique<StepLoadZoneContent>(std::move(entryPointFactory), pointerBitCount, offsetBlockBitCount, insertBlock); return std::make_unique<StepLoadZoneContent>(std::move(entryPointFactory), pointerBitCount, offsetBlockBitCount, insertBlock, memory);
} }
} // namespace step } // namespace step

View File

@ -12,5 +12,6 @@ namespace step
std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory, std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
unsigned pointerBitCount, unsigned pointerBitCount,
unsigned offsetBlockBitCount, unsigned offsetBlockBitCount,
block_t insertBlock); block_t insertBlock,
MemoryManager& memory);
} }

View File

@ -1,6 +1,7 @@
#include "ZoneInputStream.h" #include "ZoneInputStream.h"
#include "Loading/Exception/BlockOverflowException.h" #include "Loading/Exception/BlockOverflowException.h"
#include "Loading/Exception/InvalidAliasLookupException.h"
#include "Loading/Exception/InvalidOffsetBlockException.h" #include "Loading/Exception/InvalidOffsetBlockException.h"
#include "Loading/Exception/InvalidOffsetBlockOffsetException.h" #include "Loading/Exception/InvalidOffsetBlockOffsetException.h"
#include "Loading/Exception/OutOfBlockBoundsException.h" #include "Loading/Exception/OutOfBlockBoundsException.h"
@ -10,17 +11,33 @@
#include <cstring> #include <cstring>
#include <stack> #include <stack>
ZoneStreamFillReadAccessor::ZoneStreamFillReadAccessor(const void* buffer, const size_t bufferSize, const unsigned pointerByteCount) ZoneStreamFillReadAccessor::ZoneStreamFillReadAccessor(const void* dataBuffer, void* blockBuffer, const size_t bufferSize, const unsigned pointerByteCount)
: m_buffer(buffer), : m_data_buffer(dataBuffer),
m_block_buffer(blockBuffer),
m_buffer_size(bufferSize), m_buffer_size(bufferSize),
m_pointer_byte_count(pointerByteCount) m_pointer_byte_count(pointerByteCount)
{ {
// Otherwise we cannot insert alias
assert(m_pointer_byte_count <= sizeof(uintptr_t));
} }
ZoneStreamFillReadAccessor ZoneStreamFillReadAccessor::AtOffset(const size_t offset) const ZoneStreamFillReadAccessor ZoneStreamFillReadAccessor::AtOffset(const size_t offset) const
{ {
assert(offset < m_buffer_size); assert(offset < m_buffer_size);
return ZoneStreamFillReadAccessor(static_cast<const char*>(m_buffer) + offset, m_buffer_size - offset, m_pointer_byte_count); return ZoneStreamFillReadAccessor(
static_cast<const char*>(m_data_buffer) + offset, static_cast<char*>(m_block_buffer) + offset, m_buffer_size - offset, m_pointer_byte_count);
}
void ZoneStreamFillReadAccessor::InsertPointerRedirect(const uintptr_t aliasValue, const size_t offset) const
{
// Memory should be zero by default
if (aliasValue == 0)
return;
assert(offset < m_buffer_size);
assert(m_block_buffer);
std::memcpy(static_cast<char*>(m_block_buffer) + offset, &aliasValue, m_pointer_byte_count);
} }
namespace namespace
@ -28,12 +45,19 @@ namespace
class XBlockInputStream final : public ZoneInputStream class XBlockInputStream final : public ZoneInputStream
{ {
public: public:
XBlockInputStream( XBlockInputStream(const unsigned pointerBitCount,
const unsigned pointerBitCount, const unsigned blockBitCount, std::vector<XBlock*>& blocks, const block_t insertBlock, ILoadingStream& stream) const unsigned blockBitCount,
std::vector<XBlock*>& blocks,
const block_t insertBlock,
ILoadingStream& stream,
MemoryManager& memory)
: m_blocks(blocks), : m_blocks(blocks),
m_stream(stream), m_stream(stream),
m_memory(memory),
m_pointer_byte_count(pointerBitCount / 8u), m_pointer_byte_count(pointerBitCount / 8u),
m_block_bit_count(blockBitCount) m_block_mask((std::numeric_limits<uintptr_t>::max() >> (sizeof(uintptr_t) * 8 - blockBitCount)) << (pointerBitCount - blockBitCount)),
m_block_shift(pointerBitCount - blockBitCount),
m_offset_mask(std::numeric_limits<uintptr_t>::max() >> (sizeof(uintptr_t) * 8 - (pointerBitCount - blockBitCount)))
{ {
assert(pointerBitCount % 8u == 0u); assert(pointerBitCount % 8u == 0u);
assert(insertBlock < static_cast<block_t>(blocks.size())); assert(insertBlock < static_cast<block_t>(blocks.size()));
@ -45,6 +69,11 @@ namespace
m_insert_block = blocks[insertBlock]; m_insert_block = blocks[insertBlock];
} }
[[nodiscard]] unsigned GetPointerBitCount() const override
{
return m_pointer_byte_count * 8u;
}
void PushBlock(const block_t block) override void PushBlock(const block_t block) override
{ {
assert(block < static_cast<block_t>(m_blocks.size())); assert(block < static_cast<block_t>(m_blocks.size()));
@ -54,7 +83,7 @@ namespace
m_block_stack.push(newBlock); m_block_stack.push(newBlock);
if (newBlock->m_type == XBlock::Type::BLOCK_TYPE_TEMP) if (newBlock->m_type == XBlockType::BLOCK_TYPE_TEMP)
m_temp_offsets.push(m_block_offsets[newBlock->m_index]); m_temp_offsets.push(m_block_offsets[newBlock->m_index]);
} }
@ -70,7 +99,7 @@ namespace
m_block_stack.pop(); m_block_stack.pop();
// If the temp block is not used anymore right now, reset it to the buffer start since as the name suggests, the data inside is temporary. // If the temp block is not used anymore right now, reset it to the buffer start since as the name suggests, the data inside is temporary.
if (poppedBlock->m_type == XBlock::Type::BLOCK_TYPE_TEMP) if (poppedBlock->m_type == XBlockType::BLOCK_TYPE_TEMP)
{ {
m_block_offsets[poppedBlock->m_index] = m_temp_offsets.top(); m_block_offsets[poppedBlock->m_index] = m_temp_offsets.top();
m_temp_offsets.pop(); m_temp_offsets.pop();
@ -96,6 +125,23 @@ namespace
return &block->m_buffer[m_block_offsets[block->m_index]]; return &block->m_buffer[m_block_offsets[block->m_index]];
} }
void* AllocOutOfBlock(const unsigned align, const size_t size) override
{
assert(!m_block_stack.empty());
if (m_block_stack.empty())
return nullptr;
auto* block = m_block_stack.top();
Align(align);
if (m_block_offsets[block->m_index] > block->m_buffer_size)
throw BlockOverflowException(block);
return m_memory.AllocRaw(size);
}
void LoadDataRaw(void* dst, const size_t size) override void LoadDataRaw(void* dst, const size_t size) override
{ {
m_stream.Load(dst, size); m_stream.Load(dst, size);
@ -108,10 +154,10 @@ namespace
{ {
auto* block = m_block_stack.top(); auto* block = m_block_stack.top();
if (block->m_buffer > dst || block->m_buffer + block->m_buffer_size < dst) if (block->m_buffer.get() > dst || block->m_buffer.get() + block->m_buffer_size < dst)
throw OutOfBlockBoundsException(block); throw OutOfBlockBoundsException(block);
if (static_cast<uint8_t*>(dst) + size > block->m_buffer + block->m_buffer_size) if (static_cast<uint8_t*>(dst) + size > block->m_buffer.get() + block->m_buffer_size)
throw BlockOverflowException(block); throw BlockOverflowException(block);
// Theoretically ptr should always be at the current block offset. // Theoretically ptr should always be at the current block offset.
@ -119,16 +165,16 @@ namespace
switch (block->m_type) switch (block->m_type)
{ {
case XBlock::Type::BLOCK_TYPE_TEMP: case XBlockType::BLOCK_TYPE_TEMP:
case XBlock::Type::BLOCK_TYPE_NORMAL: case XBlockType::BLOCK_TYPE_NORMAL:
m_stream.Load(dst, size); m_stream.Load(dst, size);
break; break;
case XBlock::Type::BLOCK_TYPE_RUNTIME: case XBlockType::BLOCK_TYPE_RUNTIME:
std::memset(dst, 0, size); std::memset(dst, 0, size);
break; break;
case XBlock::Type::BLOCK_TYPE_DELAY: case XBlockType::BLOCK_TYPE_DELAY:
assert(false); assert(false);
break; break;
} }
@ -150,14 +196,14 @@ namespace
auto* block = m_block_stack.top(); auto* block = m_block_stack.top();
if (block->m_buffer > dst || block->m_buffer + block->m_buffer_size < dst) if (block->m_buffer.get() > dst || block->m_buffer.get() + block->m_buffer_size < dst)
throw OutOfBlockBoundsException(block); throw OutOfBlockBoundsException(block);
// Theoretically ptr should always be at the current block offset. // Theoretically ptr should always be at the current block offset.
assert(dst == &block->m_buffer[m_block_offsets[block->m_index]]); assert(dst == &block->m_buffer[m_block_offsets[block->m_index]]);
uint8_t byte; uint8_t byte;
auto offset = static_cast<size_t>(static_cast<uint8_t*>(dst) - block->m_buffer); auto offset = static_cast<size_t>(static_cast<uint8_t*>(dst) - block->m_buffer.get());
do do
{ {
if (offset >= block->m_buffer_size) if (offset >= block->m_buffer_size)
@ -179,33 +225,34 @@ namespace
if (!m_block_stack.empty()) if (!m_block_stack.empty())
{ {
const auto* block = m_block_stack.top(); const auto* block = m_block_stack.top();
auto* blockBufferForFill = &block->m_buffer[m_block_offsets[block->m_index]];
switch (block->m_type) switch (block->m_type)
{ {
case XBlock::Type::BLOCK_TYPE_TEMP: case XBlockType::BLOCK_TYPE_TEMP:
case XBlock::Type::BLOCK_TYPE_NORMAL: case XBlockType::BLOCK_TYPE_NORMAL:
m_stream.Load(dst, size); m_stream.Load(dst, size);
break; break;
case XBlock::Type::BLOCK_TYPE_RUNTIME: case XBlockType::BLOCK_TYPE_RUNTIME:
std::memset(dst, 0, size); std::memset(dst, 0, size);
break; break;
case XBlock::Type::BLOCK_TYPE_DELAY: case XBlockType::BLOCK_TYPE_DELAY:
assert(false); assert(false);
break; break;
} }
IncBlockPos(size); IncBlockPos(size);
}
else return ZoneStreamFillReadAccessor(dst, blockBufferForFill, size, m_pointer_byte_count);
{
m_stream.Load(dst, size);
} }
return ZoneStreamFillReadAccessor(dst, size, m_pointer_byte_count); m_stream.Load(dst, size);
return ZoneStreamFillReadAccessor(dst, nullptr, size, m_pointer_byte_count);
} }
void* InsertPointer() override void* InsertPointerNative() override
{ {
m_block_stack.push(m_insert_block); m_block_stack.push(m_insert_block);
@ -224,14 +271,46 @@ namespace
return ptr; return ptr;
} }
uintptr_t InsertPointerAliasLookup() override
{
m_block_stack.push(m_insert_block);
// Alignment of pointer should always be its size
Align(m_pointer_byte_count);
if (m_block_offsets[m_insert_block->m_index] + m_pointer_byte_count > m_insert_block->m_buffer_size)
throw BlockOverflowException(m_insert_block);
auto* ptr = static_cast<void*>(&m_insert_block->m_buffer[m_block_offsets[m_insert_block->m_index]]);
IncBlockPos(m_pointer_byte_count);
m_block_stack.pop();
const auto newLookupIndex = static_cast<uintptr_t>(m_alias_lookup.size()) + 1;
m_alias_lookup.emplace_back(nullptr);
std::memcpy(ptr, &newLookupIndex, m_pointer_byte_count);
return newLookupIndex;
}
void SetInsertedPointerAliasLookup(const uintptr_t lookupEntry, void* value) override
{
assert(lookupEntry > 0);
assert(lookupEntry <= m_alias_lookup.size());
m_alias_lookup[lookupEntry - 1] = value;
}
void* ConvertOffsetToPointerNative(const void* offset) override void* ConvertOffsetToPointerNative(const void* offset) override
{ {
// -1 because otherwise Block 0 Offset 0 would be just 0 which is already used to signalize a nullptr. // -1 because otherwise Block 0 Offset 0 would be just 0 which is already used to signalize a nullptr.
// So all offsets are moved by 1. // So all offsets are moved by 1.
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u; const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
const auto blockNum = static_cast<block_t>(offsetInt >> (sizeof(offsetInt) * 8u - m_block_bit_count)); const auto blockNum = static_cast<block_t>((offsetInt & m_block_mask) >> m_block_shift);
const auto blockOffset = static_cast<size_t>(offsetInt & (UINTPTR_MAX >> m_block_bit_count)); const auto blockOffset = static_cast<size_t>(offsetInt & m_offset_mask);
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size())) if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
throw InvalidOffsetBlockException(blockNum); throw InvalidOffsetBlockException(blockNum);
@ -249,8 +328,8 @@ namespace
// For details see ConvertOffsetToPointer // For details see ConvertOffsetToPointer
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u; const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
const auto blockNum = static_cast<block_t>(offsetInt >> (sizeof(offsetInt) * 8u - m_block_bit_count)); const auto blockNum = static_cast<block_t>((offsetInt & m_block_mask) >> m_block_shift);
const auto blockOffset = static_cast<size_t>(offsetInt & (UINTPTR_MAX >> m_block_bit_count)); const auto blockOffset = static_cast<size_t>(offsetInt & m_offset_mask);
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size())) if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
throw InvalidOffsetBlockException(blockNum); throw InvalidOffsetBlockException(blockNum);
@ -263,6 +342,73 @@ namespace
return *reinterpret_cast<void**>(&block->m_buffer[blockOffset]); return *reinterpret_cast<void**>(&block->m_buffer[blockOffset]);
} }
uintptr_t AllocRedirectEntry(void** alias) override
{
// nullptr is always lookup alias 0
if (*alias == nullptr)
return 0;
const auto newIndex = m_pointer_redirect_lookup.size();
m_pointer_redirect_lookup.emplace_back(alias);
return static_cast<uintptr_t>(newIndex + 1);
}
void* ConvertOffsetToPointerRedirect(const void* offset) override
{
// For details see ConvertOffsetToPointer
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
const auto blockNum = static_cast<block_t>((offsetInt & m_block_mask) >> m_block_shift);
const auto blockOffset = static_cast<size_t>(offsetInt & m_offset_mask);
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
throw InvalidOffsetBlockException(blockNum);
auto* block = m_blocks[blockNum];
if (block->m_buffer_size <= blockOffset + sizeof(void*))
throw InvalidOffsetBlockOffsetException(block, blockOffset);
uintptr_t lookupEntry = 0u;
std::memcpy(&lookupEntry, &block->m_buffer[blockOffset], m_pointer_byte_count);
if (lookupEntry == 0)
return nullptr;
if (lookupEntry > m_pointer_redirect_lookup.size())
throw InvalidAliasLookupException(lookupEntry - 1, m_pointer_redirect_lookup.size());
return *m_pointer_redirect_lookup[lookupEntry - 1];
}
void* ConvertOffsetToAliasLookup(const void* offset) override
{
// For details see ConvertOffsetToPointer
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
const auto blockNum = static_cast<block_t>((offsetInt & m_block_mask) >> m_block_shift);
const auto blockOffset = static_cast<size_t>(offsetInt & m_offset_mask);
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
throw InvalidOffsetBlockException(blockNum);
auto* block = m_blocks[blockNum];
if (block->m_buffer_size <= blockOffset + sizeof(void*))
throw InvalidOffsetBlockOffsetException(block, blockOffset);
uintptr_t lookupEntry = 0u;
std::memcpy(&lookupEntry, &block->m_buffer[blockOffset], m_pointer_byte_count);
if (lookupEntry == 0)
return nullptr;
if (lookupEntry > m_alias_lookup.size())
throw InvalidAliasLookupException(lookupEntry - 1, m_alias_lookup.size());
return m_alias_lookup[lookupEntry - 1];
}
private: private:
void IncBlockPos(const size_t size) void IncBlockPos(const size_t size)
{ {
@ -293,16 +439,26 @@ namespace
std::stack<size_t> m_temp_offsets; std::stack<size_t> m_temp_offsets;
ILoadingStream& m_stream; ILoadingStream& m_stream;
MemoryManager& m_memory;
unsigned m_pointer_byte_count; unsigned m_pointer_byte_count;
unsigned m_block_bit_count; uintptr_t m_block_mask;
unsigned m_block_shift;
uintptr_t m_offset_mask;
XBlock* m_insert_block; XBlock* m_insert_block;
std::vector<uint8_t> m_fill_buffer; std::vector<uint8_t> m_fill_buffer;
std::vector<void**> m_pointer_redirect_lookup;
std::vector<void*> m_alias_lookup;
}; };
} // namespace } // namespace
std::unique_ptr<ZoneInputStream> ZoneInputStream::Create( std::unique_ptr<ZoneInputStream> ZoneInputStream::Create(const unsigned pointerBitCount,
const unsigned pointerBitCount, const unsigned blockBitCount, std::vector<XBlock*>& blocks, const block_t insertBlock, ILoadingStream& stream) const unsigned blockBitCount,
std::vector<XBlock*>& blocks,
const block_t insertBlock,
ILoadingStream& stream,
MemoryManager& memory)
{ {
return std::make_unique<XBlockInputStream>(pointerBitCount, blockBitCount, blocks, insertBlock, stream); return std::make_unique<XBlockInputStream>(pointerBitCount, blockBitCount, blocks, insertBlock, stream, memory);
} }

View File

@ -1,17 +1,19 @@
#pragma once #pragma once
#include "Loading/ILoadingStream.h" #include "Loading/ILoadingStream.h"
#include "Utils/MemoryManager.h"
#include "Zone/Stream/IZoneStream.h" #include "Zone/Stream/IZoneStream.h"
#include "Zone/XBlock.h" #include "Zone/XBlock.h"
#include <cassert> #include <cassert>
#include <cstring>
#include <memory> #include <memory>
#include <vector> #include <vector>
class ZoneStreamFillReadAccessor class ZoneStreamFillReadAccessor
{ {
public: public:
ZoneStreamFillReadAccessor(const void* buffer, size_t bufferSize, unsigned pointerByteCount); ZoneStreamFillReadAccessor(const void* dataBuffer, void* blockBuffer, size_t bufferSize, unsigned pointerByteCount);
[[nodiscard]] ZoneStreamFillReadAccessor AtOffset(size_t offset) const; [[nodiscard]] ZoneStreamFillReadAccessor AtOffset(size_t offset) const;
@ -19,14 +21,14 @@ public:
{ {
assert(offset + sizeof(T) <= m_buffer_size); assert(offset + sizeof(T) <= m_buffer_size);
value = *reinterpret_cast<const T*>(static_cast<const char*>(m_buffer) + offset); value = *reinterpret_cast<const T*>(static_cast<const char*>(m_data_buffer) + offset);
} }
template<typename T> void FillArray(T* value, const size_t offset, const size_t arraySize) const template<typename T, size_t S> void FillArray(T (&value)[S], const size_t offset) const
{ {
assert(offset + sizeof(T) * arraySize <= m_buffer_size); assert(offset + sizeof(T) * S <= m_buffer_size);
std::memcpy(value, static_cast<const char*>(m_buffer) + offset, sizeof(T) * arraySize); std::memcpy(value, static_cast<const char*>(m_data_buffer) + offset, sizeof(T) * S);
} }
template<typename T> void FillPtr(T*& value, const size_t offset) const template<typename T> void FillPtr(T*& value, const size_t offset) const
@ -35,11 +37,14 @@ public:
assert(m_pointer_byte_count <= sizeof(uintptr_t)); assert(m_pointer_byte_count <= sizeof(uintptr_t));
value = nullptr; value = nullptr;
std::memcpy(&value, static_cast<const char*>(m_buffer) + offset, m_pointer_byte_count); std::memcpy(&value, static_cast<const char*>(m_data_buffer) + offset, m_pointer_byte_count);
} }
void InsertPointerRedirect(uintptr_t aliasValue, size_t offset) const;
private: private:
const void* m_buffer; const void* m_data_buffer;
void* m_block_buffer;
size_t m_buffer_size; size_t m_buffer_size;
unsigned m_pointer_byte_count; unsigned m_pointer_byte_count;
}; };
@ -47,6 +52,11 @@ private:
class ZoneInputStream : public IZoneStream class ZoneInputStream : public IZoneStream
{ {
public: public:
/**
* \brief Returns the configured bits that make up a pointer.
*/
[[nodiscard]] virtual unsigned GetPointerBitCount() const = 0;
/** /**
* \brief Retrieves the new read position in the current block by aligning the position with the specified value and then returning the current read * \brief Retrieves the new read position in the current block by aligning the position with the specified value and then returning the current read
* position in the block. * position in the block.
@ -64,6 +74,16 @@ public:
return static_cast<T*>(Alloc(align)); return static_cast<T*>(Alloc(align));
} }
virtual void* AllocOutOfBlock(unsigned align, size_t size) = 0;
/**
* \copydoc ZoneInputStream#AllocOutOfBlock(unsigned)
*/
template<typename T> T* AllocOutOfBlock(const unsigned align, const size_t arraySize = 1u)
{
return static_cast<T*>(AllocOutOfBlock(align, sizeof(T) * arraySize));
}
/** /**
* \brief Loads data from the underlying stream without considering the current block or advancing the block position. * \brief Loads data from the underlying stream without considering the current block or advancing the block position.
* The data is read directly to the specified location instead of block memory. * The data is read directly to the specified location instead of block memory.
@ -99,13 +119,17 @@ public:
LoadDataInBlock(const_cast<void*>(reinterpret_cast<const void*>(dst)), size); LoadDataInBlock(const_cast<void*>(reinterpret_cast<const void*>(dst)), size);
} }
virtual void* InsertPointer() = 0; virtual void* InsertPointerNative() = 0;
template<typename T> T** InsertPointerNative() template<typename T> T** InsertPointerNative()
{ {
return static_cast<T**>(InsertPointer()); return static_cast<T**>(InsertPointerNative());
} }
virtual uintptr_t InsertPointerAliasLookup() = 0;
virtual void SetInsertedPointerAliasLookup(uintptr_t lookupEntry, void* value) = 0;
virtual void* ConvertOffsetToPointerNative(const void* offset) = 0; virtual void* ConvertOffsetToPointerNative(const void* offset) = 0;
template<typename T> T* ConvertOffsetToPointerNative(T* offset) template<typename T> T* ConvertOffsetToPointerNative(T* offset)
@ -120,6 +144,27 @@ public:
return static_cast<T*>(ConvertOffsetToAliasNative(static_cast<const void*>(offset))); return static_cast<T*>(ConvertOffsetToAliasNative(static_cast<const void*>(offset)));
} }
static std::unique_ptr<ZoneInputStream> virtual uintptr_t AllocRedirectEntry(void** alias) = 0;
Create(unsigned pointerBitCount, unsigned blockBitCount, std::vector<XBlock*>& blocks, block_t insertBlock, ILoadingStream& stream);
template<typename T> uintptr_t AllocRedirectEntry(T*& offset)
{
return AllocRedirectEntry(reinterpret_cast<void**>(&offset));
}
virtual void* ConvertOffsetToPointerRedirect(const void* offset) = 0;
template<typename T> T* ConvertOffsetToPointerRedirect(T* offset)
{
return static_cast<T*>(ConvertOffsetToPointerRedirect(static_cast<const void*>(offset)));
}
virtual void* ConvertOffsetToAliasLookup(const void* offset) = 0;
template<typename T> T* ConvertOffsetToAliasLookup(T* offset)
{
return static_cast<T*>(ConvertOffsetToAliasLookup(static_cast<const void*>(offset)));
}
static std::unique_ptr<ZoneInputStream> Create(
unsigned pointerBitCount, unsigned blockBitCount, std::vector<XBlock*>& blocks, block_t insertBlock, ILoadingStream& stream, MemoryManager& memory);
}; };

View File

@ -22,15 +22,15 @@ namespace
{ {
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type) #define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF #undef XBLOCK_DEF
} }

View File

@ -24,14 +24,14 @@ namespace
{ {
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type) #define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF #undef XBLOCK_DEF
} }

View File

@ -24,15 +24,15 @@ namespace
{ {
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type) #define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF #undef XBLOCK_DEF
} }

View File

@ -22,13 +22,13 @@ namespace
{ {
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type) #define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME)); writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF #undef XBLOCK_DEF
} }

View File

@ -29,14 +29,14 @@ namespace
{ {
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type) #define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP)); writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlock::Type::BLOCK_TYPE_RUNTIME)); writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlock::Type::BLOCK_TYPE_RUNTIME)); writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlockType::BLOCK_TYPE_RUNTIME));
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlock::Type::BLOCK_TYPE_DELAY)); writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlockType::BLOCK_TYPE_DELAY));
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlock::Type::BLOCK_TYPE_DELAY)); writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlockType::BLOCK_TYPE_DELAY));
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlock::Type::BLOCK_TYPE_NORMAL)); writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlockType::BLOCK_TYPE_NORMAL));
#undef XBLOCK_DEF #undef XBLOCK_DEF
} }

View File

@ -30,7 +30,7 @@ void InMemoryZoneOutputStream::PushBlock(const block_t block)
m_block_stack.push(newBlock); m_block_stack.push(newBlock);
if (newBlock->m_type == XBlock::Type::BLOCK_TYPE_TEMP) if (newBlock->m_type == XBlockType::BLOCK_TYPE_TEMP)
{ {
if (m_temp_sizes.empty()) if (m_temp_sizes.empty())
m_temp_sizes.push(0); m_temp_sizes.push(0);
@ -50,7 +50,7 @@ block_t InMemoryZoneOutputStream::PopBlock()
m_block_stack.pop(); m_block_stack.pop();
// If temp block is popped, see if its size is bigger than the current maximum temp size // If temp block is popped, see if its size is bigger than the current maximum temp size
if (poppedBlock->m_type == XBlock::Type::BLOCK_TYPE_TEMP) if (poppedBlock->m_type == XBlockType::BLOCK_TYPE_TEMP)
{ {
const auto tempSize = m_temp_sizes.top(); const auto tempSize = m_temp_sizes.top();
m_temp_sizes.pop(); m_temp_sizes.pop();
@ -70,7 +70,7 @@ void InMemoryZoneOutputStream::Align(const int align)
{ {
auto* block = m_block_stack.top(); auto* block = m_block_stack.top();
if (block->m_type == XBlock::Type::BLOCK_TYPE_TEMP) if (block->m_type == XBlockType::BLOCK_TYPE_TEMP)
m_temp_sizes.top() = (m_temp_sizes.top() + align - 1) / align * align; m_temp_sizes.top() = (m_temp_sizes.top() + align - 1) / align * align;
else else
block->m_buffer_size = (block->m_buffer_size + align - 1) / align * align; block->m_buffer_size = (block->m_buffer_size + align - 1) / align * align;
@ -96,16 +96,16 @@ void* InMemoryZoneOutputStream::WriteDataInBlock(const void* src, const size_t s
void* result = nullptr; void* result = nullptr;
switch (block->m_type) switch (block->m_type)
{ {
case XBlock::Type::BLOCK_TYPE_TEMP: case XBlockType::BLOCK_TYPE_TEMP:
case XBlock::Type::BLOCK_TYPE_NORMAL: case XBlockType::BLOCK_TYPE_NORMAL:
result = m_zone_data->GetBufferOfSize(size); result = m_zone_data->GetBufferOfSize(size);
memcpy(result, src, size); memcpy(result, src, size);
break; break;
case XBlock::Type::BLOCK_TYPE_RUNTIME: case XBlockType::BLOCK_TYPE_RUNTIME:
break; break;
case XBlock::Type::BLOCK_TYPE_DELAY: case XBlockType::BLOCK_TYPE_DELAY:
assert(false); assert(false);
break; break;
} }
@ -122,7 +122,7 @@ void InMemoryZoneOutputStream::IncBlockPos(const size_t size)
return; return;
auto* block = m_block_stack.top(); auto* block = m_block_stack.top();
if (block->m_type == XBlock::Type::BLOCK_TYPE_TEMP) if (block->m_type == XBlockType::BLOCK_TYPE_TEMP)
{ {
m_temp_sizes.top() += size; m_temp_sizes.top() += size;
} }
@ -141,7 +141,7 @@ void InMemoryZoneOutputStream::WriteNullTerminated(const void* src)
uintptr_t InMemoryZoneOutputStream::GetCurrentZonePointer() uintptr_t InMemoryZoneOutputStream::GetCurrentZonePointer()
{ {
assert(!m_block_stack.empty()); assert(!m_block_stack.empty());
assert(m_block_stack.top()->m_type == XBlock::Type::BLOCK_TYPE_NORMAL); assert(m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_NORMAL);
uintptr_t ptr = 0; uintptr_t ptr = 0;
ptr |= static_cast<uintptr_t>(m_block_stack.top()->m_index) << (sizeof(uintptr_t) * 8 - m_block_bit_count); ptr |= static_cast<uintptr_t>(m_block_stack.top()->m_index) << (sizeof(uintptr_t) * 8 - m_block_bit_count);
@ -168,7 +168,7 @@ void InMemoryZoneOutputStream::MarkFollowing(void** pPtr)
{ {
assert(!m_block_stack.empty()); assert(!m_block_stack.empty());
assert(pPtr != nullptr); assert(pPtr != nullptr);
*pPtr = m_block_stack.top()->m_type == XBlock::Type::BLOCK_TYPE_TEMP ? PTR_INSERT : PTR_FOLLOWING; *pPtr = m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_TEMP ? PTR_INSERT : PTR_FOLLOWING;
} }
bool InMemoryZoneOutputStream::ReusableShouldWrite(void** pPtr, const size_t entrySize, const std::type_index type) bool InMemoryZoneOutputStream::ReusableShouldWrite(void** pPtr, const size_t entrySize, const std::type_index type)
@ -202,7 +202,7 @@ void InMemoryZoneOutputStream::ReusableAddOffset(void* ptr, size_t size, size_t
{ {
assert(!m_block_stack.empty()); assert(!m_block_stack.empty());
const auto inTemp = m_block_stack.top()->m_type == XBlock::Type::BLOCK_TYPE_TEMP; const auto inTemp = m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_TEMP;
auto zoneOffset = inTemp ? InsertPointer() : GetCurrentZonePointer(); auto zoneOffset = inTemp ? InsertPointer() : GetCurrentZonePointer();
const auto foundEntriesForType = m_reusable_entries.find(type); const auto foundEntriesForType = m_reusable_entries.find(type);
if (foundEntriesForType == m_reusable_entries.end()) if (foundEntriesForType == m_reusable_entries.end())