mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-10-24 12:38:10 +00:00
fix: zone pointer offset bit count may be independent from platform pointer size
This commit is contained in:
29 files changed
+171
-74
No files matched your search
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
Reference in new issue
Block a user