mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-05-07 13:04:58 +00:00
refactor: merge ZoneInputStream interface with only implementation
This commit is contained in:
parent
4ce82ad63c
commit
eb16dfcd00
@ -244,7 +244,7 @@ namespace
|
||||
|
||||
void PrintHeaderConstructor() const
|
||||
{
|
||||
LINEF("{0}(Zone& zone, IZoneInputStream* stream);", LoaderClassName(m_env.m_asset))
|
||||
LINEF("{0}(Zone& zone, ZoneInputStream& stream);", LoaderClassName(m_env.m_asset))
|
||||
}
|
||||
|
||||
void PrintVariableInitialization(const DataDefinition* def) const
|
||||
@ -259,7 +259,7 @@ namespace
|
||||
|
||||
void PrintConstructorMethod()
|
||||
{
|
||||
LINEF("{0}::{0}(Zone& zone, IZoneInputStream* stream)", LoaderClassName(m_env.m_asset))
|
||||
LINEF("{0}::{0}(Zone& zone, ZoneInputStream& stream)", LoaderClassName(m_env.m_asset))
|
||||
|
||||
m_intendation++;
|
||||
LINE_STARTF(": AssetLoader({0}::EnumEntry, zone, stream)", m_env.m_asset->m_asset_name)
|
||||
@ -320,7 +320,7 @@ namespace
|
||||
|
||||
if (info && StructureComputations(info).IsAsset())
|
||||
{
|
||||
LINEF("{0} loader(m_zone, m_stream);", LoaderClassName(info))
|
||||
LINEF("{0} loader(m_zone, *m_stream);", LoaderClassName(info))
|
||||
LINEF("loader.Load({0});", MakeTypePtrVarName(def))
|
||||
}
|
||||
else
|
||||
@ -422,7 +422,7 @@ namespace
|
||||
{
|
||||
if (loadType == MemberLoadType::SINGLE_POINTER)
|
||||
{
|
||||
LINEF("{0} loader(m_zone, m_stream);", LoaderClassName(member->m_type))
|
||||
LINEF("{0} loader(m_zone, *m_stream);", LoaderClassName(member->m_type))
|
||||
LINEF("loader.Load(&{0});", MakeMemberAccess(info, member, modifier))
|
||||
}
|
||||
else if (loadType == MemberLoadType::POINTER_ARRAY)
|
||||
|
@ -68,7 +68,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
#define LOAD_ASSET(type_index, typeName, headerEntry) \
|
||||
case type_index: \
|
||||
{ \
|
||||
Loader_##typeName loader(m_zone, m_stream); \
|
||||
Loader_##typeName loader(m_zone, *m_stream); \
|
||||
loader.Load(&varXAsset->header.headerEntry); \
|
||||
break; \
|
||||
}
|
||||
@ -134,9 +134,9 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::Load(IZoneInputStream* stream)
|
||||
void ContentLoader::Load(ZoneInputStream& stream)
|
||||
{
|
||||
m_stream = stream;
|
||||
m_stream = &stream;
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
|
@ -11,7 +11,7 @@ namespace IW3
|
||||
public:
|
||||
explicit ContentLoader(Zone& zone);
|
||||
|
||||
void Load(IZoneInputStream* stream) override;
|
||||
void Load(ZoneInputStream& stream) override;
|
||||
|
||||
private:
|
||||
void LoadScriptStringList(bool atStreamStart);
|
||||
|
@ -78,7 +78,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
#define LOAD_ASSET(type_index, typeName, headerEntry) \
|
||||
case type_index: \
|
||||
{ \
|
||||
Loader_##typeName loader(m_zone, m_stream); \
|
||||
Loader_##typeName loader(m_zone, *m_stream); \
|
||||
loader.Load(&varXAsset->header.headerEntry); \
|
||||
break; \
|
||||
}
|
||||
@ -154,9 +154,9 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::Load(IZoneInputStream* stream)
|
||||
void ContentLoader::Load(ZoneInputStream& stream)
|
||||
{
|
||||
m_stream = stream;
|
||||
m_stream = &stream;
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
|
@ -11,7 +11,7 @@ namespace IW4
|
||||
public:
|
||||
explicit ContentLoader(Zone& zone);
|
||||
|
||||
void Load(IZoneInputStream* stream) override;
|
||||
void Load(ZoneInputStream& stream) override;
|
||||
|
||||
private:
|
||||
void LoadScriptStringList(bool atStreamStart);
|
||||
|
@ -83,7 +83,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
#define LOAD_ASSET(type_index, typeName, headerEntry) \
|
||||
case type_index: \
|
||||
{ \
|
||||
Loader_##typeName loader(m_zone, m_stream); \
|
||||
Loader_##typeName loader(m_zone, *m_stream); \
|
||||
loader.Load(&varXAsset->header.headerEntry); \
|
||||
break; \
|
||||
}
|
||||
@ -163,9 +163,9 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::Load(IZoneInputStream* stream)
|
||||
void ContentLoader::Load(ZoneInputStream& stream)
|
||||
{
|
||||
m_stream = stream;
|
||||
m_stream = &stream;
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
|
@ -11,7 +11,7 @@ namespace IW5
|
||||
public:
|
||||
explicit ContentLoader(Zone& zone);
|
||||
|
||||
void Load(IZoneInputStream* stream) override;
|
||||
void Load(ZoneInputStream& stream) override;
|
||||
|
||||
private:
|
||||
void LoadScriptStringList(bool atStreamStart);
|
||||
|
@ -75,7 +75,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
#define LOAD_ASSET(type_index, typeName, headerEntry) \
|
||||
case type_index: \
|
||||
{ \
|
||||
Loader_##typeName loader(m_zone, m_stream); \
|
||||
Loader_##typeName loader(m_zone, *m_stream); \
|
||||
loader.Load(&varXAsset->header.headerEntry); \
|
||||
break; \
|
||||
}
|
||||
@ -147,9 +147,9 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::Load(IZoneInputStream* stream)
|
||||
void ContentLoader::Load(ZoneInputStream& stream)
|
||||
{
|
||||
m_stream = stream;
|
||||
m_stream = &stream;
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
|
@ -11,7 +11,7 @@ namespace T5
|
||||
public:
|
||||
explicit ContentLoader(Zone& zone);
|
||||
|
||||
void Load(IZoneInputStream* stream) override;
|
||||
void Load(ZoneInputStream& stream) override;
|
||||
|
||||
private:
|
||||
void LoadScriptStringList(bool atStreamStart);
|
||||
|
@ -91,7 +91,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
#define LOAD_ASSET(type_index, typeName, headerEntry) \
|
||||
case type_index: \
|
||||
{ \
|
||||
Loader_##typeName loader(m_zone, m_stream); \
|
||||
Loader_##typeName loader(m_zone, *m_stream); \
|
||||
loader.Load(&varXAsset->header.headerEntry); \
|
||||
break; \
|
||||
}
|
||||
@ -176,9 +176,9 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::Load(IZoneInputStream* stream)
|
||||
void ContentLoader::Load(ZoneInputStream& stream)
|
||||
{
|
||||
m_stream = stream;
|
||||
m_stream = &stream;
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
|
@ -11,7 +11,7 @@ namespace T6
|
||||
public:
|
||||
explicit ContentLoader(Zone& zone);
|
||||
|
||||
void Load(IZoneInputStream* stream) override;
|
||||
void Load(ZoneInputStream& stream) override;
|
||||
|
||||
private:
|
||||
void LoadScriptStringList(bool atStreamStart);
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
AssetLoader::AssetLoader(const asset_type_t assetType, Zone& zone, IZoneInputStream* stream)
|
||||
AssetLoader::AssetLoader(const asset_type_t assetType, Zone& zone, ZoneInputStream& stream)
|
||||
: ContentLoaderBase(zone, stream),
|
||||
varScriptString(nullptr),
|
||||
m_asset_type(assetType)
|
||||
|
@ -9,7 +9,7 @@
|
||||
class AssetLoader : public ContentLoaderBase
|
||||
{
|
||||
protected:
|
||||
AssetLoader(asset_type_t assetType, Zone& zone, IZoneInputStream* stream);
|
||||
AssetLoader(asset_type_t assetType, Zone& zone, ZoneInputStream& stream);
|
||||
|
||||
XAssetInfoGeneric* LinkAsset(std::string name,
|
||||
void* asset,
|
||||
|
@ -10,11 +10,11 @@ ContentLoaderBase::ContentLoaderBase(Zone& zone)
|
||||
{
|
||||
}
|
||||
|
||||
ContentLoaderBase::ContentLoaderBase(Zone& zone, IZoneInputStream* stream)
|
||||
ContentLoaderBase::ContentLoaderBase(Zone& zone, ZoneInputStream& stream)
|
||||
: varXString(nullptr),
|
||||
m_zone(zone),
|
||||
m_memory(zone.Memory()),
|
||||
m_stream(stream)
|
||||
m_stream(&stream)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Zone/Stream/IZoneInputStream.h"
|
||||
#include "Zone/Stream/ZoneInputStream.h"
|
||||
#include "Zone/Zone.h"
|
||||
|
||||
class ContentLoaderBase
|
||||
@ -18,7 +18,7 @@ public:
|
||||
|
||||
protected:
|
||||
explicit ContentLoaderBase(Zone& zone);
|
||||
ContentLoaderBase(Zone& zone, IZoneInputStream* stream);
|
||||
ContentLoaderBase(Zone& zone, ZoneInputStream& stream);
|
||||
|
||||
void LoadXString(bool atStreamStart) const;
|
||||
void LoadXStringArray(bool atStreamStart, size_t count);
|
||||
@ -27,5 +27,5 @@ protected:
|
||||
|
||||
Zone& m_zone;
|
||||
MemoryManager& m_memory;
|
||||
IZoneInputStream* m_stream;
|
||||
ZoneInputStream* m_stream;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Zone/Stream/IZoneInputStream.h"
|
||||
#include "Zone/Stream/ZoneInputStream.h"
|
||||
|
||||
class IContentLoadingEntryPoint
|
||||
{
|
||||
@ -12,5 +12,5 @@ public:
|
||||
IContentLoadingEntryPoint& operator=(const IContentLoadingEntryPoint& other) = default;
|
||||
IContentLoadingEntryPoint& operator=(IContentLoadingEntryPoint&& other) noexcept = default;
|
||||
|
||||
virtual void Load(IZoneInputStream* stream) = 0;
|
||||
virtual void Load(ZoneInputStream& stream) = 0;
|
||||
};
|
||||
|
@ -15,5 +15,5 @@ public:
|
||||
ILoadingStep& operator=(const ILoadingStep& other) = default;
|
||||
ILoadingStep& operator=(ILoadingStep&& other) noexcept = default;
|
||||
|
||||
virtual void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) = 0;
|
||||
virtual void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) = 0;
|
||||
};
|
||||
|
@ -7,11 +7,10 @@ StepAddProcessor::StepAddProcessor(std::unique_ptr<StreamProcessor> streamProces
|
||||
{
|
||||
}
|
||||
|
||||
void StepAddProcessor::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepAddProcessor::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
assert(zoneLoader != nullptr);
|
||||
assert(m_stream_processor != nullptr);
|
||||
|
||||
zoneLoader->AddStreamProcessor(std::move(m_stream_processor));
|
||||
zoneLoader.AddStreamProcessor(std::move(m_stream_processor));
|
||||
m_stream_processor = nullptr;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ class StepAddProcessor final : public ILoadingStep
|
||||
public:
|
||||
explicit StepAddProcessor(std::unique_ptr<StreamProcessor> streamProcessor);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<StreamProcessor> m_stream_processor;
|
||||
|
@ -7,12 +7,12 @@ namespace
|
||||
constexpr uint64_t MAX_XBLOCK_SIZE = 0x3C000000;
|
||||
}
|
||||
|
||||
void StepAllocXBlocks::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepAllocXBlocks::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
const auto blockCount = static_cast<unsigned>(zoneLoader->m_blocks.size());
|
||||
const auto blockCount = static_cast<unsigned>(zoneLoader.m_blocks.size());
|
||||
|
||||
const auto blockSizes = std::make_unique<xblock_size_t[]>(blockCount);
|
||||
stream->Load(blockSizes.get(), sizeof(xblock_size_t) * blockCount);
|
||||
stream.Load(blockSizes.get(), sizeof(xblock_size_t) * blockCount);
|
||||
|
||||
uint64_t totalMemory = 0;
|
||||
for (unsigned int block = 0; block < blockCount; block++)
|
||||
@ -27,6 +27,6 @@ void StepAllocXBlocks::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* strea
|
||||
|
||||
for (unsigned int block = 0; block < blockCount; block++)
|
||||
{
|
||||
zoneLoader->m_blocks[block]->Alloc(blockSizes[block]);
|
||||
zoneLoader.m_blocks[block]->Alloc(blockSizes[block]);
|
||||
}
|
||||
}
|
||||
|
@ -5,5 +5,5 @@
|
||||
class StepAllocXBlocks final : public ILoadingStep
|
||||
{
|
||||
public:
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
};
|
||||
|
@ -7,7 +7,7 @@ StepDumpData::StepDumpData(const size_t dumpCount)
|
||||
{
|
||||
}
|
||||
|
||||
void StepDumpData::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepDumpData::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
uint8_t tempBuffer[128];
|
||||
auto dumpedBytes = 0uz;
|
||||
@ -27,7 +27,7 @@ void StepDumpData::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
toDump = sizeof(tempBuffer);
|
||||
}
|
||||
|
||||
const auto loadedSize = stream->Load(tempBuffer, toDump);
|
||||
const auto loadedSize = stream.Load(tempBuffer, toDump);
|
||||
dumpedBytes += loadedSize;
|
||||
|
||||
if (loadedSize == 0)
|
||||
|
@ -7,7 +7,7 @@ class StepDumpData final : public ILoadingStep
|
||||
public:
|
||||
explicit StepDumpData(size_t dumpCount);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
|
||||
private:
|
||||
size_t m_dump_count;
|
||||
|
@ -13,11 +13,9 @@ StepLoadHash::StepLoadHash(const size_t hashSize, const unsigned hashCount)
|
||||
|
||||
StepLoadHash::~StepLoadHash() = default;
|
||||
|
||||
void StepLoadHash::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepLoadHash::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
assert(stream != nullptr);
|
||||
|
||||
if (stream->Load(m_hashes.get(), m_hash_size * m_hash_count) != m_hash_size * m_hash_count)
|
||||
if (stream.Load(m_hashes.get(), m_hash_size * m_hash_count) != m_hash_size * m_hash_count)
|
||||
throw UnexpectedEndOfFileException();
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ public:
|
||||
StepLoadHash& operator=(const StepLoadHash& other) = delete;
|
||||
StepLoadHash& operator=(StepLoadHash&& other) noexcept = delete;
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
void GetHash(unsigned hashIndex, const uint8_t** pHash, size_t* pSize) override;
|
||||
void GetCapturedData(const uint8_t** pCapturedData, size_t* pSize) override;
|
||||
|
||||
|
@ -10,11 +10,9 @@ StepLoadSignature::StepLoadSignature(const size_t signatureSize)
|
||||
{
|
||||
}
|
||||
|
||||
void StepLoadSignature::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepLoadSignature::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
assert(stream != nullptr);
|
||||
|
||||
if (stream->Load(m_signature.get(), m_signature_size) != m_signature_size)
|
||||
if (stream.Load(m_signature.get(), m_signature_size) != m_signature_size)
|
||||
throw UnexpectedEndOfFileException();
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ class StepLoadSignature final : public ILoadingStep, public ISignatureProvider
|
||||
public:
|
||||
explicit StepLoadSignature(size_t signatureSize);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
void GetSignature(const uint8_t** pSignature, size_t* pSize) override;
|
||||
|
||||
private:
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "StepLoadZoneContent.h"
|
||||
|
||||
#include "Zone/Stream/Impl/XBlockInputStream.h"
|
||||
#include "Zone/Stream/ZoneInputStream.h"
|
||||
|
||||
StepLoadZoneContent::StepLoadZoneContent(std::unique_ptr<IContentLoadingEntryPoint> entryPoint,
|
||||
Zone* zone,
|
||||
@ -13,9 +13,9 @@ StepLoadZoneContent::StepLoadZoneContent(std::unique_ptr<IContentLoadingEntryPoi
|
||||
{
|
||||
}
|
||||
|
||||
void StepLoadZoneContent::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepLoadZoneContent::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
const auto inputStream = std::make_unique<XBlockInputStream>(zoneLoader->m_blocks, stream, m_offset_block_bit_count, m_insert_block);
|
||||
const auto inputStream = ZoneInputStream::Create(zoneLoader.m_blocks, stream, m_offset_block_bit_count, m_insert_block);
|
||||
|
||||
m_content_loader->Load(inputStream.get());
|
||||
m_content_loader->Load(*inputStream);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ class StepLoadZoneContent final : public ILoadingStep
|
||||
public:
|
||||
StepLoadZoneContent(std::unique_ptr<IContentLoadingEntryPoint> entryPoint, Zone* zone, int offsetBlockBitCount, block_t insertBlock);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<IContentLoadingEntryPoint> m_content_loader;
|
||||
|
@ -6,10 +6,10 @@ StepLoadZoneSizes::StepLoadZoneSizes()
|
||||
{
|
||||
}
|
||||
|
||||
void StepLoadZoneSizes::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepLoadZoneSizes::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
stream->Load(&m_size, sizeof(m_size));
|
||||
stream->Load(&m_external_size, sizeof(m_external_size));
|
||||
stream.Load(&m_size, sizeof(m_size));
|
||||
stream.Load(&m_external_size, sizeof(m_external_size));
|
||||
}
|
||||
|
||||
size_t StepLoadZoneSizes::GetSize() const
|
||||
|
@ -9,7 +9,7 @@ class StepLoadZoneSizes final : public ILoadingStep
|
||||
public:
|
||||
StepLoadZoneSizes();
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
|
||||
[[nodiscard]] size_t GetSize() const;
|
||||
[[nodiscard]] size_t GetExternalSize() const;
|
||||
|
@ -7,10 +7,9 @@ StepRemoveProcessor::StepRemoveProcessor(StreamProcessor* streamProcessor)
|
||||
{
|
||||
}
|
||||
|
||||
void StepRemoveProcessor::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepRemoveProcessor::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
assert(zoneLoader != nullptr);
|
||||
assert(m_stream_processor != nullptr);
|
||||
|
||||
zoneLoader->RemoveStreamProcessor(m_stream_processor);
|
||||
zoneLoader.RemoveStreamProcessor(m_stream_processor);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ class StepRemoveProcessor final : public ILoadingStep
|
||||
public:
|
||||
explicit StepRemoveProcessor(StreamProcessor* streamProcessor);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
|
||||
private:
|
||||
StreamProcessor* m_stream_processor;
|
||||
|
@ -5,7 +5,7 @@ StepSkipBytes::StepSkipBytes(const size_t skipCount)
|
||||
{
|
||||
}
|
||||
|
||||
void StepSkipBytes::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepSkipBytes::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
uint8_t tempBuffer[128];
|
||||
auto skippedBytes = 0uz;
|
||||
@ -23,7 +23,7 @@ void StepSkipBytes::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
toSkip = sizeof(tempBuffer);
|
||||
}
|
||||
|
||||
stream->Load(tempBuffer, toSkip);
|
||||
stream.Load(tempBuffer, toSkip);
|
||||
|
||||
skippedBytes += toSkip;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ class StepSkipBytes final : public ILoadingStep
|
||||
public:
|
||||
explicit StepSkipBytes(size_t skipCount);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
|
||||
private:
|
||||
size_t m_skip_count;
|
||||
|
@ -12,7 +12,7 @@ StepVerifyFileName::StepVerifyFileName(std::string fileName, const size_t fileNa
|
||||
m_expected_file_name.erase(m_file_name_buffer_size - 1);
|
||||
}
|
||||
|
||||
void StepVerifyFileName::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepVerifyFileName::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
std::stringstream originalFilenameStream;
|
||||
unsigned bufferOffset = 0;
|
||||
@ -20,8 +20,7 @@ void StepVerifyFileName::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* str
|
||||
|
||||
for (; bufferOffset < m_file_name_buffer_size; bufferOffset++)
|
||||
{
|
||||
|
||||
stream->Load(&c, sizeof(char));
|
||||
stream.Load(&c, sizeof(char));
|
||||
|
||||
if (c == '\00')
|
||||
{
|
||||
@ -35,7 +34,7 @@ void StepVerifyFileName::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* str
|
||||
// Skip the rest of the buffer which should be null bytes
|
||||
while (bufferOffset < m_file_name_buffer_size)
|
||||
{
|
||||
stream->Load(&c, sizeof(char));
|
||||
stream.Load(&c, sizeof(char));
|
||||
bufferOffset++;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ class StepVerifyFileName final : public ILoadingStep
|
||||
public:
|
||||
explicit StepVerifyFileName(std::string fileName, size_t fileNameBufferSize);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
|
||||
private:
|
||||
std::string m_expected_file_name;
|
||||
|
@ -16,7 +16,7 @@ StepVerifyHash::StepVerifyHash(std::unique_ptr<cryptography::IHashFunction> hash
|
||||
{
|
||||
}
|
||||
|
||||
void StepVerifyHash::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepVerifyHash::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
const uint8_t* dataToHash = nullptr;
|
||||
size_t dataToHashSize = 0;
|
||||
|
@ -15,7 +15,7 @@ public:
|
||||
IHashProvider* hashProvider,
|
||||
ICapturedDataProvider* dataProvider);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<cryptography::IHashFunction> m_hash_function;
|
||||
|
@ -10,13 +10,13 @@ StepVerifyMagic::StepVerifyMagic(const char* magic)
|
||||
m_magic_len = strlen(m_magic);
|
||||
}
|
||||
|
||||
void StepVerifyMagic::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepVerifyMagic::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
char currentCharacter;
|
||||
|
||||
for (unsigned i = 0; i < m_magic_len; i++)
|
||||
{
|
||||
stream->Load(¤tCharacter, sizeof(char));
|
||||
stream.Load(¤tCharacter, sizeof(char));
|
||||
|
||||
if (currentCharacter != m_magic[i])
|
||||
throw InvalidMagicException(m_magic);
|
||||
|
@ -7,7 +7,7 @@ class StepVerifyMagic final : public ILoadingStep
|
||||
public:
|
||||
explicit StepVerifyMagic(const char* magic);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
|
||||
private:
|
||||
const char* m_magic;
|
||||
|
@ -13,7 +13,7 @@ StepVerifySignature::StepVerifySignature(std::unique_ptr<cryptography::IPublicKe
|
||||
{
|
||||
}
|
||||
|
||||
void StepVerifySignature::PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream)
|
||||
void StepVerifySignature::PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream)
|
||||
{
|
||||
assert(m_algorithm != nullptr);
|
||||
assert(m_signature_provider != nullptr);
|
||||
|
@ -12,7 +12,7 @@ public:
|
||||
ISignatureProvider* signatureProvider,
|
||||
ICapturedDataProvider* signatureDataProvider);
|
||||
|
||||
void PerformStep(ZoneLoader* zoneLoader, ILoadingStream* stream) override;
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<cryptography::IPublicKeyAlgorithm> m_algorithm;
|
||||
|
@ -4,6 +4,9 @@
|
||||
#include "LoadingFileStream.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
ZoneLoader::ZoneLoader(std::unique_ptr<Zone> zone)
|
||||
: m_processor_chain_dirty(false),
|
||||
@ -31,7 +34,7 @@ void ZoneLoader::AddXBlock(std::unique_ptr<XBlock> block)
|
||||
m_blocks.push_back(block.get());
|
||||
|
||||
std::ranges::sort(m_blocks,
|
||||
[](XBlock* b1, XBlock* b2) -> bool
|
||||
[](const XBlock* b1, const XBlock* b2) -> bool
|
||||
{
|
||||
return b1->m_index < b2->m_index;
|
||||
});
|
||||
@ -50,7 +53,7 @@ void ZoneLoader::AddStreamProcessor(std::unique_ptr<StreamProcessor> streamProce
|
||||
m_processor_chain_dirty = true;
|
||||
}
|
||||
|
||||
void ZoneLoader::RemoveStreamProcessor(StreamProcessor* streamProcessor)
|
||||
void ZoneLoader::RemoveStreamProcessor(const StreamProcessor* streamProcessor)
|
||||
{
|
||||
for (auto i = m_processors.begin(); i < m_processors.end(); ++i)
|
||||
{
|
||||
@ -67,23 +70,24 @@ std::unique_ptr<Zone> ZoneLoader::LoadZone(std::istream& stream)
|
||||
{
|
||||
LoadingFileStream fileStream(stream);
|
||||
auto* endStream = BuildLoadingChain(&fileStream);
|
||||
assert(endStream);
|
||||
|
||||
try
|
||||
{
|
||||
for (const auto& step : m_steps)
|
||||
{
|
||||
step->PerformStep(this, endStream);
|
||||
step->PerformStep(*this, *endStream);
|
||||
|
||||
if (m_processor_chain_dirty)
|
||||
{
|
||||
endStream = BuildLoadingChain(&fileStream);
|
||||
assert(endStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (LoadingException& e)
|
||||
{
|
||||
const auto detailedMessage = e.DetailedMessage();
|
||||
printf("Loading fastfile failed: %s\n", detailedMessage.c_str());
|
||||
std::cerr << std::format("Loading fastfile failed: {}\n", e.DetailedMessage());
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
void AddLoadingStep(std::unique_ptr<ILoadingStep> step);
|
||||
void AddStreamProcessor(std::unique_ptr<StreamProcessor> streamProcessor);
|
||||
|
||||
void RemoveStreamProcessor(StreamProcessor* streamProcessor);
|
||||
void RemoveStreamProcessor(const StreamProcessor* streamProcessor);
|
||||
|
||||
std::unique_ptr<Zone> LoadZone(std::istream& stream);
|
||||
|
||||
|
@ -1,248 +0,0 @@
|
||||
#include "XBlockInputStream.h"
|
||||
|
||||
#include "Loading/Exception/BlockOverflowException.h"
|
||||
#include "Loading/Exception/InvalidOffsetBlockException.h"
|
||||
#include "Loading/Exception/InvalidOffsetBlockOffsetException.h"
|
||||
#include "Loading/Exception/OutOfBlockBoundsException.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
XBlockInputStream::XBlockInputStream(std::vector<XBlock*>& blocks, ILoadingStream* stream, const int blockBitCount, const block_t insertBlock)
|
||||
: m_blocks(blocks)
|
||||
{
|
||||
m_stream = stream;
|
||||
|
||||
const auto blockCount = static_cast<unsigned>(blocks.size());
|
||||
m_block_offsets = std::make_unique<size_t[]>(blockCount);
|
||||
std::memset(m_block_offsets.get(), 0, sizeof(size_t) * blockCount);
|
||||
|
||||
m_block_bit_count = blockBitCount;
|
||||
|
||||
assert(insertBlock < static_cast<block_t>(blocks.size()));
|
||||
m_insert_block = blocks[insertBlock];
|
||||
}
|
||||
|
||||
void XBlockInputStream::Align(const unsigned align)
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (align > 0)
|
||||
{
|
||||
const block_t blockIndex = m_block_stack.top()->m_index;
|
||||
m_block_offsets[blockIndex] = (m_block_offsets[blockIndex] + align - 1u) / align * align;
|
||||
}
|
||||
}
|
||||
|
||||
void XBlockInputStream::PushBlock(const block_t block)
|
||||
{
|
||||
assert(block < static_cast<block_t>(m_blocks.size()));
|
||||
|
||||
XBlock* newBlock = m_blocks[block];
|
||||
|
||||
assert(newBlock->m_index == block);
|
||||
|
||||
m_block_stack.push(newBlock);
|
||||
|
||||
if (newBlock->m_type == XBlock::Type::BLOCK_TYPE_TEMP)
|
||||
{
|
||||
m_temp_offsets.push(m_block_offsets[newBlock->m_index]);
|
||||
}
|
||||
}
|
||||
|
||||
block_t XBlockInputStream::PopBlock()
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return -1;
|
||||
|
||||
const XBlock* poppedBlock = m_block_stack.top();
|
||||
|
||||
m_block_stack.pop();
|
||||
|
||||
// If the temp block is not used anymore right now, reset it to the buffer start since as the name suggests, the data inside is temporary.
|
||||
if (poppedBlock->m_type == XBlock::Type::BLOCK_TYPE_TEMP)
|
||||
{
|
||||
m_block_offsets[poppedBlock->m_index] = m_temp_offsets.top();
|
||||
m_temp_offsets.pop();
|
||||
}
|
||||
|
||||
return poppedBlock->m_index;
|
||||
}
|
||||
|
||||
void* XBlockInputStream::Alloc(const unsigned align)
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return nullptr;
|
||||
|
||||
XBlock* block = m_block_stack.top();
|
||||
|
||||
Align(align);
|
||||
|
||||
if (m_block_offsets[block->m_index] > block->m_buffer_size)
|
||||
{
|
||||
throw BlockOverflowException(block);
|
||||
}
|
||||
|
||||
return &block->m_buffer[m_block_offsets[block->m_index]];
|
||||
}
|
||||
|
||||
void XBlockInputStream::LoadDataRaw(void* dst, const size_t size)
|
||||
{
|
||||
m_stream->Load(dst, size);
|
||||
}
|
||||
|
||||
void XBlockInputStream::LoadDataInBlock(void* dst, const size_t size)
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return;
|
||||
|
||||
XBlock* block = m_block_stack.top();
|
||||
|
||||
if (block->m_buffer > dst || block->m_buffer + block->m_buffer_size < dst)
|
||||
{
|
||||
throw OutOfBlockBoundsException(block);
|
||||
}
|
||||
|
||||
if (static_cast<uint8_t*>(dst) + size > block->m_buffer + block->m_buffer_size)
|
||||
{
|
||||
throw BlockOverflowException(block);
|
||||
}
|
||||
|
||||
// Theoretically ptr should always be at the current block offset.
|
||||
assert(dst == &block->m_buffer[m_block_offsets[block->m_index]]);
|
||||
|
||||
switch (block->m_type)
|
||||
{
|
||||
case XBlock::Type::BLOCK_TYPE_TEMP:
|
||||
case XBlock::Type::BLOCK_TYPE_NORMAL:
|
||||
m_stream->Load(dst, size);
|
||||
break;
|
||||
|
||||
case XBlock::Type::BLOCK_TYPE_RUNTIME:
|
||||
memset(dst, 0, size);
|
||||
break;
|
||||
|
||||
case XBlock::Type::BLOCK_TYPE_DELAY:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
IncBlockPos(size);
|
||||
}
|
||||
|
||||
void XBlockInputStream::IncBlockPos(const size_t size)
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return;
|
||||
|
||||
const XBlock* block = m_block_stack.top();
|
||||
m_block_offsets[block->m_index] += size;
|
||||
}
|
||||
|
||||
void XBlockInputStream::LoadNullTerminated(void* dst)
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return;
|
||||
|
||||
XBlock* block = m_block_stack.top();
|
||||
|
||||
if (block->m_buffer > dst || block->m_buffer + block->m_buffer_size < dst)
|
||||
{
|
||||
throw OutOfBlockBoundsException(block);
|
||||
}
|
||||
|
||||
// Theoretically ptr should always be at the current block offset.
|
||||
assert(dst == &block->m_buffer[m_block_offsets[block->m_index]]);
|
||||
|
||||
uint8_t byte;
|
||||
size_t offset = static_cast<uint8_t*>(dst) - block->m_buffer;
|
||||
do
|
||||
{
|
||||
if (offset >= block->m_buffer_size)
|
||||
{
|
||||
throw BlockOverflowException(block);
|
||||
}
|
||||
|
||||
m_stream->Load(&byte, 1);
|
||||
block->m_buffer[offset++] = byte;
|
||||
} while (byte != 0);
|
||||
|
||||
m_block_offsets[block->m_index] = offset;
|
||||
}
|
||||
|
||||
void** XBlockInputStream::InsertPointer()
|
||||
{
|
||||
m_block_stack.push(m_insert_block);
|
||||
|
||||
Align(alignof(void*));
|
||||
|
||||
if (m_block_offsets[m_insert_block->m_index] + sizeof(void*) > m_insert_block->m_buffer_size)
|
||||
{
|
||||
throw BlockOverflowException(m_insert_block);
|
||||
}
|
||||
|
||||
auto* ptr = reinterpret_cast<void**>(&m_insert_block->m_buffer[m_block_offsets[m_insert_block->m_index]]);
|
||||
|
||||
IncBlockPos(sizeof(void*));
|
||||
|
||||
m_block_stack.pop();
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* XBlockInputStream::ConvertOffsetToPointer(const void* offset)
|
||||
{
|
||||
// -1 because otherwise Block 0 Offset 0 would be just 0 which is already used to signalize a nullptr.
|
||||
// So all offsets are moved by 1.
|
||||
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
|
||||
|
||||
const block_t blockNum = static_cast<block_t>(offsetInt >> (sizeof(offsetInt) * 8u - m_block_bit_count));
|
||||
const size_t blockOffset = offsetInt & (UINTPTR_MAX >> m_block_bit_count);
|
||||
|
||||
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
{
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
}
|
||||
|
||||
XBlock* block = m_blocks[blockNum];
|
||||
|
||||
if (block->m_buffer_size <= blockOffset)
|
||||
{
|
||||
throw InvalidOffsetBlockOffsetException(block, blockOffset);
|
||||
}
|
||||
|
||||
return &block->m_buffer[blockOffset];
|
||||
}
|
||||
|
||||
void* XBlockInputStream::ConvertOffsetToAlias(const void* offset)
|
||||
{
|
||||
// For details see ConvertOffsetToPointer
|
||||
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1;
|
||||
|
||||
const block_t blockNum = static_cast<block_t>(offsetInt >> (sizeof(offsetInt) * 8 - m_block_bit_count));
|
||||
const size_t blockOffset = offsetInt & (UINTPTR_MAX >> m_block_bit_count);
|
||||
|
||||
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
{
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
}
|
||||
|
||||
XBlock* block = m_blocks[blockNum];
|
||||
|
||||
if (block->m_buffer_size <= blockOffset + sizeof(void*))
|
||||
{
|
||||
throw InvalidOffsetBlockOffsetException(block, blockOffset);
|
||||
}
|
||||
|
||||
return *reinterpret_cast<void**>(&block->m_buffer[blockOffset]);
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/ILoadingStream.h"
|
||||
#include "Zone/Stream/IZoneInputStream.h"
|
||||
#include "Zone/XBlock.h"
|
||||
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
||||
class XBlockInputStream final : public IZoneInputStream
|
||||
{
|
||||
public:
|
||||
XBlockInputStream(std::vector<XBlock*>& blocks, ILoadingStream* stream, int blockBitCount, block_t insertBlock);
|
||||
|
||||
void PushBlock(block_t block) override;
|
||||
block_t PopBlock() override;
|
||||
|
||||
void* Alloc(unsigned align) override;
|
||||
|
||||
void LoadDataRaw(void* dst, size_t size) override;
|
||||
void LoadDataInBlock(void* dst, size_t size) override;
|
||||
void IncBlockPos(size_t size) override;
|
||||
void LoadNullTerminated(void* dst) override;
|
||||
|
||||
void** InsertPointer() override;
|
||||
|
||||
void* ConvertOffsetToPointer(const void* offset) override;
|
||||
void* ConvertOffsetToAlias(const void* offset) override;
|
||||
|
||||
private:
|
||||
void Align(unsigned align);
|
||||
|
||||
std::vector<XBlock*>& m_blocks;
|
||||
std::unique_ptr<size_t[]> m_block_offsets;
|
||||
|
||||
std::stack<XBlock*> m_block_stack;
|
||||
std::stack<size_t> m_temp_offsets;
|
||||
ILoadingStream* m_stream;
|
||||
|
||||
unsigned m_block_bit_count;
|
||||
XBlock* m_insert_block;
|
||||
};
|
248
src/ZoneLoading/Zone/Stream/ZoneInputStream.cpp
Normal file
248
src/ZoneLoading/Zone/Stream/ZoneInputStream.cpp
Normal file
@ -0,0 +1,248 @@
|
||||
#include "ZoneInputStream.h"
|
||||
|
||||
#include "Loading/Exception/BlockOverflowException.h"
|
||||
#include "Loading/Exception/InvalidOffsetBlockException.h"
|
||||
#include "Loading/Exception/InvalidOffsetBlockOffsetException.h"
|
||||
#include "Loading/Exception/OutOfBlockBoundsException.h"
|
||||
#include "Utils/Alignment.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <stack>
|
||||
|
||||
namespace
|
||||
{
|
||||
class XBlockInputStream final : public ZoneInputStream
|
||||
{
|
||||
public:
|
||||
XBlockInputStream(std::vector<XBlock*>& blocks, ILoadingStream& stream, const unsigned blockBitCount, const block_t insertBlock)
|
||||
: m_blocks(blocks),
|
||||
m_stream(stream)
|
||||
{
|
||||
const auto blockCount = static_cast<unsigned>(blocks.size());
|
||||
m_block_offsets = std::make_unique<size_t[]>(blockCount);
|
||||
std::memset(m_block_offsets.get(), 0, sizeof(size_t) * blockCount);
|
||||
|
||||
m_block_bit_count = blockBitCount;
|
||||
|
||||
assert(insertBlock < static_cast<block_t>(blocks.size()));
|
||||
m_insert_block = blocks[insertBlock];
|
||||
}
|
||||
|
||||
void PushBlock(const block_t block) override
|
||||
{
|
||||
assert(block < static_cast<block_t>(m_blocks.size()));
|
||||
|
||||
auto* newBlock = m_blocks[block];
|
||||
assert(newBlock->m_index == block);
|
||||
|
||||
m_block_stack.push(newBlock);
|
||||
|
||||
if (newBlock->m_type == XBlock::Type::BLOCK_TYPE_TEMP)
|
||||
m_temp_offsets.push(m_block_offsets[newBlock->m_index]);
|
||||
}
|
||||
|
||||
block_t PopBlock() override
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return -1;
|
||||
|
||||
const auto* poppedBlock = m_block_stack.top();
|
||||
|
||||
m_block_stack.pop();
|
||||
|
||||
// If the temp block is not used anymore right now, reset it to the buffer start since as the name suggests, the data inside is temporary.
|
||||
if (poppedBlock->m_type == XBlock::Type::BLOCK_TYPE_TEMP)
|
||||
{
|
||||
m_block_offsets[poppedBlock->m_index] = m_temp_offsets.top();
|
||||
m_temp_offsets.pop();
|
||||
}
|
||||
|
||||
return poppedBlock->m_index;
|
||||
}
|
||||
|
||||
void* Alloc(const unsigned align) override
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return nullptr;
|
||||
|
||||
auto* block = m_block_stack.top();
|
||||
|
||||
Align(align);
|
||||
|
||||
if (m_block_offsets[block->m_index] > block->m_buffer_size)
|
||||
throw BlockOverflowException(block);
|
||||
|
||||
return &block->m_buffer[m_block_offsets[block->m_index]];
|
||||
}
|
||||
|
||||
void LoadDataRaw(void* dst, const size_t size) override
|
||||
{
|
||||
m_stream.Load(dst, size);
|
||||
}
|
||||
|
||||
void LoadDataInBlock(void* dst, const size_t size) override
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return;
|
||||
|
||||
auto* block = m_block_stack.top();
|
||||
|
||||
if (block->m_buffer > dst || block->m_buffer + block->m_buffer_size < dst)
|
||||
throw OutOfBlockBoundsException(block);
|
||||
|
||||
if (static_cast<uint8_t*>(dst) + size > block->m_buffer + block->m_buffer_size)
|
||||
throw BlockOverflowException(block);
|
||||
|
||||
// Theoretically ptr should always be at the current block offset.
|
||||
assert(dst == &block->m_buffer[m_block_offsets[block->m_index]]);
|
||||
|
||||
switch (block->m_type)
|
||||
{
|
||||
case XBlock::Type::BLOCK_TYPE_TEMP:
|
||||
case XBlock::Type::BLOCK_TYPE_NORMAL:
|
||||
m_stream.Load(dst, size);
|
||||
break;
|
||||
|
||||
case XBlock::Type::BLOCK_TYPE_RUNTIME:
|
||||
memset(dst, 0, size);
|
||||
break;
|
||||
|
||||
case XBlock::Type::BLOCK_TYPE_DELAY:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
IncBlockPos(size);
|
||||
}
|
||||
|
||||
void IncBlockPos(const size_t size) override
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return;
|
||||
|
||||
const auto* block = m_block_stack.top();
|
||||
m_block_offsets[block->m_index] += size;
|
||||
}
|
||||
|
||||
void LoadNullTerminated(void* dst) override
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return;
|
||||
|
||||
auto* block = m_block_stack.top();
|
||||
|
||||
if (block->m_buffer > dst || block->m_buffer + block->m_buffer_size < dst)
|
||||
throw OutOfBlockBoundsException(block);
|
||||
|
||||
// Theoretically ptr should always be at the current block offset.
|
||||
assert(dst == &block->m_buffer[m_block_offsets[block->m_index]]);
|
||||
|
||||
uint8_t byte;
|
||||
auto offset = static_cast<size_t>(static_cast<uint8_t*>(dst) - block->m_buffer);
|
||||
do
|
||||
{
|
||||
if (offset >= block->m_buffer_size)
|
||||
throw BlockOverflowException(block);
|
||||
|
||||
m_stream.Load(&byte, 1);
|
||||
block->m_buffer[offset++] = byte;
|
||||
} while (byte != 0);
|
||||
|
||||
m_block_offsets[block->m_index] = offset;
|
||||
}
|
||||
|
||||
void** InsertPointer() override
|
||||
{
|
||||
m_block_stack.push(m_insert_block);
|
||||
|
||||
Align(alignof(void*));
|
||||
|
||||
if (m_block_offsets[m_insert_block->m_index] + sizeof(void*) > m_insert_block->m_buffer_size)
|
||||
throw BlockOverflowException(m_insert_block);
|
||||
|
||||
auto* ptr = reinterpret_cast<void**>(&m_insert_block->m_buffer[m_block_offsets[m_insert_block->m_index]]);
|
||||
|
||||
IncBlockPos(sizeof(void*));
|
||||
|
||||
m_block_stack.pop();
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* ConvertOffsetToPointer(const void* offset) override
|
||||
{
|
||||
// -1 because otherwise Block 0 Offset 0 would be just 0 which is already used to signalize a nullptr.
|
||||
// So all offsets are moved by 1.
|
||||
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
|
||||
|
||||
const auto blockNum = static_cast<block_t>(offsetInt >> (sizeof(offsetInt) * 8u - m_block_bit_count));
|
||||
const auto blockOffset = static_cast<size_t>(offsetInt & (UINTPTR_MAX >> m_block_bit_count));
|
||||
|
||||
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
|
||||
auto* block = m_blocks[blockNum];
|
||||
|
||||
if (block->m_buffer_size <= blockOffset)
|
||||
throw InvalidOffsetBlockOffsetException(block, blockOffset);
|
||||
|
||||
return &block->m_buffer[blockOffset];
|
||||
}
|
||||
|
||||
void* ConvertOffsetToAlias(const void* offset) override
|
||||
{
|
||||
// For details see ConvertOffsetToPointer
|
||||
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
|
||||
|
||||
const auto blockNum = static_cast<block_t>(offsetInt >> (sizeof(offsetInt) * 8u - m_block_bit_count));
|
||||
const auto blockOffset = static_cast<size_t>(offsetInt & (UINTPTR_MAX >> m_block_bit_count));
|
||||
|
||||
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
|
||||
auto* block = m_blocks[blockNum];
|
||||
|
||||
if (block->m_buffer_size <= blockOffset + sizeof(void*))
|
||||
throw InvalidOffsetBlockOffsetException(block, blockOffset);
|
||||
|
||||
return *reinterpret_cast<void**>(&block->m_buffer[blockOffset]);
|
||||
}
|
||||
|
||||
private:
|
||||
void Align(const unsigned align)
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (align > 0)
|
||||
{
|
||||
const auto blockIndex = m_block_stack.top()->m_index;
|
||||
m_block_offsets[blockIndex] = utils::Align(m_block_offsets[blockIndex], static_cast<size_t>(align));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<XBlock*>& m_blocks;
|
||||
std::unique_ptr<size_t[]> m_block_offsets;
|
||||
|
||||
std::stack<XBlock*> m_block_stack;
|
||||
std::stack<size_t> m_temp_offsets;
|
||||
ILoadingStream& m_stream;
|
||||
|
||||
unsigned m_block_bit_count;
|
||||
XBlock* m_insert_block;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<ZoneInputStream> ZoneInputStream::Create(std::vector<XBlock*>& blocks, ILoadingStream& stream, unsigned blockBitCount, block_t insertBlock)
|
||||
{
|
||||
return std::make_unique<XBlockInputStream>(blocks, stream, blockBitCount, insertBlock);
|
||||
}
|
@ -1,11 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/ILoadingStream.h"
|
||||
#include "Zone/Stream/IZoneStream.h"
|
||||
#include "Zone/XBlock.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class IZoneInputStream : public IZoneStream
|
||||
class ZoneInputStream : public IZoneStream
|
||||
{
|
||||
public:
|
||||
virtual void* Alloc(unsigned align) = 0;
|
||||
@ -55,4 +57,6 @@ public:
|
||||
{
|
||||
return static_cast<T*>(ConvertOffsetToAlias(static_cast<const void*>(offset)));
|
||||
}
|
||||
|
||||
static std::unique_ptr<ZoneInputStream> Create(std::vector<XBlock*>& blocks, ILoadingStream& stream, unsigned blockBitCount, block_t insertBlock);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user