Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2022-01-22 21:43:09 +0300
committerKornel <kornel@geekhood.net>2022-01-22 21:43:09 +0300
commitc3529a41f527101f05e9e834a19205ee33a3b097 (patch)
tree2a76fa3119a75a39cf3ea7418877f53f1a64b7b4 /CPP/7zip/Compress
parent52eeaf1ad614fcd03b48423009182e3e3d1ff694 (diff)
21.0721.07
Diffstat (limited to 'CPP/7zip/Compress')
-rw-r--r--CPP/7zip/Compress/CopyCoder.cpp50
1 files changed, 39 insertions, 11 deletions
diff --git a/CPP/7zip/Compress/CopyCoder.cpp b/CPP/7zip/Compress/CopyCoder.cpp
index d8487ad5..a49bba8a 100644
--- a/CPP/7zip/Compress/CopyCoder.cpp
+++ b/CPP/7zip/Compress/CopyCoder.cpp
@@ -37,12 +37,34 @@ 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)
+ 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;
@@ -52,12 +74,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;
+ 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 (curSize == 0)
+ if (processed == 0)
return E_FAIL;
}
while (pos < size);
@@ -67,7 +92,10 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
RINOK(readRes);
- if (progress)
+ if (size != kBufSize)
+ return S_OK;
+
+ if (progress && (TotalSize & (((UInt32)1 << 22) - 1)) == 0)
{
RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
}