diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp | 80 |
1 files changed, 59 insertions, 21 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp index ac6ab2e718a..b779e08b5b3 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp @@ -15,10 +15,15 @@ CCopyCoder::~CCopyCoder() ::MidFree(_buf); } -STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, +Z7_COM7F_IMF(CCopyCoder::SetFinishMode(UInt32 /* finishMode */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CCopyCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, - ICompressProgressInfo *progress) + ICompressProgressInfo *progress)) { if (!_buf) { @@ -32,12 +37,39 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, for (;;) { UInt32 size = kBufSize; - if (outSize && size > *outSize - TotalSize) - size = (UInt32)(*outSize - TotalSize); - if (size == 0) - return S_OK; + if (outSize) + { + const UInt64 rem = *outSize - TotalSize; + if (size > rem) + { + size = (UInt32)rem; + if (size == 0) + { + /* if we enable the following check, + we will make one call of Read(_buf, 0) for empty stream */ + // if (TotalSize != 0) + return S_OK; + } + } + } - HRESULT readRes = inStream->Read(_buf, size, &size); + HRESULT readRes; + { + UInt32 pos = 0; + do + { + const UInt32 curSize = size - pos; + UInt32 processed = 0; + readRes = inStream->Read(_buf + pos, curSize, &processed); + if (processed > curSize) + return E_FAIL; // internal code failure + pos += processed; + if (readRes != S_OK || processed == 0) + break; + } + while (pos < kBufSize); + size = pos; + } if (size == 0) return readRes; @@ -47,12 +79,15 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, UInt32 pos = 0; do { - UInt32 curSize = size - pos; - HRESULT res = outStream->Write(_buf + pos, curSize, &curSize); - pos += curSize; - TotalSize += curSize; - RINOK(res); - if (curSize == 0) + const UInt32 curSize = size - pos; + UInt32 processed = 0; + const HRESULT res = outStream->Write(_buf + pos, curSize, &processed); + if (processed > curSize) + return E_FAIL; // internal code failure + pos += processed; + TotalSize += processed; + RINOK(res) + if (processed == 0) return E_FAIL; } while (pos < size); @@ -60,29 +95,32 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, else TotalSize += size; - RINOK(readRes); + RINOK(readRes) + + if (size != kBufSize) + return S_OK; - if (progress) + if (progress && (TotalSize & (((UInt32)1 << 22) - 1)) == 0) { - RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)); + RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)) } } } -STDMETHODIMP CCopyCoder::SetInStream(ISequentialInStream *inStream) +Z7_COM7F_IMF(CCopyCoder::SetInStream(ISequentialInStream *inStream)) { _inStream = inStream; TotalSize = 0; return S_OK; } -STDMETHODIMP CCopyCoder::ReleaseInStream() +Z7_COM7F_IMF(CCopyCoder::ReleaseInStream()) { _inStream.Release(); return S_OK; } -STDMETHODIMP CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize = 0; HRESULT res = _inStream->Read(data, size, &realProcessedSize); @@ -92,7 +130,7 @@ STDMETHODIMP CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize) return res; } -STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CCopyCoder::GetInStreamProcessedSize(UInt64 *value)) { *value = TotalSize; return S_OK; @@ -108,7 +146,7 @@ HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream { NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; - RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress)); + RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress)) return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL; } |