From 745b9f974ab54772c092d61d81859f7eac10e816 Mon Sep 17 00:00:00 2001 From: Reece Wilson Date: Mon, 7 Nov 2022 22:46:35 +0000 Subject: [PATCH] [+] ByteBuffer::WriteFromEx [+] ByteBuffer::WriteFrom [*] Fix known path resolution quirks and missing compression staged change [+] ICompressionInterceptor::LimitHasHit [+] ICompressionInterceptor::LimitReset [+] ICompressionInterceptor::LimitSet [+] ICompressionInterceptor::LimitGetIndex --- .../Compression/CompressionInterceptor.hpp | 7 ++++ Include/Aurora/Memory/ByteBuffer.hpp | 4 +- .../Aurora/Memory/ByteBuffer_WriteFrom.inl | 33 +++++++++++++-- Source/Compression/CompressionInterceptor.cpp | 41 +++++++++++++++---- Source/Compression/CompressionInterceptor.hpp | 7 ++++ .../Compressors/ZSTDCompressor.hpp | 4 +- Source/IO/FS/FS.cpp | 39 +++++++++++++++++- 7 files changed, 120 insertions(+), 15 deletions(-) diff --git a/Include/Aurora/Compression/CompressionInterceptor.hpp b/Include/Aurora/Compression/CompressionInterceptor.hpp index 8c68e98a..b40fd309 100644 --- a/Include/Aurora/Compression/CompressionInterceptor.hpp +++ b/Include/Aurora/Compression/CompressionInterceptor.hpp @@ -14,6 +14,13 @@ namespace Aurora::Compression struct ICompressionInterceptor : IO::Protocol::IProtocolInterceptorEx { virtual bool HasFailed() = 0; + + // TODO (Reece): interface potential + + virtual bool LimitHasHit() = 0; + virtual void LimitReset() = 0; + virtual void LimitSet(AuUInt uLength) = 0; + virtual AuUInt LimitGetIndex() = 0; }; AUKN_SYM AuSPtr NewDecompressionInterceptor(const DecompressInfo &info); diff --git a/Include/Aurora/Memory/ByteBuffer.hpp b/Include/Aurora/Memory/ByteBuffer.hpp index f49d9fd1..962858ba 100644 --- a/Include/Aurora/Memory/ByteBuffer.hpp +++ b/Include/Aurora/Memory/ByteBuffer.hpp @@ -433,7 +433,9 @@ namespace Aurora::Memory inline bool ReadString(AuString &string, EStringType type = EStringType::eStringDword, Locale::ECodePage codepage = Locale::ECodePage::eUTF8); // Copy, concat, etc - inline bool WriteFrom(ByteBuffer &buffer, AuUInt length); + inline AuUInt WriteFromEx(ByteBuffer &buffer, + AuUInt uLength); + inline bool WriteFrom(ByteBuffer &buffer); // Utilities inline bool Trim(AuUInt tail); diff --git a/Include/Aurora/Memory/ByteBuffer_WriteFrom.inl b/Include/Aurora/Memory/ByteBuffer_WriteFrom.inl index b25cce73..29931233 100644 --- a/Include/Aurora/Memory/ByteBuffer_WriteFrom.inl +++ b/Include/Aurora/Memory/ByteBuffer_WriteFrom.inl @@ -2,15 +2,42 @@ Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: ByteBuffer_WriteFrom.inl - Date: 2022-2-15 + Date: 2022-11-07 Author: Reece ***/ #pragma once namespace Aurora::Memory { - bool ByteBuffer::WriteFrom(ByteBuffer &buffer, AuUInt length) + AuUInt ByteBuffer::WriteFromEx(ByteBuffer &buffer, + AuUInt uLength) { - return {}; + AuUInt uTotal {}; + bool bSuccess {}; + + do + { + auto readView = buffer.GetNextLinearRead(); + auto writeView = this->GetNextLinearWrite(); + + auto uMax = AuMin(readView.length, writeView.length); + uMax = AuMin(uTotal + uMax, uLength); + AuMemcpy(writeView.ptr, readView.ptr, uMax); + + this->writePtr += uMax; + buffer.readPtr += uMax; + uTotal += uTotal; + + bSuccess = uMax; + } + while (bSuccess); + + return uTotal; + } + + bool ByteBuffer::WriteFrom(ByteBuffer &buffer) + { + auto readable = buffer.RemainingBytes(); + return this->WriteFromEx(buffer, readable) == readable; } } \ No newline at end of file diff --git a/Source/Compression/CompressionInterceptor.cpp b/Source/Compression/CompressionInterceptor.cpp index 48080507..bea58996 100644 --- a/Source/Compression/CompressionInterceptor.cpp +++ b/Source/Compression/CompressionInterceptor.cpp @@ -31,13 +31,12 @@ namespace Aurora::Compression IO::EStreamError CompressionInterceptor::Read(const Memory::MemoryViewStreamWrite ¶meters) { - //if (auto pBuffer = this->pLastBuffer_.lock()) - { - parameters.outVariable = pLastBuffer_->Read(parameters.ptr, parameters.length); - return parameters.outVariable == 0 ? IO::EStreamError::eErrorEndOfStream : IO::EStreamError::eErrorNone; - } + auto uRemainingBytes = AuMin(this->uCount_ + parameters.length, + this->uCountMax_); - return IO::EStreamError::eErrorStreamNotOpen; + parameters.outVariable = pLastBuffer_->Read(parameters.ptr, uRemainingBytes); + this->uCount_ += parameters.outVariable; + return parameters.outVariable == 0 ? IO::EStreamError::eErrorEndOfStream : IO::EStreamError::eErrorNone; } void CompressionInterceptor::Close() @@ -69,6 +68,11 @@ namespace Aurora::Compression } while (bSuccess); + if (this->LimitHasHit()) + { + return pWriteOutByteBuffer->WriteFromEx(*pReadInByteBuffer, AuNumericLimits::max()); // intentionally non-ex. + } + if (!bSuccess) { this->bErrorFlag_ = true; @@ -77,7 +81,28 @@ namespace Aurora::Compression this->pBaseStream_->SetBuffer({}); return true; } - + + bool CompressionInterceptor::LimitHasHit() + { + return this->uCount_ >= this->uCountMax_; + } + + void CompressionInterceptor::LimitReset() + { + this->uCount_ = 0; + this->uCountMax_ = 0; + } + + AuUInt CompressionInterceptor::LimitGetIndex() + { + return this->uCount_; + } + + void CompressionInterceptor::LimitSet(AuUInt uLength) + { + this->uCountMax_ = uLength; + } + AUKN_SYM AuSPtr NewDecompressionInterceptor(const DecompressInfo &info) { auto pInterceptor = AuMakeShared(); @@ -117,7 +142,7 @@ namespace Aurora::Compression SysPushErrorMemory(); return {}; } - + pInterceptor->Init(pCompressor, AuStaticCast(pCompressor)); diff --git a/Source/Compression/CompressionInterceptor.hpp b/Source/Compression/CompressionInterceptor.hpp index 6ef0f058..83ec4c3d 100644 --- a/Source/Compression/CompressionInterceptor.hpp +++ b/Source/Compression/CompressionInterceptor.hpp @@ -27,6 +27,11 @@ namespace Aurora::Compression inline virtual void Close() override; + bool LimitHasHit() override; + void LimitReset() override; + void LimitSet(AuUInt uLength) override; + AuUInt LimitGetIndex() override; + bool HasFailed() override; private: @@ -34,5 +39,7 @@ namespace Aurora::Compression AuSPtr pStream_; AuSPtr pBaseStream_; AuSPtr pLastBuffer_; + AuUInt uCountMax_ { AuNumericLimits::max() }; + AuUInt uCount_ {}; }; } \ No newline at end of file diff --git a/Source/Compression/Compressors/ZSTDCompressor.hpp b/Source/Compression/Compressors/ZSTDCompressor.hpp index b57e22a0..24bcb006 100644 --- a/Source/Compression/Compressors/ZSTDCompressor.hpp +++ b/Source/Compression/Compressors/ZSTDCompressor.hpp @@ -211,8 +211,8 @@ namespace Aurora::Compression AuSPtr pReader_; ZSTD_CCtx *cctx_ {}; - char din_[ZSTD_BLOCKSIZE_MAX + 3]; - char dout_[ZSTD_BLOCKSIZE_MAX /*ZSTD_BLOCKHEADERSIZE*/]; + char din_[ZSTD_BLOCKSIZE_MAX]; + char dout_[ZSTD_COMPRESSBOUND(ZSTD_BLOCKSIZE_MAX) + 3 +/*ZSTD_BLOCKHEADERSIZE*/ + 4 /*32bit hash*/]; char *pIterator_ {}; AuUInt32 uAvailableIn_ {}; ZSTD_inBuffer input_ {}; diff --git a/Source/IO/FS/FS.cpp b/Source/IO/FS/FS.cpp index 6e09e339..f1c657a1 100644 --- a/Source/IO/FS/FS.cpp +++ b/Source/IO/FS/FS.cpp @@ -110,7 +110,7 @@ namespace Aurora::IO::FS { if (ch == "..") { - auto i = result.size() - 1; + auto i = result.size() - 1 - (result[result.size() - 1] == kPathSplitter); while (i >= 0 && result[i] != kPathSplitter) { --i; @@ -119,6 +119,7 @@ namespace Aurora::IO::FS if (i >= 0) { result.resize(i); + result += kPathSplitter; } continue; @@ -164,6 +165,42 @@ namespace Aurora::IO::FS bool requiresMountUpdate = false; requiresExpanding = str.size() && IsMagicCharacter(str[0]); + + if (str.size() == 1) + { + if (str[0] == '.' + // Win32 has no concept of a rootfs + // However, all users expect paths in userspace programs to assume CWD + // Since we are not on a NIX operating system, we can assume these mean CWD + #if defined(AURORA_IS_MODERNNT_DERIVED) + || + str[0] == '/' || + str[1] == '\\' + #endif + ) + { + AuProcess::GetWorkingDirectory(str); + return; + } + + if (str[0] == '^') + { + AuProcess::GetProcDirectory(str); + return; + } + + if (str[0] == '~') + { + AuFS::GetProfileDomain(str); + return; + } + + if (str[0] == '!') + { + AuFS::GetSystemDomain(str); + return; + } + } // best case -> O(n) wherein we merely check each BYTE with a handful of branch conditions int doubleDots = 0;