| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- // 7zFolderOutStream.cpp
- #include "StdAfx.h"
- #include "7zFolderOutStream.h"
- namespace NArchive {
- namespace N7z {
- CFolderOutStream::CFolderOutStream()
- {
- _outStreamWithHashSpec = new COutStreamWithCRC;
- _outStreamWithHash = _outStreamWithHashSpec;
- }
- HRESULT CFolderOutStream::Init(
- const CArchiveDatabaseEx *archiveDatabase,
- UInt32 ref2Offset,
- UInt32 startIndex,
- const CBoolVector *extractStatuses,
- IArchiveExtractCallback *extractCallback,
- bool testMode,
- bool checkCrc)
- {
- _archiveDatabase = archiveDatabase;
- _ref2Offset = ref2Offset;
- _startIndex = startIndex;
- _extractStatuses = extractStatuses;
- _extractCallback = extractCallback;
- _testMode = testMode;
- _checkCrc = checkCrc;
- _currentIndex = 0;
- _fileIsOpen = false;
- return WriteEmptyFiles();
- }
- HRESULT CFolderOutStream::OpenFile()
- {
- Int32 askMode;
- if((*_extractStatuses)[_currentIndex])
- askMode = _testMode ?
- NArchive::NExtract::NAskMode::kTest :
- NArchive::NExtract::NAskMode::kExtract;
- else
- askMode = NArchive::NExtract::NAskMode::kSkip;
- CMyComPtr<ISequentialOutStream> realOutStream;
- UInt32 index = _startIndex + _currentIndex;
- RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
- _outStreamWithHashSpec->SetStream(realOutStream);
- _outStreamWithHashSpec->Init(_checkCrc);
- if (askMode == NArchive::NExtract::NAskMode::kExtract &&
- (!realOutStream))
- {
- const CFileItem &fileInfo = _archiveDatabase->Files[index];
- if (!fileInfo.IsAnti && !fileInfo.IsDirectory)
- askMode = NArchive::NExtract::NAskMode::kSkip;
- }
- return _extractCallback->PrepareOperation(askMode);
- }
- HRESULT CFolderOutStream::WriteEmptyFiles()
- {
- for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
- {
- UInt32 index = _startIndex + _currentIndex;
- const CFileItem &fileInfo = _archiveDatabase->Files[index];
- if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0)
- return S_OK;
- RINOK(OpenFile());
- RINOK(_extractCallback->SetOperationResult(
- NArchive::NExtract::NOperationResult::kOK));
- _outStreamWithHashSpec->ReleaseStream();
- }
- return S_OK;
- }
- STDMETHODIMP CFolderOutStream::Write(const void *data,
- UInt32 size, UInt32 *processedSize)
- {
- UInt32 realProcessedSize = 0;
- while(_currentIndex < _extractStatuses->Size())
- {
- if (_fileIsOpen)
- {
- UInt32 index = _startIndex + _currentIndex;
- const CFileItem &fileInfo = _archiveDatabase->Files[index];
- UInt64 fileSize = fileInfo.UnPackSize;
-
- UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
- UInt64(size - realProcessedSize));
-
- UInt32 processedSizeLocal;
- RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,
- numBytesToWrite, &processedSizeLocal));
- _filePos += processedSizeLocal;
- realProcessedSize += processedSizeLocal;
- if (_filePos == fileSize)
- {
- bool digestsAreEqual;
- if (fileInfo.IsFileCRCDefined && _checkCrc)
- digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC();
- else
- digestsAreEqual = true;
- RINOK(_extractCallback->SetOperationResult(
- digestsAreEqual ?
- NArchive::NExtract::NOperationResult::kOK :
- NArchive::NExtract::NOperationResult::kCRCError));
- _outStreamWithHashSpec->ReleaseStream();
- _fileIsOpen = false;
- _currentIndex++;
- }
- if (realProcessedSize == size)
- {
- if (processedSize != NULL)
- *processedSize = realProcessedSize;
- return WriteEmptyFiles();
- }
- }
- else
- {
- RINOK(OpenFile());
- _fileIsOpen = true;
- _filePos = 0;
- }
- }
- if (processedSize != NULL)
- *processedSize = size;
- return S_OK;
- }
- HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
- {
- while(_currentIndex < _extractStatuses->Size())
- {
- if (_fileIsOpen)
- {
- RINOK(_extractCallback->SetOperationResult(resultEOperationResult));
- _outStreamWithHashSpec->ReleaseStream();
- _fileIsOpen = false;
- _currentIndex++;
- }
- else
- {
- RINOK(OpenFile());
- _fileIsOpen = true;
- }
- }
- return S_OK;
- }
- HRESULT CFolderOutStream::WasWritingFinished()
- {
- if (_currentIndex == _extractStatuses->Size())
- return S_OK;
- return E_FAIL;
- }
- }}
|