fix: zone pointer offset bit count may be independent from platform pointer size

This commit is contained in:
Jan Laupetin committed 2026-10-22 20:01:06 +02:00
1 parent 49cebf0f0e
commit 0df7f16158
29 files changed
+171 -74

No files matched your search

+2 -1
View File
@@ -38,7 +38,8 @@ namespace IW3
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 4u;
static constexpr unsigned ZONE_POINTER_OFFSET_BIT_COUNT = 28u;
static constexpr unsigned ZONE_POINTER_BLOCK_BIT_COUNT = 4u;
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
};
} // namespace IW3
+2 -1
View File
@@ -60,7 +60,8 @@ namespace IW4
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 4u;
static constexpr unsigned ZONE_POINTER_OFFSET_BIT_COUNT = 28u;
static constexpr unsigned ZONE_POINTER_BLOCK_BIT_COUNT = 4u;
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
};
} // namespace IW4
+2 -1
View File
@@ -40,7 +40,8 @@ namespace IW5
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 4u;
static constexpr unsigned ZONE_POINTER_OFFSET_BIT_COUNT = 28u;
static constexpr unsigned ZONE_POINTER_BLOCK_BIT_COUNT = 4u;
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
};
} // namespace IW5
+2 -1
View File
@@ -16,7 +16,8 @@ namespace QOS
static constexpr size_t FILE_HEADER_SIZE = 28;
static constexpr size_t AUTHED_CHUNK_SIZE = 0x20000;
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 3u;
static constexpr unsigned ZONE_POINTER_OFFSET_BIT_COUNT = 29u;
static constexpr unsigned ZONE_POINTER_BLOCK_BIT_COUNT = 3u;
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
};
} // namespace QOS
+2 -1
View File
@@ -18,7 +18,8 @@ namespace T4
static_assert(std::char_traits<char>::length(MAGIC_UNSIGNED) == sizeof(ZoneHeader::m_magic));
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 3u;
static constexpr unsigned ZONE_POINTER_OFFSET_BIT_COUNT = 29u;
static constexpr unsigned ZONE_POINTER_BLOCK_BIT_COUNT = 3u;
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
};
} // namespace T4
+2 -1
View File
@@ -20,7 +20,8 @@ namespace T5
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 3u;
static constexpr unsigned ZONE_POINTER_OFFSET_BIT_COUNT = 29u;
static constexpr unsigned ZONE_POINTER_BLOCK_BIT_COUNT = 3u;
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
};
} // namespace T5
+2 -1
View File
@@ -33,7 +33,8 @@ namespace T6
static constexpr unsigned XCHUNK_SIZE = 0x8000;
static constexpr unsigned XCHUNK_MAX_WRITE_SIZE = XCHUNK_SIZE - 0x40;
static constexpr unsigned VANILLA_BUFFER_SIZE = 0x80000;
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 3u;
static constexpr unsigned ZONE_POINTER_OFFSET_BIT_COUNT = 29u;
static constexpr unsigned ZONE_POINTER_BLOCK_BIT_COUNT = 3u;
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
static constexpr size_t FILE_SUFFIX_ZERO_MIN_SIZE = 0x40;
@@ -208,7 +208,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
return std::make_unique<ContentLoader>(*zonePtr, stream);
},
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr,
std::move(progressCallback)));
@@ -376,7 +376,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
return std::make_unique<ContentLoader>(*zonePtr, stream);
},
variant->GetWordSize() == GameWordSize::ARCH_64 ? 64u : 32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr,
std::move(progressCallback)));
@@ -277,7 +277,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
return std::make_unique<ContentLoader>(*zonePtr, stream);
},
variant->GetWordSize() == GameWordSize::ARCH_64 ? 64u : 32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr,
std::move(progressCallback)));
@@ -82,7 +82,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
return std::make_unique<ContentLoader>(*zonePtr, stream);
},
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr,
std::move(progressCallback)));
@@ -85,7 +85,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
return std::make_unique<ContentLoader>(*zonePtr, stream);
},
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr,
std::move(progressCallback)));
@@ -91,7 +91,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
return std::make_unique<ContentLoader>(*zonePtr, stream);
},
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr,
std::move(progressCallback)));
@@ -348,7 +348,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
return std::make_unique<ContentLoader>(*zonePtr, stream);
},
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr,
std::move(progressCallback)));
@@ -9,13 +9,15 @@ namespace
public:
StepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
const unsigned pointerBitCount,
const unsigned offsetBlockBitCount,
const unsigned zonePointerOffsetBitCount,
const unsigned zonePointerBlockBitCount,
const block_t insertBlock,
Zone* zone,
std::optional<std::unique_ptr<ProgressCallback>> progressCallback)
: m_entry_point_factory(std::move(entryPointFactory)),
m_pointer_bit_count(pointerBitCount),
m_offset_block_bit_count(offsetBlockBitCount),
m_zone_pointer_offset_bit_count(zonePointerOffsetBitCount),
m_zone_pointer_block_bit_count(zonePointerBlockBitCount),
m_insert_block(insertBlock),
m_zone(zone),
m_progress_callback(std::move(progressCallback))
@@ -31,8 +33,14 @@ namespace
for (size_t i = 0; i < blockCount; ++i)
m_blocks.emplace_back(zoneMemory.GetBlock(i));
const auto inputStream = ZoneInputStream::Create(
m_pointer_bit_count, m_offset_block_bit_count, m_blocks, m_insert_block, stream, m_zone->Memory(), std::move(m_progress_callback));
const auto inputStream = ZoneInputStream::Create(m_pointer_bit_count,
m_zone_pointer_offset_bit_count,
m_zone_pointer_block_bit_count,
m_blocks,
m_insert_block,
stream,
m_zone->Memory(),
std::move(m_progress_callback));
const auto entryPoint = m_entry_point_factory(*inputStream);
assert(entryPoint);
@@ -43,7 +51,8 @@ namespace
private:
std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> m_entry_point_factory;
unsigned m_pointer_bit_count;
unsigned m_offset_block_bit_count;
unsigned m_zone_pointer_offset_bit_count;
unsigned m_zone_pointer_block_bit_count;
block_t m_insert_block;
Zone* m_zone;
std::vector<XBlock*> m_blocks;
@@ -55,12 +64,13 @@ namespace step
{
std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
const unsigned pointerBitCount,
const unsigned offsetBlockBitCount,
const unsigned zonePointerOffsetBitCount,
const unsigned zonePointerBlockBitCount,
const block_t insertBlock,
Zone* zone,
std::optional<std::unique_ptr<ProgressCallback>> progressCallback)
{
return std::make_unique<StepLoadZoneContent>(
std::move(entryPointFactory), pointerBitCount, offsetBlockBitCount, insertBlock, zone, std::move(progressCallback));
std::move(entryPointFactory), pointerBitCount, zonePointerOffsetBitCount, zonePointerBlockBitCount, insertBlock, zone, std::move(progressCallback));
}
} // namespace step
@@ -11,7 +11,8 @@ namespace step
{
std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
unsigned pointerBitCount,
unsigned offsetBlockBitCount,
unsigned zonePointerOffsetBitCount,
unsigned zonePointerBlockBitCount,
block_t insertBlock,
Zone* zone,
std::optional<std::unique_ptr<ProgressCallback>> progressCallback);
+25 -20
View File
@@ -46,7 +46,8 @@ namespace
{
public:
XBlockInputStream(const unsigned pointerBitCount,
const unsigned blockBitCount,
const unsigned zonePointerOffsetBitCount,
const unsigned zonePointerBlockBitCount,
std::vector<XBlock*>& blocks,
const block_t insertBlock,
ILoadingStream& stream,
@@ -57,15 +58,17 @@ namespace
m_stream(stream),
m_memory(memory),
m_pointer_byte_count(pointerBitCount / 8u),
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))),
m_zone_pointer_block_mask((std::numeric_limits<uintptr_t>::max() >> (sizeof(uintptr_t) * 8 - zonePointerBlockBitCount))
<< zonePointerOffsetBitCount),
m_zone_pointer_block_shift(zonePointerOffsetBitCount),
m_zone_pointer_offset_mask(std::numeric_limits<uintptr_t>::max() >> (sizeof(uintptr_t) * 8 - zonePointerOffsetBitCount)),
m_last_fill_size(0),
m_has_progress_callback(false),
m_progress_current_size(0uz),
m_progress_total_size(0uz)
{
assert(pointerBitCount % 8u == 0u);
assert(zonePointerOffsetBitCount + zonePointerBlockBitCount <= pointerBitCount);
assert(insertBlock < static_cast<block_t>(blocks.size()));
std::memset(m_block_offsets.data(), 0, sizeof(decltype(m_block_offsets)::value_type) * m_block_offsets.size());
@@ -292,7 +295,7 @@ namespace
const auto blockNum = m_insert_block->m_index;
const auto blockOffset = static_cast<uintptr_t>(m_block_offsets[m_insert_block->m_index]);
const auto zonePtr = (static_cast<uintptr_t>(blockNum) << m_block_shift) | (blockOffset & m_offset_mask);
const auto zonePtr = (static_cast<uintptr_t>(blockNum) << m_zone_pointer_block_shift) | (blockOffset & m_zone_pointer_offset_mask);
IncBlockPos(*m_insert_block, m_pointer_byte_count);
@@ -301,7 +304,7 @@ namespace
void SetInsertedPointerAliasLookup(const uintptr_t zonePtr, void* value) override
{
assert((static_cast<block_t>((zonePtr & m_block_mask) >> m_block_shift)) < m_blocks.size());
assert((static_cast<block_t>((zonePtr & m_zone_pointer_block_mask) >> m_zone_pointer_block_shift)) < m_blocks.size());
m_alias_redirect_lookup.emplace(zonePtr, value);
}
@@ -311,8 +314,8 @@ namespace
// So all offsets are moved by 1.
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);
const auto blockNum = static_cast<block_t>((offsetInt & m_zone_pointer_block_mask) >> m_zone_pointer_block_shift);
const auto blockOffset = static_cast<size_t>(offsetInt & m_zone_pointer_offset_mask);
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
throw InvalidOffsetBlockException(blockNum);
@@ -330,8 +333,8 @@ namespace
// 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);
const auto blockNum = static_cast<block_t>((offsetInt & m_zone_pointer_block_mask) >> m_zone_pointer_block_shift);
const auto blockOffset = static_cast<size_t>(offsetInt & m_zone_pointer_offset_mask);
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
throw InvalidOffsetBlockException(blockNum);
@@ -356,7 +359,7 @@ namespace
const auto blockNum = block->m_index;
const auto blockOffset = static_cast<uintptr_t>(static_cast<const uint8_t*>(blockPtr) - block->m_buffer.get());
const auto zonePtr = (static_cast<uintptr_t>(blockNum) << m_block_shift) | (blockOffset & m_offset_mask);
const auto zonePtr = (static_cast<uintptr_t>(blockNum) << m_zone_pointer_block_shift) | (blockOffset & m_zone_pointer_offset_mask);
m_pointer_redirect_lookup.emplace(zonePtr, alias);
}
@@ -365,8 +368,8 @@ namespace
// 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);
const auto blockNum = static_cast<block_t>((offsetInt & m_zone_pointer_block_mask) >> m_zone_pointer_block_shift);
const auto blockOffset = static_cast<size_t>(offsetInt & m_zone_pointer_offset_mask);
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
throw InvalidOffsetBlockException(blockNum);
@@ -388,8 +391,8 @@ namespace
// 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);
const auto blockNum = static_cast<block_t>((offsetInt & m_zone_pointer_block_mask) >> m_zone_pointer_block_shift);
const auto blockOffset = static_cast<size_t>(offsetInt & m_zone_pointer_offset_mask);
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
throw InvalidOffsetBlockException(blockNum);
@@ -496,9 +499,9 @@ namespace
MemoryManager& m_memory;
unsigned m_pointer_byte_count;
uintptr_t m_block_mask;
unsigned m_block_shift;
uintptr_t m_offset_mask;
uintptr_t m_zone_pointer_block_mask;
unsigned m_zone_pointer_block_shift;
uintptr_t m_zone_pointer_offset_mask;
XBlock* m_insert_block;
std::vector<uint8_t> m_fill_buffer;
@@ -515,12 +518,14 @@ namespace
} // namespace
std::unique_ptr<ZoneInputStream> ZoneInputStream::Create(const unsigned pointerBitCount,
const unsigned blockBitCount,
const unsigned zonePointerOffsetBitCount,
const unsigned zonePointerBlockBitCount,
std::vector<XBlock*>& blocks,
const block_t insertBlock,
ILoadingStream& stream,
MemoryManager& memory,
std::optional<std::unique_ptr<ProgressCallback>> progressCallback)
{
return std::make_unique<XBlockInputStream>(pointerBitCount, blockBitCount, blocks, insertBlock, stream, memory, std::move(progressCallback));
return std::make_unique<XBlockInputStream>(
pointerBitCount, zonePointerOffsetBitCount, zonePointerBlockBitCount, blocks, insertBlock, stream, memory, std::move(progressCallback));
}
+14 -1
View File
@@ -240,8 +240,21 @@ public:
virtual void DebugOffsets(size_t assetIndex) const = 0;
#endif
/**
* \brief Creates a new ZoneInputStream with given parameters.
* \param pointerBitCount The bit count of a pointer of the platform the zone data comes from.
* \param zonePointerBlockBitCount The bit count of the offset in a zone pointer. offsetBitCount + blockBitCount <= pointerBitCount
* \param zonePointerOffsetBitCount The bitcount of a block index in a zone pointer. offsetBitCount + blockBitCount <= pointerBitCount
* \param blocks The blocks of the zone.
* \param insertBlock The block index that is used when inserting a pointer. Should be the default normal block.
* \param stream The stream to load data from.
* \param memory The memory manager to use for allocating new memory.
* \param progressCallback An optional callback to call on progress.
* \return
*/
static std::unique_ptr<ZoneInputStream> Create(unsigned pointerBitCount,
unsigned blockBitCount,
unsigned zonePointerOffsetBitCount,
unsigned zonePointerBlockBitCount,
std::vector<XBlock*>& blocks,
block_t insertBlock,
ILoadingStream& stream,
@@ -52,8 +52,12 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
SetupBlocks(*writer);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(std::make_unique<ContentWriter>(zone),
zone,
32u,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK);
auto* contentInMemoryPtr = contentInMemory.get();
writer->AddWritingStep(std::move(contentInMemory));
@@ -67,8 +67,12 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
SetupBlocks(*writer);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(std::make_unique<ContentWriter>(zone),
zone,
32u,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK);
auto* contentInMemoryPtr = contentInMemory.get();
writer->AddWritingStep(std::move(contentInMemory));
@@ -68,8 +68,12 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
SetupBlocks(*writer);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(std::make_unique<ContentWriter>(zone),
zone,
32u,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK);
auto* contentInMemoryPtr = contentInMemory.get();
writer->AddWritingStep(std::move(contentInMemory));
@@ -54,8 +54,12 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
SetupBlocks(*writer);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(std::make_unique<ContentWriter>(zone),
zone,
32u,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK);
auto* contentInMemoryPtr = contentInMemory.get();
writer->AddWritingStep(std::move(contentInMemory));
@@ -50,8 +50,12 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
SetupBlocks(*writer);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(std::make_unique<ContentWriter>(zone),
zone,
32u,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK);
auto* contentInMemoryPtr = contentInMemory.get();
writer->AddWritingStep(std::move(contentInMemory));
@@ -50,8 +50,12 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
SetupBlocks(*writer);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(std::make_unique<ContentWriter>(zone),
zone,
32u,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK);
auto* contentInMemoryPtr = contentInMemory.get();
writer->AddWritingStep(std::move(contentInMemory));
@@ -106,8 +106,12 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
SetupBlocks(*writer);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(std::make_unique<ContentWriter>(zone),
zone,
32u,
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK);
auto* contentInMemoryPtr = contentInMemory.get();
writer->AddWritingStep(std::move(contentInMemory));
@@ -5,13 +5,15 @@
StepWriteZoneContentToMemory::StepWriteZoneContentToMemory(std::unique_ptr<IContentWritingEntryPoint> entryPoint,
const Zone& zone,
const unsigned pointerBitCount,
const unsigned offsetBlockBitCount,
const unsigned zonePointerOffsetBitCount,
const unsigned zonePointerBlockBitCount,
const block_t insertBlock)
: m_content_loader(std::move(entryPoint)),
m_zone_data(std::make_unique<InMemoryZoneData>()),
m_zone(zone),
m_pointer_bit_count(pointerBitCount),
m_offset_block_bit_count(offsetBlockBitCount),
m_zone_pointer_offset_bit_count(zonePointerOffsetBitCount),
m_zone_pointer_block_bit_count(zonePointerBlockBitCount),
m_insert_block(insertBlock)
{
}
@@ -22,7 +24,8 @@ void StepWriteZoneContentToMemory::PerformStep(ZoneWriter* zoneWriter, IWritingS
for (const auto& block : zoneWriter->m_blocks)
m_blocks.emplace_back(block.get());
const auto zoneOutputStream = ZoneOutputStream::Create(m_pointer_bit_count, m_offset_block_bit_count, m_blocks, m_insert_block, *m_zone_data);
const auto zoneOutputStream =
ZoneOutputStream::Create(m_pointer_bit_count, m_zone_pointer_offset_bit_count, m_zone_pointer_block_bit_count, m_blocks, m_insert_block, *m_zone_data);
m_content_loader->WriteContent(*zoneOutputStream);
}
@@ -9,8 +9,12 @@
class StepWriteZoneContentToMemory final : public IWritingStep
{
public:
StepWriteZoneContentToMemory(
std::unique_ptr<IContentWritingEntryPoint> entryPoint, const Zone& zone, unsigned pointerBitCount, unsigned offsetBlockBitCount, block_t insertBlock);
StepWriteZoneContentToMemory(std::unique_ptr<IContentWritingEntryPoint> entryPoint,
const Zone& zone,
unsigned pointerBitCount,
unsigned zonePointerOffsetBitCount,
unsigned zonePointerBlockBitCount,
block_t insertBlock);
void PerformStep(ZoneWriter* zoneWriter, IWritingStream* stream) override;
[[nodiscard]] InMemoryZoneData* GetData() const;
@@ -22,6 +26,7 @@ private:
std::vector<XBlock*> m_blocks;
unsigned m_pointer_bit_count;
unsigned m_offset_block_bit_count;
unsigned m_zone_pointer_offset_bit_count;
unsigned m_zone_pointer_block_bit_count;
block_t m_insert_block;
};
@@ -38,12 +38,19 @@ namespace
class InMemoryZoneOutputStream final : public ZoneOutputStream
{
public:
InMemoryZoneOutputStream(
const unsigned pointerBitCount, const unsigned blockBitCount, std::vector<XBlock*>& blocks, const block_t insertBlock, InMemoryZoneData& zoneData)
InMemoryZoneOutputStream(const unsigned pointerBitCount,
const unsigned zonePointerOffsetBitCount,
const unsigned zonePointerBlockBitCount,
std::vector<XBlock*>& blocks,
const block_t insertBlock,
InMemoryZoneData& zoneData)
: m_zone_data(zoneData),
m_blocks(blocks),
m_block_bit_count(blockBitCount),
m_pointer_byte_count(pointerBitCount / 8u),
m_zone_pointer_block_mask((std::numeric_limits<uintptr_t>::max() >> (sizeof(uintptr_t) * 8 - zonePointerBlockBitCount))
<< zonePointerOffsetBitCount),
m_zone_pointer_block_shift(zonePointerOffsetBitCount),
m_zone_pointer_offset_mask(std::numeric_limits<uintptr_t>::max() >> (sizeof(uintptr_t) * 8 - zonePointerOffsetBitCount)),
// -1
m_zone_ptr_following(std::numeric_limits<std::uintptr_t>::max() >> ((sizeof(std::uintptr_t) * 8u) - pointerBitCount)),
@@ -52,6 +59,7 @@ namespace
m_zone_ptr_insert((std::numeric_limits<std::uintptr_t>::max() >> ((sizeof(std::uintptr_t) * 8u) - pointerBitCount)) - 1u)
{
assert(pointerBitCount % 8u == 0u);
assert(zonePointerOffsetBitCount + zonePointerBlockBitCount <= pointerBitCount);
assert(insertBlock < static_cast<block_t>(blocks.size()));
m_insert_block = blocks[insertBlock];
@@ -288,8 +296,8 @@ namespace
assert(m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_NORMAL);
uintptr_t ptr = 0;
ptr |= static_cast<uintptr_t>(m_block_stack.top()->m_index) << (m_pointer_byte_count * 8 - m_block_bit_count);
ptr |= m_block_stack.top()->m_buffer_size & (UINTPTR_MAX >> (m_block_bit_count + (sizeof(uintptr_t) - m_pointer_byte_count) * 8));
ptr |= (static_cast<uintptr_t>(m_block_stack.top()->m_index) << m_zone_pointer_block_shift) & m_zone_pointer_block_mask;
ptr |= m_block_stack.top()->m_buffer_size & m_zone_pointer_offset_mask;
ptr++;
return ptr;
@@ -314,8 +322,10 @@ namespace
std::stack<XBlock*> m_block_stack;
std::stack<size_t> m_temp_sizes;
unsigned m_block_bit_count;
unsigned m_pointer_byte_count;
uintptr_t m_zone_pointer_block_mask;
unsigned m_zone_pointer_block_shift;
uintptr_t m_zone_pointer_offset_mask;
XBlock* m_insert_block;
uintptr_t m_zone_ptr_following;
@@ -350,10 +360,14 @@ void* ZoneOutputOffset::Offset() const
return m_offset;
}
std::unique_ptr<ZoneOutputStream>
ZoneOutputStream::Create(unsigned pointerBitCount, unsigned blockBitCount, std::vector<XBlock*>& blocks, block_t insertBlock, InMemoryZoneData& zoneData)
std::unique_ptr<ZoneOutputStream> ZoneOutputStream::Create(const unsigned pointerBitCount,
const unsigned zonePointerOffsetBitCount,
const unsigned zonePointerBlockBitCount,
std::vector<XBlock*>& blocks,
const block_t insertBlock,
InMemoryZoneData& zoneData)
{
return std::make_unique<InMemoryZoneOutputStream>(pointerBitCount, blockBitCount, blocks, insertBlock, zoneData);
return std::make_unique<InMemoryZoneOutputStream>(pointerBitCount, zonePointerOffsetBitCount, zonePointerBlockBitCount, blocks, insertBlock, zoneData);
}
ZoneStreamFillWriteAccessor::ZoneStreamFillWriteAccessor(void* blockBuffer, const size_t bufferSize)
@@ -143,6 +143,10 @@ public:
return WriteDataInBlock(dst, size);
}
static std::unique_ptr<ZoneOutputStream>
Create(unsigned pointerBitCount, unsigned blockBitCount, std::vector<XBlock*>& blocks, block_t insertBlock, InMemoryZoneData& zoneData);
static std::unique_ptr<ZoneOutputStream> Create(unsigned pointerBitCount,
unsigned zonePointerOffsetBitCount,
unsigned zonePointerBlockBitCount,
std::vector<XBlock*>& blocks,
block_t insertBlock,
InMemoryZoneData& zoneData);
};