mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-11 12:07:12 -06:00
9.13
This commit is contained in:
committed by
Kornel Lesiński
parent
76b173af78
commit
3dacb5eb8a
@@ -24,9 +24,10 @@ static HRESULT SResToHRESULT(SRes res)
|
||||
namespace NCompress {
|
||||
namespace NLzma {
|
||||
|
||||
static const UInt32 kInBufSize = 1 << 20;
|
||||
|
||||
CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false), FinishStream(false)
|
||||
CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false),
|
||||
_inBufSize(1 << 20),
|
||||
_outBufSize(1 << 22),
|
||||
FinishStream(false)
|
||||
{
|
||||
_inSizeProcessed = 0;
|
||||
_inPos = _inSize = 0;
|
||||
@@ -43,13 +44,18 @@ CDecoder::~CDecoder()
|
||||
MyFree(_inBuf);
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; }
|
||||
STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; }
|
||||
|
||||
HRESULT CDecoder::CreateInputBuffer()
|
||||
{
|
||||
if (_inBuf == 0)
|
||||
if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated)
|
||||
{
|
||||
_inBuf = (Byte *)MyAlloc(kInBufSize);
|
||||
MyFree(_inBuf);
|
||||
_inBuf = (Byte *)MyAlloc(_inBufSize);
|
||||
if (_inBuf == 0)
|
||||
return E_OUTOFMEMORY;
|
||||
_inBufSizeAllocated = _inBufSize;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
@@ -67,6 +73,7 @@ void CDecoder::SetOutStreamSizeResume(const UInt64 *outSize)
|
||||
if (_outSizeDefined)
|
||||
_outSize = *outSize;
|
||||
_outSizeProcessed = 0;
|
||||
_wrPos = 0;
|
||||
LzmaDec_Init(&_state);
|
||||
}
|
||||
|
||||
@@ -85,19 +92,17 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
|
||||
|
||||
UInt64 startInProgress = _inSizeProcessed;
|
||||
|
||||
SizeT next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize);
|
||||
for (;;)
|
||||
{
|
||||
if (_inPos == _inSize)
|
||||
{
|
||||
_inPos = _inSize = 0;
|
||||
RINOK(inStream->Read(_inBuf, kInBufSize, &_inSize));
|
||||
RINOK(inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));
|
||||
}
|
||||
|
||||
SizeT dicPos = _state.dicPos;
|
||||
SizeT curSize = _state.dicBufSize - dicPos;
|
||||
const UInt32 kStepSize = ((UInt32)1 << 22);
|
||||
if (curSize > kStepSize)
|
||||
curSize = (SizeT)kStepSize;
|
||||
SizeT curSize = next - dicPos;
|
||||
|
||||
ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
|
||||
if (_outSizeDefined)
|
||||
@@ -123,9 +128,18 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
|
||||
bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0);
|
||||
bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize);
|
||||
|
||||
if (res != 0 || _state.dicPos == _state.dicBufSize || finished || stopDecoding)
|
||||
if (res != 0 || _state.dicPos == next || finished || stopDecoding)
|
||||
{
|
||||
HRESULT res2 = WriteStream(outStream, _state.dic, _state.dicPos);
|
||||
HRESULT res2 = WriteStream(outStream, _state.dic + _wrPos, _state.dicPos - _wrPos);
|
||||
|
||||
_wrPos = _state.dicPos;
|
||||
if (_state.dicPos == _state.dicBufSize)
|
||||
{
|
||||
_state.dicPos = 0;
|
||||
_wrPos = 0;
|
||||
}
|
||||
next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize);
|
||||
|
||||
if (res != 0)
|
||||
return S_FALSE;
|
||||
RINOK(res2);
|
||||
@@ -134,9 +148,6 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
|
||||
if (finished)
|
||||
return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE);
|
||||
}
|
||||
if (_state.dicPos == _state.dicBufSize)
|
||||
_state.dicPos = 0;
|
||||
|
||||
if (progress)
|
||||
{
|
||||
UInt64 inSize = _inSizeProcessed - startInProgress;
|
||||
@@ -148,6 +159,8 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
|
||||
{
|
||||
if (_inBuf == 0)
|
||||
return E_INVALIDARG;
|
||||
SetOutStreamSize(outSize);
|
||||
return CodeSpec(inStream, outStream, progress);
|
||||
}
|
||||
@@ -166,7 +179,7 @@ STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
if (_inPos == _inSize)
|
||||
{
|
||||
_inPos = _inSize = 0;
|
||||
RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize));
|
||||
RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));
|
||||
}
|
||||
{
|
||||
SizeT inProcessed = _inSize - _inPos;
|
||||
@@ -214,7 +227,7 @@ HRESULT CDecoder::ReadFromInputStream(void *data, UInt32 size, UInt32 *processed
|
||||
if (_inPos == _inSize)
|
||||
{
|
||||
_inPos = _inSize = 0;
|
||||
RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize));
|
||||
RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));
|
||||
if (_inSize == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user