mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-01-13 20:21:48 +00:00
refactor: return ZoneOutputOffset when writing via ZoneOutputStream
This commit is contained in:
@@ -60,15 +60,18 @@ void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (atStreamStart)
|
||||
varScriptStringList = m_stream->Write(varScriptStringList);
|
||||
varScriptStringListWritten = m_stream->Write(varScriptStringList);
|
||||
|
||||
if (varScriptStringList->strings != nullptr)
|
||||
{
|
||||
m_stream->Align(alignof(const char*));
|
||||
m_stream->Align(4);
|
||||
varXString = varScriptStringList->strings;
|
||||
WriteXStringArray(true, varScriptStringList->count);
|
||||
|
||||
m_stream->MarkFollowing(varScriptStringList->strings);
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(ScriptStringList, strings) == 4u);
|
||||
#endif
|
||||
m_stream->MarkFollowing(varScriptStringListWritten.WithInnerOffset(4));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
@@ -90,7 +93,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart)
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
varXAsset = m_stream->Write(varXAsset);
|
||||
varXAssetWritten = m_stream->Write(varXAsset);
|
||||
|
||||
switch (varXAsset->type)
|
||||
{
|
||||
@@ -137,12 +140,17 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
varXAsset = m_stream->Write(varXAsset, count);
|
||||
varXAssetWritten = m_stream->Write(varXAsset, count);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
WriteXAsset(false);
|
||||
varXAsset++;
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(sizeof(XAsset) == 8u);
|
||||
#endif
|
||||
varXAssetWritten.Inc(8u);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,17 +165,26 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream)
|
||||
|
||||
CreateXAssetList(assetList, memory);
|
||||
|
||||
varXAssetList = static_cast<XAssetList*>(m_stream->WriteDataRaw(&assetList, sizeof(assetList)));
|
||||
varXAssetList = &assetList;
|
||||
varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList));
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(XAssetList, stringList) == 0u);
|
||||
#endif
|
||||
varScriptStringList = &varXAssetList->stringList;
|
||||
varScriptStringListWritten = varXAssetListWritten.WithInnerOffset(0);
|
||||
WriteScriptStringList(false);
|
||||
|
||||
if (varXAssetList->assets != nullptr)
|
||||
{
|
||||
m_stream->Align(alignof(XAsset));
|
||||
m_stream->Align(4);
|
||||
varXAsset = varXAssetList->assets;
|
||||
WriteXAssetArray(true, varXAssetList->assetCount);
|
||||
m_stream->MarkFollowing(varXAssetList->assets);
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(XAssetList, assets) == 12u);
|
||||
#endif
|
||||
m_stream->MarkFollowing(varXAssetListWritten.WithInnerOffset(12));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
|
||||
@@ -24,5 +24,9 @@ namespace IW3
|
||||
XAssetList* varXAssetList;
|
||||
XAsset* varXAsset;
|
||||
ScriptStringList* varScriptStringList;
|
||||
|
||||
ZoneOutputOffset varXAssetListWritten;
|
||||
ZoneOutputOffset varXAssetWritten;
|
||||
ZoneOutputOffset varScriptStringListWritten;
|
||||
};
|
||||
} // namespace IW3
|
||||
|
||||
@@ -60,15 +60,18 @@ void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (atStreamStart)
|
||||
varScriptStringList = m_stream->Write(varScriptStringList);
|
||||
varScriptStringListWritten = m_stream->Write(varScriptStringList);
|
||||
|
||||
if (varScriptStringList->strings != nullptr)
|
||||
{
|
||||
m_stream->Align(alignof(const char*));
|
||||
m_stream->Align(4);
|
||||
varXString = varScriptStringList->strings;
|
||||
WriteXStringArray(true, varScriptStringList->count);
|
||||
|
||||
m_stream->MarkFollowing(varScriptStringList->strings);
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(ScriptStringList, strings) == 4u);
|
||||
#endif
|
||||
m_stream->MarkFollowing(varScriptStringListWritten.WithInnerOffset(4));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
@@ -90,7 +93,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart)
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
varXAsset = m_stream->Write(varXAsset);
|
||||
varXAssetWritten = m_stream->Write(varXAsset);
|
||||
|
||||
switch (varXAsset->type)
|
||||
{
|
||||
@@ -147,12 +150,17 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
varXAsset = m_stream->Write(varXAsset, count);
|
||||
varXAssetWritten = m_stream->Write(varXAsset, count);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
WriteXAsset(false);
|
||||
varXAsset++;
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(sizeof(XAsset) == 8u);
|
||||
#endif
|
||||
varXAssetWritten.Inc(8u);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,17 +175,26 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream)
|
||||
|
||||
CreateXAssetList(assetList, memory);
|
||||
|
||||
varXAssetList = static_cast<XAssetList*>(m_stream->WriteDataRaw(&assetList, sizeof(assetList)));
|
||||
varXAssetList = &assetList;
|
||||
varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList));
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(XAssetList, stringList) == 0u);
|
||||
#endif
|
||||
varScriptStringList = &varXAssetList->stringList;
|
||||
varScriptStringListWritten = varXAssetListWritten.WithInnerOffset(0);
|
||||
WriteScriptStringList(false);
|
||||
|
||||
if (varXAssetList->assets != nullptr)
|
||||
{
|
||||
m_stream->Align(alignof(XAsset));
|
||||
m_stream->Align(4);
|
||||
varXAsset = varXAssetList->assets;
|
||||
WriteXAssetArray(true, varXAssetList->assetCount);
|
||||
m_stream->MarkFollowing(varXAssetList->assets);
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(XAssetList, assets) == 12u);
|
||||
#endif
|
||||
m_stream->MarkFollowing(varXAssetListWritten.WithInnerOffset(12));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
|
||||
@@ -24,5 +24,9 @@ namespace IW4
|
||||
XAssetList* varXAssetList;
|
||||
XAsset* varXAsset;
|
||||
ScriptStringList* varScriptStringList;
|
||||
|
||||
ZoneOutputOffset varXAssetListWritten;
|
||||
ZoneOutputOffset varXAssetWritten;
|
||||
ZoneOutputOffset varScriptStringListWritten;
|
||||
};
|
||||
} // namespace IW4
|
||||
|
||||
@@ -60,15 +60,18 @@ void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (atStreamStart)
|
||||
varScriptStringList = m_stream->Write(varScriptStringList);
|
||||
varScriptStringListWritten = m_stream->Write(varScriptStringList);
|
||||
|
||||
if (varScriptStringList->strings != nullptr)
|
||||
{
|
||||
m_stream->Align(alignof(const char*));
|
||||
m_stream->Align(4);
|
||||
varXString = varScriptStringList->strings;
|
||||
WriteXStringArray(true, varScriptStringList->count);
|
||||
|
||||
m_stream->MarkFollowing(varScriptStringList->strings);
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(ScriptStringList, strings) == 4u);
|
||||
#endif
|
||||
m_stream->MarkFollowing(varScriptStringListWritten.WithInnerOffset(4));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
@@ -90,7 +93,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart)
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
varXAsset = m_stream->Write(varXAsset);
|
||||
varXAssetWritten = m_stream->Write(varXAsset);
|
||||
|
||||
switch (varXAsset->type)
|
||||
{
|
||||
@@ -150,12 +153,17 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
varXAsset = m_stream->Write(varXAsset, count);
|
||||
varXAssetWritten = m_stream->Write(varXAsset, count);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
WriteXAsset(false);
|
||||
varXAsset++;
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(sizeof(XAsset) == 8u);
|
||||
#endif
|
||||
varXAssetWritten.Inc(8u);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,17 +178,26 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream)
|
||||
|
||||
CreateXAssetList(assetList, memory);
|
||||
|
||||
varXAssetList = static_cast<XAssetList*>(m_stream->WriteDataRaw(&assetList, sizeof(assetList)));
|
||||
varXAssetList = &assetList;
|
||||
varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList));
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(XAssetList, stringList) == 0u);
|
||||
#endif
|
||||
varScriptStringList = &varXAssetList->stringList;
|
||||
varScriptStringListWritten = varXAssetListWritten.WithInnerOffset(0);
|
||||
WriteScriptStringList(false);
|
||||
|
||||
if (varXAssetList->assets != nullptr)
|
||||
{
|
||||
m_stream->Align(alignof(XAsset));
|
||||
m_stream->Align(4);
|
||||
varXAsset = varXAssetList->assets;
|
||||
WriteXAssetArray(true, varXAssetList->assetCount);
|
||||
m_stream->MarkFollowing(varXAssetList->assets);
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(XAssetList, assets) == 12u);
|
||||
#endif
|
||||
m_stream->MarkFollowing(varXAssetListWritten.WithInnerOffset(12));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
|
||||
@@ -24,5 +24,9 @@ namespace IW5
|
||||
XAssetList* varXAssetList;
|
||||
XAsset* varXAsset;
|
||||
ScriptStringList* varScriptStringList;
|
||||
|
||||
ZoneOutputOffset varXAssetListWritten;
|
||||
ZoneOutputOffset varXAssetWritten;
|
||||
ZoneOutputOffset varScriptStringListWritten;
|
||||
};
|
||||
} // namespace IW5
|
||||
|
||||
@@ -60,15 +60,18 @@ void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (atStreamStart)
|
||||
varScriptStringList = m_stream->Write(varScriptStringList);
|
||||
varScriptStringListWritten = m_stream->Write(varScriptStringList);
|
||||
|
||||
if (varScriptStringList->strings != nullptr)
|
||||
{
|
||||
m_stream->Align(alignof(const char*));
|
||||
m_stream->Align(4);
|
||||
varXString = varScriptStringList->strings;
|
||||
WriteXStringArray(true, varScriptStringList->count);
|
||||
|
||||
m_stream->MarkFollowing(varScriptStringList->strings);
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(ScriptStringList, strings) == 4u);
|
||||
#endif
|
||||
m_stream->MarkFollowing(varScriptStringListWritten.WithInnerOffset(4));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
@@ -90,7 +93,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart)
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
varXAsset = m_stream->Write(varXAsset);
|
||||
varXAssetWritten = m_stream->Write(varXAsset);
|
||||
|
||||
switch (varXAsset->type)
|
||||
{
|
||||
@@ -143,12 +146,17 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
varXAsset = m_stream->Write(varXAsset, count);
|
||||
varXAssetWritten = m_stream->Write(varXAsset, count);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
WriteXAsset(false);
|
||||
varXAsset++;
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(sizeof(XAsset) == 8u);
|
||||
#endif
|
||||
varXAssetWritten.Inc(8u);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,17 +171,26 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream)
|
||||
|
||||
CreateXAssetList(assetList, memory);
|
||||
|
||||
varXAssetList = static_cast<XAssetList*>(m_stream->WriteDataRaw(&assetList, sizeof(assetList)));
|
||||
varXAssetList = &assetList;
|
||||
varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList));
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(XAssetList, stringList) == 0u);
|
||||
#endif
|
||||
varScriptStringList = &varXAssetList->stringList;
|
||||
varScriptStringListWritten = varXAssetListWritten.WithInnerOffset(0);
|
||||
WriteScriptStringList(false);
|
||||
|
||||
if (varXAssetList->assets != nullptr)
|
||||
{
|
||||
m_stream->Align(alignof(XAsset));
|
||||
m_stream->Align(4);
|
||||
varXAsset = varXAssetList->assets;
|
||||
WriteXAssetArray(true, varXAssetList->assetCount);
|
||||
m_stream->MarkFollowing(varXAssetList->assets);
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(XAssetList, assets) == 12u);
|
||||
#endif
|
||||
m_stream->MarkFollowing(varXAssetListWritten.WithInnerOffset(12));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
|
||||
@@ -24,5 +24,9 @@ namespace T5
|
||||
XAssetList* varXAssetList;
|
||||
XAsset* varXAsset;
|
||||
ScriptStringList* varScriptStringList;
|
||||
|
||||
ZoneOutputOffset varXAssetListWritten;
|
||||
ZoneOutputOffset varXAssetWritten;
|
||||
ZoneOutputOffset varScriptStringListWritten;
|
||||
};
|
||||
} // namespace T5
|
||||
|
||||
@@ -63,15 +63,18 @@ void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (atStreamStart)
|
||||
varScriptStringList = m_stream->Write(varScriptStringList);
|
||||
varScriptStringListWritten = m_stream->Write(varScriptStringList);
|
||||
|
||||
if (varScriptStringList->strings != nullptr)
|
||||
{
|
||||
m_stream->Align(alignof(const char*));
|
||||
m_stream->Align(4);
|
||||
varXString = varScriptStringList->strings;
|
||||
WriteXStringArray(true, varScriptStringList->count);
|
||||
|
||||
m_stream->MarkFollowing(varScriptStringList->strings);
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(ScriptStringList, strings) == 4u);
|
||||
#endif
|
||||
m_stream->MarkFollowing(varScriptStringListWritten.WithInnerOffset(4));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
@@ -90,7 +93,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart)
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
varXAsset = m_stream->Write(varXAsset);
|
||||
varXAssetWritten = m_stream->Write(varXAsset);
|
||||
|
||||
switch (varXAsset->type)
|
||||
{
|
||||
@@ -158,12 +161,17 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
varXAsset = m_stream->Write(varXAsset, count);
|
||||
varXAssetWritten = m_stream->Write(varXAsset, count);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
WriteXAsset(false);
|
||||
varXAsset++;
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(sizeof(XAsset) == 8u);
|
||||
#endif
|
||||
varXAssetWritten.Inc(8u);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,25 +186,38 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream)
|
||||
|
||||
CreateXAssetList(assetList, memory);
|
||||
|
||||
varXAssetList = static_cast<XAssetList*>(m_stream->WriteDataRaw(&assetList, sizeof(assetList)));
|
||||
varXAssetList = &assetList;
|
||||
varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList));
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(XAssetList, stringList) == 0u);
|
||||
#endif
|
||||
varScriptStringList = &varXAssetList->stringList;
|
||||
varScriptStringListWritten = varXAssetListWritten.WithInnerOffset(0);
|
||||
WriteScriptStringList(false);
|
||||
|
||||
if (varXAssetList->depends != nullptr)
|
||||
{
|
||||
m_stream->Align(alignof(const char*));
|
||||
m_stream->Align(4);
|
||||
varXString = varXAssetList->depends;
|
||||
WriteXStringArray(true, varXAssetList->dependCount);
|
||||
m_stream->MarkFollowing(varXAssetList->depends);
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(XAssetList, depends) == 12u);
|
||||
#endif
|
||||
m_stream->MarkFollowing(varXAssetListWritten.WithInnerOffset(12));
|
||||
}
|
||||
|
||||
if (varXAssetList->assets != nullptr)
|
||||
{
|
||||
m_stream->Align(alignof(XAsset));
|
||||
m_stream->Align(4);
|
||||
varXAsset = varXAssetList->assets;
|
||||
WriteXAssetArray(true, varXAssetList->assetCount);
|
||||
m_stream->MarkFollowing(varXAssetList->assets);
|
||||
|
||||
#ifdef ARCH_x86
|
||||
static_assert(offsetof(XAssetList, assets) == 20u);
|
||||
#endif
|
||||
m_stream->MarkFollowing(varXAssetListWritten.WithInnerOffset(20));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
|
||||
@@ -24,5 +24,9 @@ namespace T6
|
||||
XAssetList* varXAssetList;
|
||||
XAsset* varXAsset;
|
||||
ScriptStringList* varScriptStringList;
|
||||
|
||||
ZoneOutputOffset varXAssetListWritten;
|
||||
ZoneOutputOffset varXAssetWritten;
|
||||
ZoneOutputOffset varScriptStringListWritten;
|
||||
};
|
||||
} // namespace T6
|
||||
|
||||
@@ -38,12 +38,13 @@ void AssetWriter::WriteScriptStringArray(const bool atStreamStart, const size_t
|
||||
varScriptStringWritten = m_stream->Write<scr_string_t>(varScriptString, count);
|
||||
}
|
||||
|
||||
assert(varScriptStringWritten != nullptr);
|
||||
assert(varScriptStringWritten.Offset() != nullptr);
|
||||
|
||||
auto* ptr = varScriptStringWritten;
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
*ptr = UseScriptString(*ptr);
|
||||
ptr++;
|
||||
*static_cast<scr_string_t*>(varScriptStringWritten.Offset()) = UseScriptString(*varScriptString);
|
||||
|
||||
varScriptString++;
|
||||
varScriptStringWritten.Inc(sizeof(scr_string_t));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,5 +17,5 @@ protected:
|
||||
XAssetInfoGeneric* m_asset;
|
||||
|
||||
scr_string_t* varScriptString;
|
||||
scr_string_t* varScriptStringWritten;
|
||||
ZoneOutputOffset varScriptStringWritten;
|
||||
};
|
||||
|
||||
@@ -26,15 +26,15 @@ void ContentWriterBase::WriteXString(const bool atStreamStart)
|
||||
varXStringWritten = m_stream->Write<const char*>(varXString);
|
||||
}
|
||||
|
||||
assert(varXStringWritten != nullptr);
|
||||
assert(varXStringWritten.Offset() != nullptr);
|
||||
|
||||
if (m_stream->ReusableShouldWrite(varXStringWritten))
|
||||
if (m_stream->ReusableShouldWrite(*varXString, varXStringWritten))
|
||||
{
|
||||
m_stream->Align(alignof(const char));
|
||||
m_stream->ReusableAddOffset(*varXStringWritten);
|
||||
m_stream->WriteNullTerminated(*varXStringWritten);
|
||||
m_stream->Align(1);
|
||||
m_stream->ReusableAddOffset(*varXString);
|
||||
m_stream->WriteNullTerminated(*varXString);
|
||||
|
||||
m_stream->MarkFollowing(*varXStringWritten);
|
||||
m_stream->MarkFollowing(varXStringWritten);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,12 @@ void ContentWriterBase::WriteXStringArray(const bool atStreamStart, const size_t
|
||||
varXStringWritten = m_stream->Write<const char*>(varXString, count);
|
||||
}
|
||||
|
||||
assert(varXStringWritten != nullptr);
|
||||
assert(varXStringWritten.Offset() != nullptr);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
WriteXString(false);
|
||||
varXStringWritten++;
|
||||
varXString++;
|
||||
varXStringWritten.Inc(m_stream->GetPointerByteCount());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,5 +24,5 @@ protected:
|
||||
ZoneOutputStream* m_stream;
|
||||
|
||||
const char** varXString;
|
||||
const char** varXStringWritten;
|
||||
ZoneOutputOffset varXStringWritten;
|
||||
};
|
||||
|
||||
@@ -44,7 +44,13 @@ namespace
|
||||
: m_zone_data(zoneData),
|
||||
m_blocks(blocks),
|
||||
m_block_bit_count(blockBitCount),
|
||||
m_pointer_byte_count(pointerBitCount / 8u)
|
||||
m_pointer_byte_count(pointerBitCount / 8u),
|
||||
|
||||
// -1
|
||||
m_zone_ptr_following(std::numeric_limits<std::uintptr_t>::max() >> ((sizeof(std::uintptr_t) * 8u) - pointerBitCount)),
|
||||
|
||||
// -2
|
||||
m_zone_ptr_insert((std::numeric_limits<std::uintptr_t>::max() >> ((sizeof(std::uintptr_t) * 8u) - pointerBitCount)) - 1u)
|
||||
{
|
||||
assert(pointerBitCount % 8u == 0u);
|
||||
assert(insertBlock < static_cast<block_t>(blocks.size()));
|
||||
@@ -52,9 +58,9 @@ namespace
|
||||
m_insert_block = blocks[insertBlock];
|
||||
}
|
||||
|
||||
[[nodiscard]] unsigned GetPointerBitCount() const override
|
||||
[[nodiscard]] unsigned GetPointerByteCount() const override
|
||||
{
|
||||
return m_pointer_byte_count * 8u;
|
||||
return m_pointer_byte_count;
|
||||
}
|
||||
|
||||
void PushBlock(const block_t block) override
|
||||
@@ -113,19 +119,20 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
void* WriteDataRaw(const void* src, const size_t size) override
|
||||
ZoneOutputOffset WriteDataRaw(const void* src, const size_t size) override
|
||||
{
|
||||
auto* result = m_zone_data.GetBufferOfSize(size);
|
||||
memcpy(result, src, size);
|
||||
return result;
|
||||
|
||||
return ZoneOutputOffset(result);
|
||||
}
|
||||
|
||||
void* WriteDataInBlock(const void* src, const size_t size) override
|
||||
ZoneOutputOffset WriteDataInBlock(const void* src, const size_t size) override
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return nullptr;
|
||||
return ZoneOutputOffset();
|
||||
|
||||
const auto* block = m_block_stack.top();
|
||||
|
||||
@@ -147,7 +154,8 @@ namespace
|
||||
}
|
||||
|
||||
IncBlockPos(size);
|
||||
return result;
|
||||
|
||||
return ZoneOutputOffset(result);
|
||||
}
|
||||
|
||||
void IncBlockPos(const size_t size) override
|
||||
@@ -174,19 +182,30 @@ namespace
|
||||
WriteDataInBlock(src, len + 1);
|
||||
}
|
||||
|
||||
void MarkFollowing(void** pPtr) override
|
||||
void MarkFollowing(const ZoneOutputOffset outputOffset) override
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
assert(pPtr != nullptr);
|
||||
*pPtr = m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_TEMP ? PTR_INSERT : PTR_FOLLOWING;
|
||||
|
||||
auto* ptr = static_cast<char*>(outputOffset.Offset());
|
||||
assert(ptr != nullptr);
|
||||
|
||||
if (m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
||||
{
|
||||
for (auto i = 0u; i < m_pointer_byte_count; i++)
|
||||
ptr[i] = reinterpret_cast<const char*>(&m_zone_ptr_insert)[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto i = 0u; i < m_pointer_byte_count; i++)
|
||||
ptr[i] = reinterpret_cast<const char*>(&m_zone_ptr_following)[i];
|
||||
}
|
||||
}
|
||||
|
||||
bool ReusableShouldWrite(void** pPtr, const size_t entrySize, const std::type_index type) override
|
||||
bool ReusableShouldWrite(void* ptr, const ZoneOutputOffset outputOffset, const size_t entrySize, const std::type_index type) override
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
assert(pPtr != nullptr);
|
||||
|
||||
if (*pPtr == nullptr)
|
||||
if (ptr == nullptr)
|
||||
return false;
|
||||
|
||||
const auto foundEntriesForType = m_reusable_entries.find(type);
|
||||
@@ -197,11 +216,14 @@ namespace
|
||||
|
||||
for (const auto& entry : foundEntriesForType->second)
|
||||
{
|
||||
if (*pPtr >= entry.m_start_ptr && *pPtr < entry.m_end_ptr)
|
||||
if (ptr >= entry.m_start_ptr && ptr < entry.m_end_ptr)
|
||||
{
|
||||
assert((reinterpret_cast<uintptr_t>(*pPtr) - reinterpret_cast<uintptr_t>(entry.m_start_ptr)) % entrySize == 0);
|
||||
*pPtr =
|
||||
reinterpret_cast<void*>(entry.m_start_zone_ptr + (reinterpret_cast<uintptr_t>(*pPtr) - reinterpret_cast<uintptr_t>(entry.m_start_ptr)));
|
||||
assert((reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(entry.m_start_ptr)) % entrySize == 0);
|
||||
const auto finalZonePointer = entry.m_start_zone_ptr + (reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(entry.m_start_ptr));
|
||||
|
||||
for (auto i = 0u; i < m_pointer_byte_count; i++)
|
||||
static_cast<char*>(ptr)[i] = reinterpret_cast<const char*>(&finalZonePointer)[i];
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -265,10 +287,38 @@ namespace
|
||||
unsigned m_pointer_byte_count;
|
||||
XBlock* m_insert_block;
|
||||
|
||||
uintptr_t m_zone_ptr_following;
|
||||
uintptr_t m_zone_ptr_insert;
|
||||
|
||||
std::unordered_map<std::type_index, std::vector<ReusableEntry>> m_reusable_entries;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
ZoneOutputOffset::ZoneOutputOffset()
|
||||
: m_offset(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ZoneOutputOffset::ZoneOutputOffset(void* offset)
|
||||
: m_offset(offset)
|
||||
{
|
||||
}
|
||||
|
||||
void* ZoneOutputOffset::Offset() const
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
void ZoneOutputOffset::Inc(const size_t size)
|
||||
{
|
||||
m_offset = static_cast<void*>(static_cast<char*>(m_offset) + size);
|
||||
}
|
||||
|
||||
ZoneOutputOffset ZoneOutputOffset::WithInnerOffset(const size_t innerOffset) const
|
||||
{
|
||||
return ZoneOutputOffset(static_cast<char*>(m_offset) + innerOffset);
|
||||
}
|
||||
|
||||
std::unique_ptr<ZoneOutputStream>
|
||||
ZoneOutputStream::Create(unsigned pointerBitCount, unsigned blockBitCount, std::vector<XBlock*>& blocks, block_t insertBlock, InMemoryZoneData& zoneData)
|
||||
{
|
||||
|
||||
@@ -10,13 +10,27 @@
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
class ZoneOutputOffset
|
||||
{
|
||||
public:
|
||||
ZoneOutputOffset();
|
||||
explicit ZoneOutputOffset(void* offset);
|
||||
|
||||
[[nodiscard]] void* Offset() const;
|
||||
void Inc(size_t size);
|
||||
[[nodiscard]] ZoneOutputOffset WithInnerOffset(size_t innerOffset) const;
|
||||
|
||||
private:
|
||||
void* m_offset;
|
||||
};
|
||||
|
||||
class ZoneOutputStream : public IZoneStream
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Returns the configured bits that make up a pointer.
|
||||
*/
|
||||
[[nodiscard]] virtual unsigned GetPointerBitCount() const = 0;
|
||||
[[nodiscard]] virtual unsigned GetPointerByteCount() const = 0;
|
||||
|
||||
/**
|
||||
* \brief Aligns the write position in the current block with the specified value.
|
||||
@@ -31,7 +45,7 @@ public:
|
||||
* \param dst The memory location to write data to.
|
||||
* \param size The amount of data to write.
|
||||
*/
|
||||
virtual void* WriteDataRaw(const void* dst, size_t size) = 0;
|
||||
virtual ZoneOutputOffset WriteDataRaw(const void* dst, size_t size) = 0;
|
||||
|
||||
/**
|
||||
* \brief Write data with the current blocks write operation into its block memory.
|
||||
@@ -41,17 +55,17 @@ public:
|
||||
* \param dst The destination where the data is written to. Must be inside the current block's memory bounds.
|
||||
* \param size The amount of data to write.
|
||||
*/
|
||||
virtual void* WriteDataInBlock(const void* dst, size_t size) = 0;
|
||||
virtual ZoneOutputOffset WriteDataInBlock(const void* dst, size_t size) = 0;
|
||||
virtual void IncBlockPos(size_t size) = 0;
|
||||
virtual void WriteNullTerminated(const void* dst) = 0;
|
||||
|
||||
virtual bool ReusableShouldWrite(void** pPtr, size_t size, std::type_index type) = 0;
|
||||
virtual bool ReusableShouldWrite(void* pPtr, ZoneOutputOffset outputOffset, size_t size, std::type_index type) = 0;
|
||||
virtual void ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type) = 0;
|
||||
virtual void MarkFollowing(void** pPtr) = 0;
|
||||
virtual void MarkFollowing(ZoneOutputOffset offset) = 0;
|
||||
|
||||
template<typename T> bool ReusableShouldWrite(T** pPtr)
|
||||
template<typename T> bool ReusableShouldWrite(T* pPtr, const ZoneOutputOffset outputOffset)
|
||||
{
|
||||
return ReusableShouldWrite(reinterpret_cast<void**>(reinterpret_cast<uintptr_t>(pPtr)), sizeof(T), std::type_index(typeid(T)));
|
||||
return ReusableShouldWrite(const_cast<void*>(reinterpret_cast<const void*>(pPtr)), outputOffset, sizeof(T), std::type_index(typeid(T)));
|
||||
}
|
||||
|
||||
template<typename T> void ReusableAddOffset(T* ptr)
|
||||
@@ -64,24 +78,19 @@ public:
|
||||
ReusableAddOffset(const_cast<void*>(reinterpret_cast<const void*>(ptr)), sizeof(T), count, std::type_index(typeid(T)));
|
||||
}
|
||||
|
||||
template<typename T> T* Write(T* dst)
|
||||
template<typename T> ZoneOutputOffset Write(T* dst)
|
||||
{
|
||||
return static_cast<T*>(WriteDataInBlock(reinterpret_cast<const void*>(dst), sizeof(T)));
|
||||
return WriteDataInBlock(reinterpret_cast<const void*>(dst), sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T> T* Write(T* dst, const size_t count)
|
||||
template<typename T> ZoneOutputOffset Write(T* dst, const size_t count)
|
||||
{
|
||||
return static_cast<T*>(WriteDataInBlock(reinterpret_cast<const void*>(dst), count * sizeof(T)));
|
||||
return WriteDataInBlock(reinterpret_cast<const void*>(dst), count * sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T> T* WritePartial(T* dst, const size_t size)
|
||||
ZoneOutputOffset WritePartial(const void* dst, const size_t size)
|
||||
{
|
||||
return static_cast<T*>(WriteDataInBlock(reinterpret_cast<const void*>(dst), size));
|
||||
}
|
||||
|
||||
template<typename T> void MarkFollowing(T*& ptr)
|
||||
{
|
||||
MarkFollowing(reinterpret_cast<void**>(reinterpret_cast<uintptr_t>(&ptr)));
|
||||
return WriteDataInBlock(dst, size);
|
||||
}
|
||||
|
||||
static std::unique_ptr<ZoneOutputStream>
|
||||
|
||||
Reference in New Issue
Block a user