From 2efa10565ac395d2ce9a679ead46e70fb2f963eb Mon Sep 17 00:00:00 2001 From: Igor Pavlov Date: Sun, 30 Apr 2017 00:00:00 +0000 Subject: 17.00 --- CPP/7zip/Compress/Lzma2Decoder.cpp | 254 +++++++++++++++++++------------------ 1 file changed, 129 insertions(+), 125 deletions(-) (limited to 'CPP/7zip/Compress/Lzma2Decoder.cpp') diff --git a/CPP/7zip/Compress/Lzma2Decoder.cpp b/CPP/7zip/Compress/Lzma2Decoder.cpp index 1a378bbe..98af203d 100644 --- a/CPP/7zip/Compress/Lzma2Decoder.cpp +++ b/CPP/7zip/Compress/Lzma2Decoder.cpp @@ -15,7 +15,7 @@ static HRESULT SResToHRESULT(SRes res) case SZ_OK: return S_OK; case SZ_ERROR_MEM: return E_OUTOFMEMORY; case SZ_ERROR_PARAM: return E_INVALIDARG; - // case SZ_ERROR_PROGRESS: return E_ABORT; + case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; case SZ_ERROR_DATA: return S_FALSE; } return E_FAIL; @@ -26,30 +26,31 @@ namespace NLzma2 { CDecoder::CDecoder(): _inBuf(NULL), - _inBufSize(0), - _inBufSizeNew(1 << 20), - _outStepSize(1 << 22), + _finishMode(false), _outSizeDefined(false), - _finishMode(false) + _outStep(1 << 22), + _inBufSize(0), + _inBufSizeNew(1 << 20) { Lzma2Dec_Construct(&_state); } -STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; } -STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStepSize = size; return S_OK; } - CDecoder::~CDecoder() { Lzma2Dec_Free(&_state, &g_Alloc); MidFree(_inBuf); } +STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; } +STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStep = size; return S_OK; } + STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) { if (size != 1) return E_NOTIMPL; RINOK(SResToHRESULT(Lzma2Dec_Allocate(&_state, prop[0], &g_Alloc))); + if (!_inBuf || _inBufSize != _inBufSizeNew) { MidFree(_inBuf); @@ -63,9 +64,6 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) return S_OK; } -STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) { *value = _inSizeProcessed; return S_OK; } -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; } -STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; } STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) { @@ -73,191 +71,197 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) _outSize = 0; if (_outSizeDefined) _outSize = *outSize; + _inPos = _inLim = 0; + _inProcessed = 0; + _outProcessed = 0; Lzma2Dec_Init(&_state); - - _inPos = _inSize = 0; - _inSizeProcessed = _outSizeProcessed = 0; + return S_OK; } + STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) { _finishMode = (finishMode != 0); return S_OK; } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, - const UInt64 *outSize, ICompressProgressInfo *progress) + +STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +{ + *value = _inProcessed; + return S_OK; +} + + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { if (!_inBuf) return S_FALSE; + SetOutStreamSize(outSize); - UInt32 step = _outStepSize; - const UInt32 kOutStepSize_Min = 1 << 12; - if (step < kOutStepSize_Min) - step = kOutStepSize_Min; - SizeT wrPos = _state.decoder.dicPos; - - SizeT next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ? - _state.decoder.dicBufSize : - _state.decoder.dicPos + step; - - HRESULT hres = S_OK; + HRESULT readRes = S_OK; for (;;) { - if (_inPos == _inSize) + if (_inPos == _inLim && readRes == S_OK) { - _inPos = _inSize = 0; - hres = inStream->Read(_inBuf, _inBufSize, &_inSize); - if (hres != S_OK) - break; + _inPos = _inLim = 0; + readRes = inStream->Read(_inBuf, _inBufSize, &_inLim); + } + + const SizeT dicPos = _state.decoder.dicPos; + SizeT size; + { + SizeT next = _state.decoder.dicBufSize; + if (next - wrPos > _outStep) + next = wrPos + _outStep; + size = next - dicPos; } - SizeT dicPos = _state.decoder.dicPos; - SizeT curSize = next - dicPos; - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; if (_outSizeDefined) { - const UInt64 rem = _outSize - _outSizeProcessed; - if (curSize >= rem) + const UInt64 rem = _outSize - _outProcessed; + if (size >= rem) { - curSize = (SizeT)rem; + size = (SizeT)rem; if (_finishMode) finishMode = LZMA_FINISH_END; } } - SizeT inSizeProcessed = _inSize - _inPos; + SizeT inProcessed = _inLim - _inPos; ELzmaStatus status; - SRes res = Lzma2Dec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status); + + SRes res = Lzma2Dec_DecodeToDic(&_state, dicPos + size, _inBuf + _inPos, &inProcessed, finishMode, &status); - _inPos += (UInt32)inSizeProcessed; - _inSizeProcessed += inSizeProcessed; - SizeT outSizeProcessed = _state.decoder.dicPos - dicPos; - _outSizeProcessed += outSizeProcessed; + + _inPos += (UInt32)inProcessed; + _inProcessed += inProcessed; + const SizeT outProcessed = _state.decoder.dicPos - dicPos; + _outProcessed += outProcessed; + + + bool outFinished = (_outSizeDefined && _outProcessed >= _outSize); - bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0 - || status == LZMA_STATUS_FINISHED_WITH_MARK); - bool outFinished = (_outSizeDefined && _outSizeProcessed >= _outSize); + bool needStop = (res != 0 + || (inProcessed == 0 && outProcessed == 0) + || status == LZMA_STATUS_FINISHED_WITH_MARK + || (!_finishMode && outFinished)); - if (res != 0 - || _state.decoder.dicPos >= next - || finished - || outFinished) + if (needStop || outProcessed >= size) { HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos); if (_state.decoder.dicPos == _state.decoder.dicBufSize) _state.decoder.dicPos = 0; - wrPos = _state.decoder.dicPos; - next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ? - _state.decoder.dicBufSize : - _state.decoder.dicPos + step; - - if (res != 0) - return S_FALSE; RINOK(res2); - if (finished) + if (needStop) { + if (res != 0) + return S_FALSE; + if (status == LZMA_STATUS_FINISHED_WITH_MARK) { - if (_finishMode && inSize && *inSize != _inSizeProcessed) - return S_FALSE; - if (finishMode == LZMA_FINISH_END && !outFinished) - return S_FALSE; - return S_OK; + if (_finishMode) + { + if (inSize && *inSize != _inProcessed) + return S_FALSE; + if (_outSizeDefined && _outSize != _outProcessed) + return S_FALSE; + } + return readRes; } - return (finishMode == LZMA_FINISH_END) ? S_FALSE : S_OK; - } - if (outFinished && finishMode == LZMA_FINISH_ANY) - return S_OK; + if (!_finishMode && outFinished) + return readRes; + + return S_FALSE; + } } if (progress) { - RINOK(progress->SetRatioInfo(&_inSizeProcessed, &_outSizeProcessed)); + RINOK(progress->SetRatioInfo(&_inProcessed, &_outProcessed)); } } - - HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos); - if (hres != S_OK) - return hres; - return res2; } + #ifndef NO_READ_FROM_CODER +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; } +STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; } + + STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) { - UInt32 totalProcessed = 0; - if (processedSize) *processedSize = 0; - for (;;) + ELzmaFinishMode finishMode = LZMA_FINISH_ANY; + if (_outSizeDefined) { - if (_inPos == _inSize) + const UInt64 rem = _outSize - _outProcessed; + if (size >= rem) { - _inPos = _inSize = 0; - RINOK(_inStream->Read(_inBuf, _inBufSize, &_inSize)); + size = (UInt32)rem; + if (_finishMode) + finishMode = LZMA_FINISH_END; } + } + + HRESULT readRes = S_OK; + + for (;;) + { + if (_inPos == _inLim && readRes == S_OK) { - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; - if (_outSizeDefined) - { - const UInt64 rem = _outSize - _outSizeProcessed; - if (rem <= size) - { - size = (UInt32)rem; - if (_finishMode) - finishMode = LZMA_FINISH_END; - } - } + _inPos = _inLim = 0; + readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim); + } + + SizeT inProcessed = _inLim - _inPos; + SizeT outProcessed = size; + ELzmaStatus status; - SizeT outProcessed = size; - SizeT inProcessed = _inSize - _inPos; - - ELzmaStatus status; - SRes res = Lzma2Dec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, - _inBuf + _inPos, &inProcessed, finishMode, &status); - - _inPos += (UInt32)inProcessed; - _inSizeProcessed += inProcessed; - _outSizeProcessed += outProcessed; - size -= (UInt32)outProcessed; - data = (Byte *)data + outProcessed; - - totalProcessed += (UInt32)outProcessed; - if (processedSize) - *processedSize = totalProcessed; - - if (res != SZ_OK) - { - if (totalProcessed != 0) - return S_OK; - return SResToHRESULT(res); - } - - if (inProcessed == 0 && outProcessed == 0) - return S_OK; - if (status == LZMA_STATUS_FINISHED_WITH_MARK) - return S_OK; - if (outProcessed != 0) - { - if (finishMode != LZMA_FINISH_END || _outSize != _outSizeProcessed) - return S_OK; - } + SRes res = Lzma2Dec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, + _inBuf + _inPos, &inProcessed, finishMode, &status); + + + _inPos += (UInt32)inProcessed; + _inProcessed += inProcessed; + _outProcessed += outProcessed; + size -= (UInt32)outProcessed; + data = (Byte *)data + outProcessed; + if (processedSize) + *processedSize += (UInt32)outProcessed; + + if (res != 0) + return S_FALSE; + + /* + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + return readRes; + + if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT) + { + if (_finishMode && _outSizeDefined && _outProcessed >= _outSize) + return S_FALSE; + return readRes; } + */ + + if (inProcessed == 0 && outProcessed == 0) + return readRes; } } -- cgit v1.2.3