This commit is contained in:
Igor Pavlov
2023-12-22 17:17:05 +00:00
committed by Kornel
parent ec44a8a070
commit a36c48cece
954 changed files with 42199 additions and 25482 deletions

View File

@@ -16,10 +16,11 @@
namespace NArchive {
namespace N7z {
class CFolderOutStream:
public ISequentialOutStream,
public CMyUnknownImp
{
Z7_CLASS_IMP_COM_1(
CFolderOutStream
, ISequentialOutStream
/* , ICompressGetSubStreamSize */
)
CMyComPtr<ISequentialOutStream> _stream;
public:
bool TestMode;
@@ -31,6 +32,7 @@ private:
UInt64 _rem;
const UInt32 *_indexes;
// unsigned _startIndex;
unsigned _numFiles;
unsigned _fileIndex;
@@ -40,8 +42,6 @@ private:
HRESULT ProcessEmptyFiles();
public:
MY_UNKNOWN_IMP1(ISequentialOutStream)
const CDbEx *_db;
CMyComPtr<IArchiveExtractCallback> ExtractCallback;
@@ -52,8 +52,6 @@ public:
CheckCrc(true)
{}
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
HRESULT Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles);
HRESULT FlushCorrupted(Int32 callbackOperationResult);
@@ -63,6 +61,7 @@ public:
HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles)
{
// _startIndex = startIndex;
_fileIndex = startIndex;
_indexes = indexes;
_numFiles = numFiles;
@@ -76,11 +75,10 @@ HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsig
HRESULT CFolderOutStream::OpenFile(bool isCorrupted)
{
const CFileItem &fi = _db->Files[_fileIndex];
UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex);
Int32 askMode = (_fileIndex == nextFileIndex) ?
(TestMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract) :
const UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex);
Int32 askMode = (_fileIndex == nextFileIndex) ? TestMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract :
NExtract::NAskMode::kSkip;
if (isCorrupted
@@ -90,7 +88,7 @@ HRESULT CFolderOutStream::OpenFile(bool isCorrupted)
askMode = NExtract::NAskMode::kTest;
CMyComPtr<ISequentialOutStream> realOutStream;
RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode));
RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode))
_stream = realOutStream;
_crc = CRC_INIT_VAL;
@@ -136,13 +134,13 @@ HRESULT CFolderOutStream::ProcessEmptyFiles()
{
while (_numFiles != 0 && _db->Files[_fileIndex].Size == 0)
{
RINOK(OpenFile());
RINOK(CloseFile());
RINOK(OpenFile())
RINOK(CloseFile())
}
return S_OK;
}
STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
Z7_COM7F_IMF(CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
{
if (processedSize)
*processedSize = 0;
@@ -170,16 +168,16 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
_rem -= cur;
if (_rem == 0)
{
RINOK(CloseFile());
RINOK(ProcessEmptyFiles());
RINOK(CloseFile())
RINOK(ProcessEmptyFiles())
}
RINOK(result);
RINOK(result)
if (cur == 0)
break;
continue;
}
RINOK(ProcessEmptyFiles());
RINOK(ProcessEmptyFiles())
if (_numFiles == 0)
{
// we support partial extracting
@@ -192,7 +190,7 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
// return S_FALSE;
return k_My_HRESULT_WritingWasCut;
}
RINOK(OpenFile());
RINOK(OpenFile())
}
return S_OK;
@@ -204,18 +202,32 @@ HRESULT CFolderOutStream::FlushCorrupted(Int32 callbackOperationResult)
{
if (_fileIsOpen)
{
RINOK(CloseFile_and_SetResult(callbackOperationResult));
RINOK(CloseFile_and_SetResult(callbackOperationResult))
}
else
{
RINOK(OpenFile(true));
RINOK(OpenFile(true))
}
}
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
/*
Z7_COM7F_IMF(CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value))
{
*value = 0;
// const unsigned numFiles_Original = _numFiles + _fileIndex - _startIndex;
const unsigned numFiles_Original = _numFiles;
if (subStream >= numFiles_Original)
return S_FALSE; // E_FAIL;
*value = _db->Files[_startIndex + (unsigned)subStream].Size;
return S_OK;
}
*/
Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec))
{
// for GCC
// CFolderOutStream *folderOutStream = new CFolderOutStream;
@@ -229,7 +241,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
// numItems = (UInt32)(Int32)-1;
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems = _db.Files.Size();
@@ -244,8 +256,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
for (i = 0; i < numItems; i++)
{
UInt32 fileIndex = allFilesMode ? i : indices[i];
CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
const UInt32 fileIndex = allFilesMode ? i : indices[i];
const CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
if (folderIndex == kNumNoIndex)
continue;
if (folderIndex != prevFolder || fileIndex < nextFile)
@@ -257,7 +269,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
}
RINOK(extractCallback->SetTotal(importantTotalUnpacked));
RINOK(extractCallback->SetTotal(importantTotalUnpacked))
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
@@ -268,8 +280,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
false
#elif !defined(USE_MIXER_ST)
true
#elif !defined(__7Z_SET_PROPERTIES)
#ifdef _7ZIP_ST
#elif !defined(Z7_7Z_SET_PROPERTIES)
#ifdef Z7_ST
false
#else
true
@@ -281,8 +293,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
UInt64 curPacked, curUnpacked;
CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage;
extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage);
CMyComPtr<IArchiveExtractCallbackMessage2> callbackMessage;
extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage2, &callbackMessage);
CFolderOutStream *folderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
@@ -294,7 +306,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
for (UInt32 i = 0;; lps->OutSize += curUnpacked, lps->InSize += curPacked)
{
RINOK(lps->SetCur());
RINOK(lps->SetCur())
if (i >= numItems)
break;
@@ -303,7 +315,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
curPacked = 0;
UInt32 fileIndex = allFilesMode ? i : indices[i];
CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
const CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
UInt32 numSolidFiles = 1;
@@ -316,7 +328,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
for (k = i + 1; k < numItems; k++)
{
UInt32 fileIndex2 = allFilesMode ? k : indices[k];
const UInt32 fileIndex2 = allFilesMode ? k : indices[k];
if (_db.FileIndexToFolderIndexMap[fileIndex2] != folderIndex
|| fileIndex2 < nextFile)
break;
@@ -330,20 +342,26 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
{
HRESULT result = folderOutStream->Init(fileIndex,
const HRESULT result = folderOutStream->Init(fileIndex,
allFilesMode ? NULL : indices + i,
numSolidFiles);
i += numSolidFiles;
RINOK(result);
RINOK(result)
}
// to test solid block with zero unpacked size we disable that code
if (folderOutStream->WasWritingFinished())
{
// for debug: to test zero size stream unpacking
// if (folderIndex == kNumNoIndex) // enable this check for debug
continue;
}
#ifndef _NO_CRYPTO
if (folderIndex == kNumNoIndex)
return E_FAIL;
#ifndef Z7_NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (extractCallback)
extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
@@ -351,16 +369,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
try
{
#ifndef _NO_CRYPTO
#ifndef Z7_NO_CRYPTO
bool isEncrypted = false;
bool passwordIsDefined = false;
UString_Wipe password;
#endif
bool dataAfterEnd_Error = false;
HRESULT result = decoder.Decode(
const HRESULT result = decoder.Decode(
EXTERNAL_CODECS_VARS
_inStream,
_db.ArcInfo.DataStartPosition,
@@ -372,15 +389,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
NULL // *inStreamMainRes
, dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST)
Z7_7Z_DECODER_CRYPRO_VARS
#if !defined(Z7_ST)
, true, _numThreads, _memUsage_Decompress
#endif
);
if (result == S_FALSE || result == E_NOTIMPL || dataAfterEnd_Error)
{
bool wasFinished = folderOutStream->WasWritingFinished();
const bool wasFinished = folderOutStream->WasWritingFinished();
int resOp = NExtract::NOperationResult::kDataError;
@@ -392,14 +409,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
resOp = NExtract::NOperationResult::kDataAfterEnd;
}
RINOK(folderOutStream->FlushCorrupted(resOp));
RINOK(folderOutStream->FlushCorrupted(resOp))
if (wasFinished)
{
// we don't show error, if it's after required files
if (/* !folderOutStream->ExtraWriteWasCut && */ callbackMessage)
{
RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp));
RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp))
}
}
continue;
@@ -408,12 +425,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (result != S_OK)
return result;
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError))
continue;
}
catch(...)
{
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError))
// continue;
// return E_FAIL;
throw;