diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp | 82 |
1 files changed, 65 insertions, 17 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp index f71692a7781..ac6ab2e718a 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp @@ -4,17 +4,15 @@ #include "../../../C/Alloc.h" -#include "../Common/StreamUtils.h" - #include "CopyCoder.h" namespace NCompress { -static const UInt32 kBufferSize = 1 << 17; +static const UInt32 kBufSize = 1 << 17; CCopyCoder::~CCopyCoder() { - ::MidFree(_buffer); + ::MidFree(_buf); } STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, @@ -22,36 +20,78 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) { - if (_buffer == 0) + if (!_buf) { - _buffer = (Byte *)::MidAlloc(kBufferSize); - if (_buffer == 0) + _buf = (Byte *)::MidAlloc(kBufSize); + if (!_buf) return E_OUTOFMEMORY; } TotalSize = 0; + for (;;) { - UInt32 size = kBufferSize; - if (outSize != 0) - if (size > *outSize - TotalSize) - size = (UInt32)(*outSize - TotalSize); - RINOK(inStream->Read(_buffer, size, &size)); + UInt32 size = kBufSize; + if (outSize && size > *outSize - TotalSize) + size = (UInt32)(*outSize - TotalSize); + if (size == 0) + return S_OK; + + HRESULT readRes = inStream->Read(_buf, size, &size); + if (size == 0) - break; + return readRes; + if (outStream) { - RINOK(WriteStream(outStream, _buffer, size)); + 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) + return E_FAIL; + } + while (pos < size); } - TotalSize += size; - if (progress != NULL) + else + TotalSize += size; + + RINOK(readRes); + + if (progress) { RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)); } } +} + +STDMETHODIMP CCopyCoder::SetInStream(ISequentialInStream *inStream) +{ + _inStream = inStream; + TotalSize = 0; return S_OK; } +STDMETHODIMP CCopyCoder::ReleaseInStream() +{ + _inStream.Release(); + return S_OK; +} + +STDMETHODIMP CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + HRESULT res = _inStream->Read(data, size, &realProcessedSize); + TotalSize += realProcessedSize; + if (processedSize) + *processedSize = realProcessedSize; + return res; +} + STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value) { *value = TotalSize; @@ -60,8 +100,16 @@ STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value) HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) { - CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder; + CMyComPtr<ICompressCoder> copyCoder = new CCopyCoder; return copyCoder->Code(inStream, outStream, NULL, NULL, progress); } +HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress) +{ + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; + RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress)); + return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL; +} + } |