// 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; | |
} | |
}} |