diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2015-10-18 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:56 +0300 |
commit | a663a6deb7a150f935fac7efdbf4d53d27369594 (patch) | |
tree | d1be306b33dd96050206da5774fff7bd9083ddfa /CPP/7zip/Common/LimitedStreams.cpp | |
parent | 6543c280208393fa32cb0094f770d14c1cfb13b2 (diff) |
15.0915.09
Diffstat (limited to 'CPP/7zip/Common/LimitedStreams.cpp')
-rw-r--r-- | CPP/7zip/Common/LimitedStreams.cpp | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/CPP/7zip/Common/LimitedStreams.cpp b/CPP/7zip/Common/LimitedStreams.cpp index 77665ae1..c7962167 100644 --- a/CPP/7zip/Common/LimitedStreams.cpp +++ b/CPP/7zip/Common/LimitedStreams.cpp @@ -86,26 +86,34 @@ STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSi *processedSize = 0; if (_virtPos >= Size) return S_OK; + { + UInt64 rem = Size - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + if (size == 0) + return S_OK; if (_curRem == 0) { - UInt32 blockSize = (UInt32)1 << BlockSizeLog; - UInt32 virtBlock = (UInt32)(_virtPos >> BlockSizeLog); - UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1); - UInt32 phyBlock = Vector[virtBlock]; + const UInt32 blockSize = (UInt32)1 << BlockSizeLog; + const UInt32 virtBlock = (UInt32)(_virtPos >> BlockSizeLog); + const UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1); + const UInt32 phyBlock = Vector[virtBlock]; + UInt64 newPos = StartOffset + ((UInt64)phyBlock << BlockSizeLog) + offsetInBlock; if (newPos != _physPos) { _physPos = newPos; RINOK(SeekToPhys()); } + _curRem = blockSize - offsetInBlock; + for (int i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++) _curRem += (UInt32)1 << BlockSizeLog; - UInt64 rem = Size - _virtPos; - if (_curRem > rem) - _curRem = (UInt32)rem; } + if (size > _curRem) size = _curRem; HRESULT res = Stream->Read(data, size, &size); |