[*] Untested bug fix: large compression frames were getting dropped
This commit is contained in:
parent
35e4d4bedc
commit
c256406053
@ -397,7 +397,42 @@ namespace Aurora::Memory
|
||||
}
|
||||
else
|
||||
{
|
||||
return endAtWrite ? (writePtr - readPtr) : (length - (readPtr - base));
|
||||
if (endAtWrite)
|
||||
{
|
||||
if (writePtr < readPtr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return writePtr - readPtr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return (length - (readPtr - base));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline AuUInt RemainingWrite(bool endAtRead = true)
|
||||
{
|
||||
if (flagCircular)
|
||||
{
|
||||
if ((writePtr < readPtr) && (endAtRead))
|
||||
{
|
||||
return length - (readPtr - writePtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto linearOverhead = length - (writePtr - base);
|
||||
auto toWriteOverhead = readPtr - base;
|
||||
return linearOverhead + toWriteOverhead;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return length - (writePtr - base);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,29 +83,37 @@ namespace Aurora::Compression
|
||||
return true;
|
||||
}
|
||||
|
||||
bool userBound_ {};
|
||||
char din_[ZSTD_BLOCKSIZE_MAX + 3 /*ZSTD_BLOCKHEADERSIZE*/];
|
||||
char dout_[ZSTD_BLOCKSIZE_MAX];
|
||||
ZSTD_inBuffer input_;
|
||||
|
||||
AuStreamReadWrittenPair_t Ingest(AuUInt32 input) override
|
||||
{
|
||||
AuUInt32 length = ZSTD_DStreamInSize();
|
||||
void *din = alloca(length);
|
||||
auto outFrameLength = ZSTD_DStreamOutSize();
|
||||
void *dout = alloca(outFrameLength);
|
||||
AuUInt32 outFrameLength = ZSTD_DStreamOutSize();
|
||||
AuUInt32 done{}, read{};
|
||||
|
||||
while (read != input)
|
||||
while (read != input || userBound_)
|
||||
{
|
||||
if (this->userBound_)
|
||||
{
|
||||
AuUInt32 request = std::min(input, length);
|
||||
if (this->reader_->Read(din, request) != IO::EStreamError::eErrorNone)
|
||||
if (this->reader_->Read(din_, request) != IO::EStreamError::eErrorNone)
|
||||
{
|
||||
return AuMakePair(read, done);
|
||||
}
|
||||
read += request;
|
||||
|
||||
ZSTD_inBuffer input = { din, request, 0 };
|
||||
while (input.pos < input.size)
|
||||
{
|
||||
ZSTD_outBuffer output = { dout, outFrameLength, 0 };
|
||||
input_ = ZSTD_inBuffer{ din_, request, 0 };
|
||||
}
|
||||
|
||||
auto ret = ZSTD_decompressStream(this->dctx_, &output, &input);
|
||||
while (input_.pos < input_.size)
|
||||
{
|
||||
auto maxWrite = std::min(outFrameLength, AuUInt32(this->_outbuffer.RemainingWrite()));
|
||||
ZSTD_outBuffer output = { dout_, outFrameLength, 0 };
|
||||
|
||||
auto ret = ZSTD_decompressStream(this->dctx_, &output, &input_);
|
||||
if (ZSTD_isError(ret))
|
||||
{
|
||||
SysPushErrorIO("Compression error: {}", ret);
|
||||
@ -116,6 +124,8 @@ namespace Aurora::Compression
|
||||
this->_outbuffer.Write(reinterpret_cast<const AuUInt8 *>(output.dst),
|
||||
output.pos);
|
||||
}
|
||||
|
||||
this->userBound_ = input_.pos != input_.size;
|
||||
}
|
||||
|
||||
return AuMakePair(read, done);
|
||||
@ -153,13 +163,17 @@ namespace Aurora::Compression
|
||||
return true;
|
||||
}
|
||||
|
||||
bool userBound_ {};
|
||||
|
||||
AuStreamReadWrittenPair_t Ingest(AuUInt32 input) override
|
||||
{
|
||||
int ret;
|
||||
|
||||
AuUInt32 done{}, read{};
|
||||
|
||||
while (read < input)
|
||||
while (read < input || userBound_)
|
||||
{
|
||||
if (!userBound_)
|
||||
{
|
||||
AuUInt32 request = std::min(input, AuUInt32(AuArraySize(din_)));
|
||||
if (this->reader_->Read(din_, request) != IO::EStreamError::eErrorNone)
|
||||
@ -171,10 +185,11 @@ namespace Aurora::Compression
|
||||
|
||||
this->ctx_.avail_in = request;
|
||||
this->ctx_.next_in = reinterpret_cast<unsigned char *>(din_);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
this->ctx_.avail_out = AuArraySize(dout_);
|
||||
this->ctx_.avail_out = std::min(AuUInt32(AuArraySize(dout_)), AuUInt32(this->_outbuffer.RemainingWrite()));
|
||||
this->ctx_.next_out = dout_;
|
||||
|
||||
if (!this->ctx_.avail_out)
|
||||
@ -196,7 +211,8 @@ namespace Aurora::Compression
|
||||
have);
|
||||
|
||||
} while (this->ctx_.avail_out == 0);
|
||||
SysAssert(this->ctx_.avail_in == 0);
|
||||
|
||||
this->userBound_ = this->ctx_.avail_in != 0;
|
||||
}
|
||||
|
||||
return AuMakePair(read, done);
|
||||
@ -237,12 +253,17 @@ namespace Aurora::Compression
|
||||
return true;
|
||||
}
|
||||
|
||||
bool userBound_ {};
|
||||
|
||||
AuStreamReadWrittenPair_t Ingest(AuUInt32 input) override
|
||||
{
|
||||
int ret;
|
||||
|
||||
AuUInt32 done{}, read{};
|
||||
while (read < input)
|
||||
while (read < input || userBound_)
|
||||
{
|
||||
|
||||
if (!userBound_)
|
||||
{
|
||||
AuUInt32 request = std::min(input, AuUInt32(AuArraySize(din_)));
|
||||
if (this->reader_->Read(din_, request) != IO::EStreamError::eErrorNone)
|
||||
@ -253,10 +274,11 @@ namespace Aurora::Compression
|
||||
|
||||
this->ctx_.avail_in = request;
|
||||
this->ctx_.next_in = reinterpret_cast<char *>(din_);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
this->ctx_.avail_out = AuArraySize(dout_);
|
||||
this->ctx_.avail_out = std::min(AuUInt32(AuArraySize(dout_)), AuUInt32(this->_outbuffer.RemainingWrite()));
|
||||
this->ctx_.next_out = dout_;
|
||||
|
||||
ret = BZ2_bzDecompress(&this->ctx_);
|
||||
@ -274,7 +296,8 @@ namespace Aurora::Compression
|
||||
|
||||
|
||||
} while (this->ctx_.avail_out == 0);
|
||||
SysAssert(this->ctx_.avail_in == 0);
|
||||
|
||||
this->userBound_ = this->ctx_.avail_in != 0;
|
||||
}
|
||||
|
||||
return AuMakePair(read, done);
|
||||
|
@ -37,46 +37,19 @@ namespace Aurora::Locale::Encoding
|
||||
// Convert the cpA buffer to UTF-16
|
||||
MultiByteToWideChar(cpA, 0, (LPCCH)in, inLength, ret, chars);
|
||||
|
||||
AuUInt32 utf16Recalc = chars;
|
||||
|
||||
if (!utf16Recalc)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// convert the shortened string with invalid surrogates back into a cpA length
|
||||
AuUInt32 read = inLength;
|
||||
|
||||
// always calc for now
|
||||
// handle **end of stream** and error trailing bytes
|
||||
#if 0
|
||||
if (slowPath)
|
||||
#endif
|
||||
{
|
||||
// Assumes A1 -> B -> A2 (A1 == A2), would GB2312 survive the round trip?
|
||||
// I know edge cases don't always map 1:1 with unicode
|
||||
// However, with all that struggle to maintain a codepage, would you have duplicate characters?
|
||||
// googling `GB2312 duplicate characters` and how translating works specifically is taking too long
|
||||
// this shoule be fine, i cope. worst case scenario, we end up with a stream jump x bytes bug
|
||||
// TODO: REVIEW ME
|
||||
read = WideCharToMultiByte(cpA, 0, ret, utf16Recalc, NULL, 0, NULL, NULL);
|
||||
|
||||
// skipping is one thing, but this would be really bad
|
||||
read = std::min(AuUInt32(read), AuUInt32(inLength));
|
||||
}
|
||||
|
||||
AuUInt32 cpLength;
|
||||
if (!cpBlob)
|
||||
{
|
||||
cpLength = WideCharToMultiByte(cpB, 0, ret, utf16Recalc, NULL, NULL, NULL, NULL);
|
||||
cpLength = WideCharToMultiByte(cpB, 0, ret, chars, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpLength = WideCharToMultiByte(cpB, 0, ret, utf16Recalc, (LPSTR)cpBlob, cpLen, NULL, NULL);
|
||||
cpLength = WideCharToMultiByte(cpB, 0, ret, chars, (LPSTR)cpBlob, cpLen, NULL, NULL);
|
||||
}
|
||||
|
||||
delete[] ret;
|
||||
return {read, cpLength};
|
||||
return {inLength, cpLength};
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user