2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-01-13 12:11:50 +00:00

refactor: return ZoneOutputOffset when writing via ZoneOutputStream

This commit is contained in:
Jan Laupetin
2026-01-06 22:37:46 +00:00
parent df07ebe083
commit 4048de44a1
16 changed files with 262 additions and 92 deletions

View File

@@ -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();

View File

@@ -24,5 +24,9 @@ namespace IW3
XAssetList* varXAssetList;
XAsset* varXAsset;
ScriptStringList* varScriptStringList;
ZoneOutputOffset varXAssetListWritten;
ZoneOutputOffset varXAssetWritten;
ZoneOutputOffset varScriptStringListWritten;
};
} // namespace IW3

View File

@@ -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();

View File

@@ -24,5 +24,9 @@ namespace IW4
XAssetList* varXAssetList;
XAsset* varXAsset;
ScriptStringList* varScriptStringList;
ZoneOutputOffset varXAssetListWritten;
ZoneOutputOffset varXAssetWritten;
ZoneOutputOffset varScriptStringListWritten;
};
} // namespace IW4

View File

@@ -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();

View File

@@ -24,5 +24,9 @@ namespace IW5
XAssetList* varXAssetList;
XAsset* varXAsset;
ScriptStringList* varScriptStringList;
ZoneOutputOffset varXAssetListWritten;
ZoneOutputOffset varXAssetWritten;
ZoneOutputOffset varScriptStringListWritten;
};
} // namespace IW5

View File

@@ -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();

View File

@@ -24,5 +24,9 @@ namespace T5
XAssetList* varXAssetList;
XAsset* varXAsset;
ScriptStringList* varScriptStringList;
ZoneOutputOffset varXAssetListWritten;
ZoneOutputOffset varXAssetWritten;
ZoneOutputOffset varScriptStringListWritten;
};
} // namespace T5

View File

@@ -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();

View File

@@ -24,5 +24,9 @@ namespace T6
XAssetList* varXAssetList;
XAsset* varXAsset;
ScriptStringList* varScriptStringList;
ZoneOutputOffset varXAssetListWritten;
ZoneOutputOffset varXAssetWritten;
ZoneOutputOffset varScriptStringListWritten;
};
} // namespace T6

View File

@@ -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));
}
}

View File

@@ -17,5 +17,5 @@ protected:
XAssetInfoGeneric* m_asset;
scr_string_t* varScriptString;
scr_string_t* varScriptStringWritten;
ZoneOutputOffset varScriptStringWritten;
};

View File

@@ -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());
}
}

View File

@@ -24,5 +24,5 @@ protected:
ZoneOutputStream* m_stream;
const char** varXString;
const char** varXStringWritten;
ZoneOutputOffset varXStringWritten;
};

View File

@@ -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)
{

View File

@@ -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>