LZMA decoder allows repeated calls to Code
This commit is contained in:
@@ -6,7 +6,8 @@ namespace SevenZip.Compression.LZ
|
||||
uint _pos;
|
||||
uint _windowSize = 0;
|
||||
uint _streamPos;
|
||||
System.IO.Stream _stream;
|
||||
uint _writePos;
|
||||
internal System.IO.Stream _stream;
|
||||
|
||||
public uint TrainSize = 0;
|
||||
|
||||
@@ -20,6 +21,7 @@ namespace SevenZip.Compression.LZ
|
||||
_windowSize = windowSize;
|
||||
_pos = 0;
|
||||
_streamPos = 0;
|
||||
_writePos = 0;
|
||||
}
|
||||
|
||||
public void Init(System.IO.Stream stream, bool solid)
|
||||
@@ -29,6 +31,7 @@ namespace SevenZip.Compression.LZ
|
||||
if (!solid)
|
||||
{
|
||||
_streamPos = 0;
|
||||
_writePos = 0;
|
||||
_pos = 0;
|
||||
TrainSize = 0;
|
||||
}
|
||||
@@ -40,7 +43,7 @@ namespace SevenZip.Compression.LZ
|
||||
uint size = (len < _windowSize) ? (uint)len : _windowSize;
|
||||
TrainSize = size;
|
||||
stream.Position = len - size;
|
||||
_streamPos = _pos = 0;
|
||||
_streamPos = _pos = _writePos = 0;
|
||||
while (size > 0)
|
||||
{
|
||||
uint curSize = _windowSize - _pos;
|
||||
@@ -52,8 +55,9 @@ namespace SevenZip.Compression.LZ
|
||||
size -= (uint)numReadBytes;
|
||||
_pos += (uint)numReadBytes;
|
||||
_streamPos += (uint)numReadBytes;
|
||||
_writePos += (uint)numReadBytes;
|
||||
if (_pos == _windowSize)
|
||||
_streamPos = _pos = 0;
|
||||
_streamPos = _pos = _writePos = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -64,15 +68,19 @@ namespace SevenZip.Compression.LZ
|
||||
_stream = null;
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
public void Flush(bool writeOnly = false, int avoidNewestCount = 0)
|
||||
{
|
||||
uint size = _pos - _streamPos;
|
||||
if (size == 0)
|
||||
int size = (int)(_pos - _writePos) - avoidNewestCount;
|
||||
if (size <= 0)
|
||||
return;
|
||||
_stream.Write(_buffer, (int)_streamPos, (int)size);
|
||||
if (_pos >= _windowSize)
|
||||
_pos = 0;
|
||||
_streamPos = _pos;
|
||||
_stream.Write(_buffer, (int)_writePos, (int)size);
|
||||
_writePos += (uint)size;
|
||||
|
||||
if (!writeOnly) {
|
||||
if (_pos >= _windowSize)
|
||||
_pos = 0;
|
||||
_streamPos = _pos;
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyBlock(uint distance, uint len)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user