From 96ade47c182bf37a2efca2aa62922e54e5ff1660 Mon Sep 17 00:00:00 2001 From: Arttu Tarkiainen Date: Wed, 6 Apr 2022 13:33:38 +0300 Subject: Move LZMA SDK to 3rdparty subdirectory Also add attribution document. Task-number: QTIFW-2336 Change-Id: I91546bc6c3ace244e4b546b945f40b7d204f7463 Reviewed-by: Katja Marttila Reviewed-by: Qt CI Bot --- .../unix/CPP/7zip/Archive/7z/7zFolderOutStream.cpp | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 src/libs/3rdparty/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.cpp (limited to 'src/libs/3rdparty/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.cpp') diff --git a/src/libs/3rdparty/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.cpp b/src/libs/3rdparty/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.cpp new file mode 100644 index 000000000..847f65bf2 --- /dev/null +++ b/src/libs/3rdparty/7zip/unix/CPP/7zip/Archive/7z/7zFolderOutStream.cpp @@ -0,0 +1,149 @@ +// 7zFolderOutStream.cpp + +#include "StdAfx.h" + +#include "7zFolderOutStream.h" + +namespace NArchive { +namespace N7z { + +CFolderOutStream::CFolderOutStream() +{ + _crcStreamSpec = new COutStreamWithCRC; + _crcStream = _crcStreamSpec; +} + +HRESULT CFolderOutStream::Init( + const CDbEx *db, + UInt32 ref2Offset, UInt32 startIndex, + const CBoolVector *extractStatuses, + IArchiveExtractCallback *extractCallback, + bool testMode, bool checkCrc) +{ + _db = db; + _ref2Offset = ref2Offset; + _startIndex = startIndex; + + _extractStatuses = extractStatuses; + _extractCallback = extractCallback; + _testMode = testMode; + _checkCrc = checkCrc; + + _currentIndex = 0; + _fileIsOpen = false; + return ProcessEmptyFiles(); +} + +HRESULT CFolderOutStream::OpenFile() +{ + Int32 askMode = ((*_extractStatuses)[_currentIndex]) ? (_testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract) : + NExtract::NAskMode::kSkip; + CMyComPtr realOutStream; + UInt32 index = _startIndex + _currentIndex; + RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode)); + _crcStreamSpec->SetStream(realOutStream); + _crcStreamSpec->Init(_checkCrc); + _fileIsOpen = true; + const CFileItem &fi = _db->Files[index]; + _rem = fi.Size; + if (askMode == NExtract::NAskMode::kExtract && !realOutStream && + !_db->IsItemAnti(index) && !fi.IsDir) + askMode = NExtract::NAskMode::kSkip; + return _extractCallback->PrepareOperation(askMode); +} + +HRESULT CFolderOutStream::CloseFileAndSetResult(Int32 res) +{ + _crcStreamSpec->ReleaseStream(); + _fileIsOpen = false; + _currentIndex++; + return _extractCallback->SetOperationResult(res); +} + +HRESULT CFolderOutStream::CloseFileAndSetResult() +{ + const CFileItem &fi = _db->Files[_startIndex + _currentIndex]; + return CloseFileAndSetResult( + (fi.IsDir || !fi.CrcDefined || !_checkCrc || fi.Crc == _crcStreamSpec->GetCRC()) ? + NExtract::NOperationResult::kOK : + NExtract::NOperationResult::kCRCError); +} + +HRESULT CFolderOutStream::ProcessEmptyFiles() +{ + while (_currentIndex < _extractStatuses->Size() && _db->Files[_startIndex + _currentIndex].Size == 0) + { + RINOK(OpenFile()); + RINOK(CloseFileAndSetResult()); + } + return S_OK; +} + +STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize != NULL) + *processedSize = 0; + while (size != 0) + { + if (_fileIsOpen) + { + UInt32 cur = size < _rem ? size : (UInt32)_rem; + RINOK(_crcStream->Write(data, cur, &cur)); + if (cur == 0) + break; + data = (const Byte *)data + cur; + size -= cur; + _rem -= cur; + if (processedSize != NULL) + *processedSize += cur; + if (_rem == 0) + { + RINOK(CloseFileAndSetResult()); + RINOK(ProcessEmptyFiles()); + continue; + } + } + else + { + RINOK(ProcessEmptyFiles()); + if (_currentIndex == _extractStatuses->Size()) + { + // we support partial extracting + if (processedSize != NULL) + *processedSize += size; + break; + } + RINOK(OpenFile()); + } + } + return S_OK; +} + +STDMETHODIMP CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value) +{ + *value = 0; + if ((int)subStream >= _extractStatuses->Size()) + return S_FALSE; + *value = _db->Files[_startIndex + (int)subStream].Size; + return S_OK; +} + +HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult) +{ + while (_currentIndex < _extractStatuses->Size()) + { + if (_fileIsOpen) + { + RINOK(CloseFileAndSetResult(resultEOperationResult)); + } + else + { + RINOK(OpenFile()); + } + } + return S_OK; +} + +}} -- cgit v1.2.3