LZMA decoder allows repeated calls to Code
This commit is contained in:
@@ -6,7 +6,8 @@ namespace SevenZip.Compression.LZ
|
|||||||
uint _pos;
|
uint _pos;
|
||||||
uint _windowSize = 0;
|
uint _windowSize = 0;
|
||||||
uint _streamPos;
|
uint _streamPos;
|
||||||
System.IO.Stream _stream;
|
uint _writePos;
|
||||||
|
internal System.IO.Stream _stream;
|
||||||
|
|
||||||
public uint TrainSize = 0;
|
public uint TrainSize = 0;
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ namespace SevenZip.Compression.LZ
|
|||||||
_windowSize = windowSize;
|
_windowSize = windowSize;
|
||||||
_pos = 0;
|
_pos = 0;
|
||||||
_streamPos = 0;
|
_streamPos = 0;
|
||||||
|
_writePos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init(System.IO.Stream stream, bool solid)
|
public void Init(System.IO.Stream stream, bool solid)
|
||||||
@@ -29,6 +31,7 @@ namespace SevenZip.Compression.LZ
|
|||||||
if (!solid)
|
if (!solid)
|
||||||
{
|
{
|
||||||
_streamPos = 0;
|
_streamPos = 0;
|
||||||
|
_writePos = 0;
|
||||||
_pos = 0;
|
_pos = 0;
|
||||||
TrainSize = 0;
|
TrainSize = 0;
|
||||||
}
|
}
|
||||||
@@ -40,7 +43,7 @@ namespace SevenZip.Compression.LZ
|
|||||||
uint size = (len < _windowSize) ? (uint)len : _windowSize;
|
uint size = (len < _windowSize) ? (uint)len : _windowSize;
|
||||||
TrainSize = size;
|
TrainSize = size;
|
||||||
stream.Position = len - size;
|
stream.Position = len - size;
|
||||||
_streamPos = _pos = 0;
|
_streamPos = _pos = _writePos = 0;
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
{
|
{
|
||||||
uint curSize = _windowSize - _pos;
|
uint curSize = _windowSize - _pos;
|
||||||
@@ -52,8 +55,9 @@ namespace SevenZip.Compression.LZ
|
|||||||
size -= (uint)numReadBytes;
|
size -= (uint)numReadBytes;
|
||||||
_pos += (uint)numReadBytes;
|
_pos += (uint)numReadBytes;
|
||||||
_streamPos += (uint)numReadBytes;
|
_streamPos += (uint)numReadBytes;
|
||||||
|
_writePos += (uint)numReadBytes;
|
||||||
if (_pos == _windowSize)
|
if (_pos == _windowSize)
|
||||||
_streamPos = _pos = 0;
|
_streamPos = _pos = _writePos = 0;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -64,15 +68,19 @@ namespace SevenZip.Compression.LZ
|
|||||||
_stream = null;
|
_stream = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Flush()
|
public void Flush(bool writeOnly = false, int avoidNewestCount = 0)
|
||||||
{
|
{
|
||||||
uint size = _pos - _streamPos;
|
int size = (int)(_pos - _writePos) - avoidNewestCount;
|
||||||
if (size == 0)
|
if (size <= 0)
|
||||||
return;
|
return;
|
||||||
_stream.Write(_buffer, (int)_streamPos, (int)size);
|
_stream.Write(_buffer, (int)_writePos, (int)size);
|
||||||
if (_pos >= _windowSize)
|
_writePos += (uint)size;
|
||||||
_pos = 0;
|
|
||||||
_streamPos = _pos;
|
if (!writeOnly) {
|
||||||
|
if (_pos >= _windowSize)
|
||||||
|
_pos = 0;
|
||||||
|
_streamPos = _pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyBlock(uint distance, uint len)
|
public void CopyBlock(uint distance, uint len)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace SevenZip.Compression.LZMA
|
|||||||
{
|
{
|
||||||
using RangeCoder;
|
using RangeCoder;
|
||||||
|
|
||||||
public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
|
public class Decoder //: ICoder, ISetDecoderProperties // ,System.IO.Stream
|
||||||
{
|
{
|
||||||
class LenDecoder
|
class LenDecoder
|
||||||
{
|
{
|
||||||
@@ -225,26 +225,33 @@ namespace SevenZip.Compression.LZMA
|
|||||||
m_PosAlignDecoder.Init();
|
m_PosAlignDecoder.Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Base.State state;
|
||||||
|
uint rep0, rep1, rep2, rep3;
|
||||||
|
UInt64 nowPos64;
|
||||||
public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
|
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;
|
UInt64 outSize64 = (UInt64)outSize;
|
||||||
if (nowPos64 < outSize64)
|
if (!noInit) {
|
||||||
{
|
Init(inStream, outStream);
|
||||||
if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)
|
state.Init();
|
||||||
throw new DataErrorException();
|
rep0 = 0; rep1 = 0; rep2 = 0; rep3 = 0;
|
||||||
state.UpdateChar();
|
nowPos64 = 0;
|
||||||
byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);
|
|
||||||
m_OutWindow.PutByte(b);
|
if (nowPos64 < outSize64)
|
||||||
nowPos64++;
|
{
|
||||||
|
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)
|
while (nowPos64 < outSize64)
|
||||||
{
|
{
|
||||||
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
|
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
|
||||||
@@ -339,9 +346,13 @@ namespace SevenZip.Compression.LZMA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_OutWindow.Flush();
|
|
||||||
m_OutWindow.ReleaseStream();
|
if (isLast) {
|
||||||
m_RangeDecoder.ReleaseStream();
|
m_OutWindow.Flush();
|
||||||
|
m_OutWindow.ReleaseStream();
|
||||||
|
m_RangeDecoder.ReleaseStream();
|
||||||
|
} else
|
||||||
|
m_OutWindow.Flush(writeOnly: true, (int)(nowPos64 - outSize64));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDecoderProperties(byte[] properties)
|
public void SetDecoderProperties(byte[] properties)
|
||||||
|
|||||||
Reference in New Issue
Block a user