STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) { if (processedSize) *processedSize = 0; if (_virtPos >= _size) { // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case. return S_OK; // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF } { const UInt64 rem = _size - _virtPos; if (size > rem) size = (UInt32)rem; } UInt64 newPos = _startOffset + _virtPos; if (newPos != _physPos) { _physPos = newPos; RINOK(SeekToPhys()); } HRESULT res = _stream->Read(data, size, &size); if (processedSize) *processedSize = size; _physPos += size; _virtPos += size; return res; }
STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize) { if (processedSize) *processedSize = 0; if (_virtPos >= Size) 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]; 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; }
STDMETHODIMP CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize) { if (processedSize) *processedSize = 0; if (_virtPos >= Extents.Back().Virt) return S_OK; if (size == 0) return S_OK; unsigned left = 0, right = Extents.Size() - 1; for (;;) { unsigned mid = (left + right) / 2; if (mid == left) break; if (_virtPos < Extents[mid].Virt) right = mid; else left = mid; } const CSeekExtent &extent = Extents[left]; UInt64 phyPos = extent.Phy + (_virtPos - extent.Virt); if (_needStartSeek || _phyPos != phyPos) { _needStartSeek = false; _phyPos = phyPos; RINOK(SeekToPhys()); } UInt64 rem = Extents[left + 1].Virt - _virtPos; if (size > rem) size = (UInt32)rem; HRESULT res = Stream->Read(data, size, &size); _phyPos += size; _virtPos += size; if (processedSize) *processedSize = size; return res; }
STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) { if (processedSize) *processedSize = 0; if (_virtPos >= _size) { // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case. return S_OK; // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF } UInt64 rem = _size - _virtPos; if (rem < size) size = (UInt32)rem; UInt64 newPos = _startOffset + _virtPos; UInt64 offsetInCache = newPos - _cachePhyPos; HRESULT res = S_OK; if (newPos >= _cachePhyPos && offsetInCache <= _cacheSize && size <= _cacheSize - (size_t)offsetInCache) { if (size != 0) memcpy(data, _cache + (size_t)offsetInCache, size); } else { if (newPos != _physPos) { _physPos = newPos; RINOK(SeekToPhys()); } res = _stream->Read(data, size, &size); _physPos += size; } if (processedSize) *processedSize = size; _virtPos += size; return res; }