// 7zFolderInStream.cpp #include "StdAfx.h" #include "7zFolderInStream.h" namespace NArchive { namespace N7z { CFolderInStream::CFolderInStream() { _inStreamWithHashSpec = new CSequentialInStreamWithCRC; _inStreamWithHash = _inStreamWithHashSpec; } void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback, const UInt32 *fileIndices, UInt32 numFiles) { _updateCallback = updateCallback; _numFiles = numFiles; _fileIndex = 0; _fileIndices = fileIndices; Processed.Clear(); CRCs.Clear(); Sizes.Clear(); _fileIsOpen = false; _currentSizeIsDefined = false; } HRESULT CFolderInStream::OpenStream() { _filePos = 0; while (_fileIndex < _numFiles) { CMyComPtr<ISequentialInStream> stream; HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream); if (result != S_OK && result != S_FALSE) return result; _fileIndex++; _inStreamWithHashSpec->SetStream(stream); _inStreamWithHashSpec->Init(); if (stream) { _fileIsOpen = true; CMyComPtr<IStreamGetSize> streamGetSize; stream.QueryInterface(IID_IStreamGetSize, &streamGetSize); if (streamGetSize) { RINOK(streamGetSize->GetSize(&_currentSize)); _currentSizeIsDefined = true; } return S_OK; } RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); Sizes.Add(0); Processed.Add(result == S_OK); AddDigest(); } return S_OK; } void CFolderInStream::AddDigest() { CRCs.Add(_inStreamWithHashSpec->GetCRC()); } HRESULT CFolderInStream::CloseStream() { RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); _inStreamWithHashSpec->ReleaseStream(); _fileIsOpen = false; _currentSizeIsDefined = false; Processed.Add(true); Sizes.Add(_filePos); AddDigest(); return S_OK; } STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) { if (processedSize != 0) *processedSize = 0; while (size > 0) { if (_fileIsOpen) { UInt32 processed2; RINOK(_inStreamWithHash->Read(data, size, &processed2)); if (processed2 == 0) { RINOK(CloseStream()); continue; } if (processedSize != 0) *processedSize = processed2; _filePos += processed2; break; } if (_fileIndex >= _numFiles) break; RINOK(OpenStream()); } return S_OK; } STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value) { *value = 0; unsigned index2 = (unsigned)subStream; if (subStream > Sizes.Size()) return E_FAIL; if (index2 < Sizes.Size()) { *value = Sizes[index2]; return S_OK; } if (!_currentSizeIsDefined) return S_FALSE; *value = _currentSize; return S_OK; } }}