LZMA decoder allows repeated calls to Code

This commit is contained in:
2025-05-16 18:40:48 +00:00
parent d4d2c5a4cc
commit 53c4c16cd0
2 changed files with 49 additions and 30 deletions

View File

@@ -4,7 +4,7 @@ namespace SevenZip.Compression.LZMA
{
using RangeCoder;
public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
public class Decoder //: ICoder, ISetDecoderProperties // ,System.IO.Stream
{
class LenDecoder
{
@@ -225,26 +225,33 @@ namespace SevenZip.Compression.LZMA
m_PosAlignDecoder.Init();
}
Base.State state;
uint rep0, rep1, rep2, rep3;
UInt64 nowPos64;
public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
Int64 inSize, Int64 outSize, ICodeProgress progress)
Int64 inSize, Int64 outSize, ICodeProgress progress, bool noInit, bool isLast)
{
Init(inStream, outStream);
Base.State state = new Base.State();
state.Init();
uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
UInt64 nowPos64 = 0;
UInt64 outSize64 = (UInt64)outSize;
if (nowPos64 < outSize64)
{
if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)
throw new DataErrorException();
state.UpdateChar();
byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);
m_OutWindow.PutByte(b);
nowPos64++;
if (!noInit) {
Init(inStream, outStream);
state.Init();
rep0 = 0; rep1 = 0; rep2 = 0; rep3 = 0;
nowPos64 = 0;
if (nowPos64 < outSize64)
{
if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)
throw new DataErrorException();
state.UpdateChar();
byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);
m_OutWindow.PutByte(b);
nowPos64++;
}
} else {
m_RangeDecoder.Stream = inStream;
m_OutWindow._stream = outStream;
}
while (nowPos64 < outSize64)
{
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
@@ -339,9 +346,13 @@ namespace SevenZip.Compression.LZMA
}
}
}
m_OutWindow.Flush();
m_OutWindow.ReleaseStream();
m_RangeDecoder.ReleaseStream();
if (isLast) {
m_OutWindow.Flush();
m_OutWindow.ReleaseStream();
m_RangeDecoder.ReleaseStream();
} else
m_OutWindow.Flush(writeOnly: true, (int)(nowPos64 - outSize64));
}
public void SetDecoderProperties(byte[] properties)