diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp index c4d96493..d7d29c95 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp @@ -306,7 +306,7 @@ namespace { std::ostringstream str; MakeTypeWrittenVarNameInternal(info->m_definition, str); - str << ".WithInnerOffset("; + str << ".AtOffset("; if (m_env.m_architecture_mismatch) { @@ -791,7 +791,7 @@ namespace return; } - LINEF("if (m_stream->ReusableShouldWrite({0}, {1}.WithInnerOffset({2})))", + LINEF("if (m_stream->ReusableShouldWrite({0}, {1}.AtOffset({2})))", MakeMemberAccess(info, member, modifier), MakeTypeWrittenVarName(info->m_definition), MakeReusableInnerOffset(info->m_definition, member->m_member)) diff --git a/src/ZoneWriting/Game/IW3/ContentWriterIW3.cpp b/src/ZoneWriting/Game/IW3/ContentWriterIW3.cpp index 34d9fbd6..e904524d 100644 --- a/src/ZoneWriting/Game/IW3/ContentWriterIW3.cpp +++ b/src/ZoneWriting/Game/IW3/ContentWriterIW3.cpp @@ -57,10 +57,7 @@ void ContentWriter::CreateXAssetList(XAssetList& xAssetList, MemoryManager& memo void ContentWriter::WriteScriptStringList(const bool atStreamStart) { - m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); - - if (atStreamStart) - varScriptStringListWritten = m_stream->Write(varScriptStringList); + assert(!atStreamStart); if (varScriptStringList->strings != nullptr) { @@ -71,10 +68,8 @@ void ContentWriter::WriteScriptStringList(const bool atStreamStart) #ifdef ARCH_x86 static_assert(offsetof(ScriptStringList, strings) == 4u); #endif - m_stream->MarkFollowing(varScriptStringListWritten.WithInnerOffset(4)); + m_stream->MarkFollowing(varScriptStringListWritten.AtOffset(4)); } - - m_stream->PopBlock(); } void ContentWriter::WriteXAsset(const bool atStreamStart) @@ -86,7 +81,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart) case type_index: \ { \ Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \ - writer.Write(varXAsset->header.headerEntry, varXAssetWritten.WithInnerOffset(4)); \ + writer.Write(varXAsset->header.headerEntry, varXAssetWritten.AtOffset(4)); \ break; \ } #define SKIP_ASSET(type_index, typeName, headerEntry) \ @@ -142,17 +137,27 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun { assert(varXAsset != nullptr); +#ifdef ARCH_x86 + static_assert(sizeof(XAsset) == 8u); +#endif + if (atStreamStart) + { +#ifdef ARCH_x86 varXAssetWritten = m_stream->Write(varXAsset, count); +#else + const auto fill = m_stream->WriteWithFill(8u * count); + varXAssetWritten = fill.Offset(); + + for (size_t index = 0; index < count; index++) + fill.Fill(varXAsset[index].type, 8u * index); +#endif + } for (size_t index = 0; index < count; index++) { WriteXAsset(false); varXAsset++; - -#ifdef ARCH_x86 - static_assert(sizeof(XAsset) == 8u); -#endif varXAssetWritten.Inc(8u); } } @@ -161,21 +166,34 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream) { m_stream = &stream; - m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); - MemoryManager memory; XAssetList assetList{}; CreateXAssetList(assetList, memory); varXAssetList = &assetList; + +#ifdef ARCH_x86 + static_assert(sizeof(XAssetList) == 16); + static_assert(offsetof(XAssetList, assetCount) == 8u); varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList)); +#else + const auto fillAccessor = m_stream->WriteWithFill(16u); + varXAssetListWritten = fillAccessor.Offset(); + + varScriptStringList = &varXAssetList->stringList; + fillAccessor.Fill(varScriptStringList->count, 0u); + + fillAccessor.Fill(varXAssetList->assetCount, 8u); +#endif + + m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); #ifdef ARCH_x86 static_assert(offsetof(XAssetList, stringList) == 0u); #endif varScriptStringList = &varXAssetList->stringList; - varScriptStringListWritten = varXAssetListWritten.WithInnerOffset(0); + varScriptStringListWritten = varXAssetListWritten.AtOffset(0); WriteScriptStringList(false); if (varXAssetList->assets != nullptr) @@ -187,7 +205,7 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream) #ifdef ARCH_x86 static_assert(offsetof(XAssetList, assets) == 12u); #endif - m_stream->MarkFollowing(varXAssetListWritten.WithInnerOffset(12)); + m_stream->MarkFollowing(varXAssetListWritten.AtOffset(12)); } m_stream->PopBlock(); diff --git a/src/ZoneWriting/Game/IW4/ContentWriterIW4.cpp b/src/ZoneWriting/Game/IW4/ContentWriterIW4.cpp index 1017573d..c0fbc85a 100644 --- a/src/ZoneWriting/Game/IW4/ContentWriterIW4.cpp +++ b/src/ZoneWriting/Game/IW4/ContentWriterIW4.cpp @@ -57,10 +57,7 @@ void ContentWriter::CreateXAssetList(XAssetList& xAssetList, MemoryManager& memo void ContentWriter::WriteScriptStringList(const bool atStreamStart) { - m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); - - if (atStreamStart) - varScriptStringListWritten = m_stream->Write(varScriptStringList); + assert(!atStreamStart); if (varScriptStringList->strings != nullptr) { @@ -71,10 +68,8 @@ void ContentWriter::WriteScriptStringList(const bool atStreamStart) #ifdef ARCH_x86 static_assert(offsetof(ScriptStringList, strings) == 4u); #endif - m_stream->MarkFollowing(varScriptStringListWritten.WithInnerOffset(4)); + m_stream->MarkFollowing(varScriptStringListWritten.AtOffset(4)); } - - m_stream->PopBlock(); } void ContentWriter::WriteXAsset(const bool atStreamStart) @@ -86,7 +81,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart) case type_index: \ { \ Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \ - writer.Write(varXAsset->header.headerEntry, varXAssetWritten.WithInnerOffset(4)); \ + writer.Write(varXAsset->header.headerEntry, varXAssetWritten.AtOffset(4)); \ break; \ } #define SKIP_ASSET(type_index, typeName, headerEntry) \ @@ -152,17 +147,27 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun { assert(varXAsset != nullptr); +#ifdef ARCH_x86 + static_assert(sizeof(XAsset) == 8u); +#endif + if (atStreamStart) + { +#ifdef ARCH_x86 varXAssetWritten = m_stream->Write(varXAsset, count); +#else + const auto fill = m_stream->WriteWithFill(8u * count); + varXAssetWritten = fill.Offset(); + + for (size_t index = 0; index < count; index++) + fill.Fill(varXAsset[index].type, 8u * index); +#endif + } for (size_t index = 0; index < count; index++) { WriteXAsset(false); varXAsset++; - -#ifdef ARCH_x86 - static_assert(sizeof(XAsset) == 8u); -#endif varXAssetWritten.Inc(8u); } } @@ -171,21 +176,34 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream) { m_stream = &stream; - m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); - MemoryManager memory; XAssetList assetList{}; CreateXAssetList(assetList, memory); varXAssetList = &assetList; + +#ifdef ARCH_x86 + static_assert(sizeof(XAssetList) == 16); + static_assert(offsetof(XAssetList, assetCount) == 8u); varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList)); +#else + const auto fillAccessor = m_stream->WriteWithFill(16u); + varXAssetListWritten = fillAccessor.Offset(); + + varScriptStringList = &varXAssetList->stringList; + fillAccessor.Fill(varScriptStringList->count, 0u); + + fillAccessor.Fill(varXAssetList->assetCount, 8u); +#endif + + m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); #ifdef ARCH_x86 static_assert(offsetof(XAssetList, stringList) == 0u); #endif varScriptStringList = &varXAssetList->stringList; - varScriptStringListWritten = varXAssetListWritten.WithInnerOffset(0); + varScriptStringListWritten = varXAssetListWritten.AtOffset(0); WriteScriptStringList(false); if (varXAssetList->assets != nullptr) @@ -197,7 +215,7 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream) #ifdef ARCH_x86 static_assert(offsetof(XAssetList, assets) == 12u); #endif - m_stream->MarkFollowing(varXAssetListWritten.WithInnerOffset(12)); + m_stream->MarkFollowing(varXAssetListWritten.AtOffset(12)); } m_stream->PopBlock(); diff --git a/src/ZoneWriting/Game/IW5/ContentWriterIW5.cpp b/src/ZoneWriting/Game/IW5/ContentWriterIW5.cpp index fef99578..d701903c 100644 --- a/src/ZoneWriting/Game/IW5/ContentWriterIW5.cpp +++ b/src/ZoneWriting/Game/IW5/ContentWriterIW5.cpp @@ -57,10 +57,7 @@ void ContentWriter::CreateXAssetList(XAssetList& xAssetList, MemoryManager& memo void ContentWriter::WriteScriptStringList(const bool atStreamStart) { - m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); - - if (atStreamStart) - varScriptStringListWritten = m_stream->Write(varScriptStringList); + assert(!atStreamStart); if (varScriptStringList->strings != nullptr) { @@ -71,10 +68,8 @@ void ContentWriter::WriteScriptStringList(const bool atStreamStart) #ifdef ARCH_x86 static_assert(offsetof(ScriptStringList, strings) == 4u); #endif - m_stream->MarkFollowing(varScriptStringListWritten.WithInnerOffset(4)); + m_stream->MarkFollowing(varScriptStringListWritten.AtOffset(4)); } - - m_stream->PopBlock(); } void ContentWriter::WriteXAsset(const bool atStreamStart) @@ -86,7 +81,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart) case type_index: \ { \ Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \ - writer.Write(varXAsset->header.headerEntry, varXAssetWritten.WithInnerOffset(4)); \ + writer.Write(varXAsset->header.headerEntry, varXAssetWritten.AtOffset(4)); \ break; \ } #define SKIP_ASSET(type_index, typeName, headerEntry) \ @@ -155,17 +150,27 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun { assert(varXAsset != nullptr); +#ifdef ARCH_x86 + static_assert(sizeof(XAsset) == 8u); +#endif + if (atStreamStart) + { +#ifdef ARCH_x86 varXAssetWritten = m_stream->Write(varXAsset, count); +#else + const auto fill = m_stream->WriteWithFill(8u * count); + varXAssetWritten = fill.Offset(); + + for (size_t index = 0; index < count; index++) + fill.Fill(varXAsset[index].type, 8u * index); +#endif + } for (size_t index = 0; index < count; index++) { WriteXAsset(false); varXAsset++; - -#ifdef ARCH_x86 - static_assert(sizeof(XAsset) == 8u); -#endif varXAssetWritten.Inc(8u); } } @@ -174,21 +179,34 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream) { m_stream = &stream; - m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); - MemoryManager memory; XAssetList assetList{}; CreateXAssetList(assetList, memory); varXAssetList = &assetList; + +#ifdef ARCH_x86 + static_assert(sizeof(XAssetList) == 16); + static_assert(offsetof(XAssetList, assetCount) == 8u); varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList)); +#else + const auto fillAccessor = m_stream->WriteWithFill(16u); + varXAssetListWritten = fillAccessor.Offset(); + + varScriptStringList = &varXAssetList->stringList; + fillAccessor.Fill(varScriptStringList->count, 0u); + + fillAccessor.Fill(varXAssetList->assetCount, 8u); +#endif + + m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); #ifdef ARCH_x86 static_assert(offsetof(XAssetList, stringList) == 0u); #endif varScriptStringList = &varXAssetList->stringList; - varScriptStringListWritten = varXAssetListWritten.WithInnerOffset(0); + varScriptStringListWritten = varXAssetListWritten.AtOffset(0); WriteScriptStringList(false); if (varXAssetList->assets != nullptr) @@ -200,7 +218,7 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream) #ifdef ARCH_x86 static_assert(offsetof(XAssetList, assets) == 12u); #endif - m_stream->MarkFollowing(varXAssetListWritten.WithInnerOffset(12)); + m_stream->MarkFollowing(varXAssetListWritten.AtOffset(12)); } m_stream->PopBlock(); diff --git a/src/ZoneWriting/Game/T5/ContentWriterT5.cpp b/src/ZoneWriting/Game/T5/ContentWriterT5.cpp index 9814fe6d..253a022a 100644 --- a/src/ZoneWriting/Game/T5/ContentWriterT5.cpp +++ b/src/ZoneWriting/Game/T5/ContentWriterT5.cpp @@ -57,10 +57,7 @@ void ContentWriter::CreateXAssetList(XAssetList& xAssetList, MemoryManager& memo void ContentWriter::WriteScriptStringList(const bool atStreamStart) { - m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); - - if (atStreamStart) - varScriptStringListWritten = m_stream->Write(varScriptStringList); + assert(!atStreamStart); if (varScriptStringList->strings != nullptr) { @@ -71,10 +68,8 @@ void ContentWriter::WriteScriptStringList(const bool atStreamStart) #ifdef ARCH_x86 static_assert(offsetof(ScriptStringList, strings) == 4u); #endif - m_stream->MarkFollowing(varScriptStringListWritten.WithInnerOffset(4)); + m_stream->MarkFollowing(varScriptStringListWritten.AtOffset(4)); } - - m_stream->PopBlock(); } void ContentWriter::WriteXAsset(const bool atStreamStart) @@ -86,7 +81,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart) case type_index: \ { \ Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \ - writer.Write(varXAsset->header.headerEntry, varXAssetWritten.WithInnerOffset(4)); \ + writer.Write(varXAsset->header.headerEntry, varXAssetWritten.AtOffset(4)); \ break; \ } #define SKIP_ASSET(type_index, typeName, headerEntry) \ @@ -148,17 +143,27 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun { assert(varXAsset != nullptr); +#ifdef ARCH_x86 + static_assert(sizeof(XAsset) == 8u); +#endif + if (atStreamStart) + { +#ifdef ARCH_x86 varXAssetWritten = m_stream->Write(varXAsset, count); +#else + const auto fill = m_stream->WriteWithFill(8u * count); + varXAssetWritten = fill.Offset(); + + for (size_t index = 0; index < count; index++) + fill.Fill(varXAsset[index].type, 8u * index); +#endif + } for (size_t index = 0; index < count; index++) { WriteXAsset(false); varXAsset++; - -#ifdef ARCH_x86 - static_assert(sizeof(XAsset) == 8u); -#endif varXAssetWritten.Inc(8u); } } @@ -167,21 +172,34 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream) { m_stream = &stream; - m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); - MemoryManager memory; XAssetList assetList{}; CreateXAssetList(assetList, memory); varXAssetList = &assetList; + +#ifdef ARCH_x86 + static_assert(sizeof(XAssetList) == 16); + static_assert(offsetof(XAssetList, assetCount) == 8u); varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList)); +#else + const auto fillAccessor = m_stream->WriteWithFill(16u); + varXAssetListWritten = fillAccessor.Offset(); + + varScriptStringList = &varXAssetList->stringList; + fillAccessor.Fill(varScriptStringList->count, 0u); + + fillAccessor.Fill(varXAssetList->assetCount, 8u); +#endif + + m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); #ifdef ARCH_x86 static_assert(offsetof(XAssetList, stringList) == 0u); #endif varScriptStringList = &varXAssetList->stringList; - varScriptStringListWritten = varXAssetListWritten.WithInnerOffset(0); + varScriptStringListWritten = varXAssetListWritten.AtOffset(0); WriteScriptStringList(false); if (varXAssetList->assets != nullptr) @@ -193,7 +211,7 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream) #ifdef ARCH_x86 static_assert(offsetof(XAssetList, assets) == 12u); #endif - m_stream->MarkFollowing(varXAssetListWritten.WithInnerOffset(12)); + m_stream->MarkFollowing(varXAssetListWritten.AtOffset(12)); } m_stream->PopBlock(); diff --git a/src/ZoneWriting/Game/T6/ContentWriterT6.cpp b/src/ZoneWriting/Game/T6/ContentWriterT6.cpp index 3f40d075..14af265a 100644 --- a/src/ZoneWriting/Game/T6/ContentWriterT6.cpp +++ b/src/ZoneWriting/Game/T6/ContentWriterT6.cpp @@ -60,10 +60,7 @@ void ContentWriter::CreateXAssetList(XAssetList& xAssetList, MemoryManager& memo void ContentWriter::WriteScriptStringList(const bool atStreamStart) { - m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); - - if (atStreamStart) - varScriptStringListWritten = m_stream->Write(varScriptStringList); + assert(!atStreamStart); if (varScriptStringList->strings != nullptr) { @@ -74,10 +71,8 @@ void ContentWriter::WriteScriptStringList(const bool atStreamStart) #ifdef ARCH_x86 static_assert(offsetof(ScriptStringList, strings) == 4u); #endif - m_stream->MarkFollowing(varScriptStringListWritten.WithInnerOffset(4)); + m_stream->MarkFollowing(varScriptStringListWritten.AtOffset(4)); } - - m_stream->PopBlock(); } void ContentWriter::WriteXAsset(const bool atStreamStart) @@ -89,7 +84,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart) case type_index: \ { \ Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \ - writer.Write(varXAsset->header.headerEntry, varXAssetWritten.WithInnerOffset(4)); \ + writer.Write(varXAsset->header.headerEntry, varXAssetWritten.AtOffset(4)); \ break; \ } @@ -162,18 +157,27 @@ void ContentWriter::WriteXAsset(const bool atStreamStart) void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t count) { assert(varXAsset != nullptr); +#ifdef ARCH_x86 + static_assert(sizeof(XAsset) == 8u); +#endif if (atStreamStart) + { +#ifdef ARCH_x86 varXAssetWritten = m_stream->Write(varXAsset, count); +#else + const auto fill = m_stream->WriteWithFill(8u * count); + varXAssetWritten = fill.Offset(); + + for (size_t index = 0; index < count; index++) + fill.Fill(varXAsset[index].type, 8u * index); +#endif + } for (size_t index = 0; index < count; index++) { WriteXAsset(false); varXAsset++; - -#ifdef ARCH_x86 - static_assert(sizeof(XAsset) == 8u); -#endif varXAssetWritten.Inc(8u); } } @@ -182,21 +186,36 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream) { m_stream = &stream; - m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); - MemoryManager memory; XAssetList assetList{}; CreateXAssetList(assetList, memory); varXAssetList = &assetList; + +#ifdef ARCH_x86 + static_assert(sizeof(XAssetList) == 24); + static_assert(offsetof(XAssetList, dependCount) == 8u); + static_assert(offsetof(XAssetList, assetCount) == 16u); varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList)); +#else + const auto fillAccessor = m_stream->WriteWithFill(24u); + varXAssetListWritten = fillAccessor.Offset(); + + varScriptStringList = &varXAssetList->stringList; + fillAccessor.Fill(varScriptStringList->count, 0u); + + fillAccessor.Fill(varXAssetList->dependCount, 8u); + fillAccessor.Fill(varXAssetList->assetCount, 16u); +#endif + + m_stream->PushBlock(XFILE_BLOCK_VIRTUAL); #ifdef ARCH_x86 static_assert(offsetof(XAssetList, stringList) == 0u); #endif varScriptStringList = &varXAssetList->stringList; - varScriptStringListWritten = varXAssetListWritten.WithInnerOffset(0); + varScriptStringListWritten = varXAssetListWritten.AtOffset(0); WriteScriptStringList(false); if (varXAssetList->depends != nullptr) @@ -208,7 +227,7 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream) #ifdef ARCH_x86 static_assert(offsetof(XAssetList, depends) == 12u); #endif - m_stream->MarkFollowing(varXAssetListWritten.WithInnerOffset(12)); + m_stream->MarkFollowing(varXAssetListWritten.AtOffset(12)); } if (varXAssetList->assets != nullptr) @@ -220,7 +239,7 @@ void ContentWriter::WriteContent(ZoneOutputStream& stream) #ifdef ARCH_x86 static_assert(offsetof(XAssetList, assets) == 20u); #endif - m_stream->MarkFollowing(varXAssetListWritten.WithInnerOffset(20)); + m_stream->MarkFollowing(varXAssetListWritten.AtOffset(20)); } m_stream->PopBlock(); diff --git a/src/ZoneWriting/Writing/ContentWriterBase.cpp b/src/ZoneWriting/Writing/ContentWriterBase.cpp index b4b52a42..e9a596fc 100644 --- a/src/ZoneWriting/Writing/ContentWriterBase.cpp +++ b/src/ZoneWriting/Writing/ContentWriterBase.cpp @@ -23,7 +23,7 @@ void ContentWriterBase::WriteXString(const bool atStreamStart) if (atStreamStart) { assert(varXString != nullptr); - varXStringWritten = m_stream->Write(varXString); + varXStringWritten = m_stream->WriteWithFill(m_stream->GetPointerByteCount()).Offset(); } assert(varXStringWritten.Offset() != nullptr); @@ -40,10 +40,11 @@ void ContentWriterBase::WriteXString(const bool atStreamStart) void ContentWriterBase::WriteXStringArray(const bool atStreamStart, const size_t count) { + const auto pointerByteCount = m_stream->GetPointerByteCount(); if (atStreamStart) { assert(varXString != nullptr); - varXStringWritten = m_stream->Write(varXString, count); + varXStringWritten = m_stream->WriteWithFill(pointerByteCount * count).Offset(); } assert(varXStringWritten.Offset() != nullptr); @@ -52,6 +53,6 @@ void ContentWriterBase::WriteXStringArray(const bool atStreamStart, const size_t { WriteXString(false); varXString++; - varXStringWritten.Inc(m_stream->GetPointerByteCount()); + varXStringWritten.Inc(pointerByteCount); } } diff --git a/src/ZoneWriting/Zone/Stream/ZoneOutputStream.cpp b/src/ZoneWriting/Zone/Stream/ZoneOutputStream.cpp index 42952a21..e89523b4 100644 --- a/src/ZoneWriting/Zone/Stream/ZoneOutputStream.cpp +++ b/src/ZoneWriting/Zone/Stream/ZoneOutputStream.cpp @@ -14,9 +14,6 @@ namespace { - inline const auto PTR_FOLLOWING = reinterpret_cast(-1); - inline const auto PTR_INSERT = reinterpret_cast(-2); - class ReusableEntry { public: @@ -182,6 +179,35 @@ namespace WriteDataInBlock(src, len + 1); } + ZoneStreamFillWriteAccessor WriteWithFill(const size_t size) override + { + // If no block has been pushed, load raw + if (!m_block_stack.empty()) + { + const auto* block = m_block_stack.top(); + + void* result = nullptr; + switch (block->m_type) + { + case XBlockType::BLOCK_TYPE_TEMP: + case XBlockType::BLOCK_TYPE_NORMAL: + result = m_zone_data.GetBufferOfSize(size); + break; + + case XBlockType::BLOCK_TYPE_RUNTIME: + case XBlockType::BLOCK_TYPE_DELAY: + assert(false); + break; + } + + IncBlockPos(size); + + return ZoneStreamFillWriteAccessor(result, size); + } + + return ZoneStreamFillWriteAccessor(m_zone_data.GetBufferOfSize(size), size); + } + void MarkFollowing(const ZoneOutputOffset outputOffset) override { assert(!m_block_stack.empty()); @@ -305,9 +331,9 @@ ZoneOutputOffset::ZoneOutputOffset(void* offset) { } -void* ZoneOutputOffset::Offset() const +ZoneOutputOffset ZoneOutputOffset::AtOffset(const size_t innerOffset) const { - return m_offset; + return ZoneOutputOffset(static_cast(m_offset) + innerOffset); } void ZoneOutputOffset::Inc(const size_t size) @@ -315,9 +341,9 @@ void ZoneOutputOffset::Inc(const size_t size) m_offset = static_cast(static_cast(m_offset) + size); } -ZoneOutputOffset ZoneOutputOffset::WithInnerOffset(const size_t innerOffset) const +void* ZoneOutputOffset::Offset() const { - return ZoneOutputOffset(static_cast(m_offset) + innerOffset); + return m_offset; } std::unique_ptr @@ -325,3 +351,19 @@ std::unique_ptr { return std::make_unique(pointerBitCount, blockBitCount, blocks, insertBlock, zoneData); } + +ZoneStreamFillWriteAccessor::ZoneStreamFillWriteAccessor(void* blockBuffer, const size_t bufferSize) + : m_block_buffer(blockBuffer), + m_buffer_size(bufferSize) +{ +} + +ZoneStreamFillWriteAccessor ZoneStreamFillWriteAccessor::AtOffset(const size_t offset) const +{ + return ZoneStreamFillWriteAccessor(static_cast(m_block_buffer) + offset, m_buffer_size - offset); +} + +ZoneOutputOffset ZoneStreamFillWriteAccessor::Offset() const +{ + return ZoneOutputOffset(m_block_buffer); +} diff --git a/src/ZoneWriting/Zone/Stream/ZoneOutputStream.h b/src/ZoneWriting/Zone/Stream/ZoneOutputStream.h index 3b6aa2ff..46e8e472 100644 --- a/src/ZoneWriting/Zone/Stream/ZoneOutputStream.h +++ b/src/ZoneWriting/Zone/Stream/ZoneOutputStream.h @@ -4,6 +4,7 @@ #include "Zone/Stream/IZoneStream.h" #include "Zone/XBlock.h" +#include #include #include #include @@ -16,14 +17,41 @@ public: ZoneOutputOffset(); explicit ZoneOutputOffset(void* offset); - [[nodiscard]] void* Offset() const; + [[nodiscard]] ZoneOutputOffset AtOffset(size_t innerOffset) const; void Inc(size_t size); - [[nodiscard]] ZoneOutputOffset WithInnerOffset(size_t innerOffset) const; + [[nodiscard]] void* Offset() const; private: void* m_offset; }; +class ZoneStreamFillWriteAccessor +{ +public: + ZoneStreamFillWriteAccessor(void* blockBuffer, size_t bufferSize); + + [[nodiscard]] ZoneStreamFillWriteAccessor AtOffset(size_t offset) const; + [[nodiscard]] ZoneOutputOffset Offset() const; + + template void Fill(const T& value, const size_t offset) const + { + assert(offset + sizeof(T) <= m_buffer_size); + + *reinterpret_cast(static_cast(m_block_buffer) + offset) = value; + } + + template void FillArray(T (&value)[S], const size_t offset) const + { + assert(offset + sizeof(T) * S <= m_buffer_size); + + std::memcpy(static_cast(m_block_buffer) + offset, value, sizeof(T) * S); + } + +private: + void* m_block_buffer; + size_t m_buffer_size; +}; + class ZoneOutputStream : public IZoneStream { public: @@ -59,6 +87,8 @@ public: virtual void IncBlockPos(size_t size) = 0; virtual void WriteNullTerminated(const void* dst) = 0; + virtual ZoneStreamFillWriteAccessor WriteWithFill(size_t size) = 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(ZoneOutputOffset offset) = 0;