summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/7zip/Archive
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Archive')
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h33
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp242
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h19
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp311
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h43
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp153
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp224
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h74
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp264
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h141
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp425
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp2
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h21
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp482
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h50
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h62
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp265
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h73
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp126
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.h8
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp10
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp15
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h32
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp1216
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h37
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h7
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Archive.def2
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Archive2.def2
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp23
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp262
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h134
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp2
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h14
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp288
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h127
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp29
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h46
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp129
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h33
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp56
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h51
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp4
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h14
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/ParseProperties.h4
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h7
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp73
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/IArchive.h454
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp234
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp100
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/StdAfx.h7
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp1219
-rw-r--r--3rdparty/lzma/CPP/7zip/Archive/XzHandler.h58
52 files changed, 5054 insertions, 2653 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h
index 8105ff0413d..ac1f6ad14ca 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h
@@ -1,7 +1,7 @@
// 7zCompressionMode.h
-#ifndef __7Z_COMPRESSION_MODE_H
-#define __7Z_COMPRESSION_MODE_H
+#ifndef ZIP7_INC_7Z_COMPRESSION_MODE_H
+#define ZIP7_INC_7Z_COMPRESSION_MODE_H
#include "../../Common/MethodId.h"
#include "../../Common/MethodProps.h"
@@ -13,7 +13,11 @@ struct CMethodFull: public CMethodProps
{
CMethodId Id;
UInt32 NumStreams;
+ int CodecIndex;
+ UInt32 NumThreads;
+ bool Set_NumThreads;
+ CMethodFull(): CodecIndex(-1), NumThreads(1), Set_NumThreads(false) {}
bool IsSimpleCoder() const { return NumStreams == 1; }
};
@@ -49,24 +53,37 @@ struct CCompressionMethodMode
bool DefaultMethod_was_Inserted;
bool Filter_was_Inserted;
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
UInt32 NumThreads;
+ bool NumThreads_WasForced;
bool MultiThreadMixer;
#endif
+
+ UInt64 MemoryUsageLimit;
+ bool MemoryUsageLimit_WasSet;
bool PasswordIsDefined;
- UString Password;
+ UString Password; // _Wipe
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
CCompressionMethodMode():
- DefaultMethod_was_Inserted(false),
- Filter_was_Inserted(false),
- PasswordIsDefined(false)
- #ifndef _7ZIP_ST
+ DefaultMethod_was_Inserted(false)
+ , Filter_was_Inserted(false)
+ #ifndef Z7_ST
, NumThreads(1)
+ , NumThreads_WasForced(false)
, MultiThreadMixer(true)
#endif
+ , MemoryUsageLimit((UInt64)1 << 30)
+ , MemoryUsageLimit_WasSet(false)
+ , PasswordIsDefined(false)
{}
+
+#ifdef Z7_CPP_IS_SUPPORTED_default
+ CCompressionMethodMode(const CCompressionMethodMode &) = default;
+ CCompressionMethodMode& operator =(const CCompressionMethodMode &) = default;
+#endif
+ ~CCompressionMethodMode() { Password.Wipe_and_Empty(); }
};
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp
index b0d6dd838aa..5420dcee30d 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp
@@ -5,25 +5,23 @@
#include "../../Common/LimitedStreams.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
#include "7zDecode.h"
namespace NArchive {
namespace N7z {
-class CDecProgress:
- public ICompressProgressInfo,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_COM_1(
+ CDecProgress
+ , ICompressProgressInfo
+)
CMyComPtr<ICompressProgressInfo> _progress;
public:
CDecProgress(ICompressProgressInfo *progress): _progress(progress) {}
-
- MY_UNKNOWN_IMP1(ICompressProgressInfo)
- STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
-STDMETHODIMP CDecProgress::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 *outSize)
+Z7_COM7F_IMF(CDecProgress::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 *outSize))
{
return _progress->SetRatioInfo(NULL, outSize);
}
@@ -110,20 +108,23 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
}
CDecoder::CDecoder(bool useMixerMT):
- _bindInfoPrev_Defined(false),
- _useMixerMT(useMixerMT)
-{}
+ _bindInfoPrev_Defined(false)
+{
+ #if defined(USE_MIXER_ST) && defined(USE_MIXER_MT)
+ _useMixerMT = useMixerMT;
+ #else
+ UNUSED_VAR(useMixerMT)
+ #endif
+}
-struct CLockedInStream:
- public IUnknown,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_COM_0(
+ CLockedInStream
+)
+public:
CMyComPtr<IInStream> Stream;
UInt64 Pos;
- MY_UNKNOWN_IMP
-
#ifdef USE_MIXER_MT
NWindows::NSynchronization::CCriticalSection CriticalSection;
#endif
@@ -132,10 +133,10 @@ struct CLockedInStream:
#ifdef USE_MIXER_MT
-class CLockedSequentialInStreamMT:
- public ISequentialInStream,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_COM_1(
+ CLockedSequentialInStreamMT
+ , ISequentialInStream
+)
CLockedInStream *_glob;
UInt64 _pos;
CMyComPtr<IUnknown> _globRef;
@@ -146,24 +147,20 @@ public:
_glob = lockedInStream;
_pos = startPos;
}
-
- MY_UNKNOWN_IMP1(ISequentialInStream)
-
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
-STDMETHODIMP CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *processedSize))
{
NWindows::NSynchronization::CCriticalSectionLock lock(_glob->CriticalSection);
if (_pos != _glob->Pos)
{
- RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL));
+ RINOK(InStream_SeekSet(_glob->Stream, _pos))
_glob->Pos = _pos;
}
UInt32 realProcessedSize = 0;
- HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize);
+ const HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize);
_pos += realProcessedSize;
_glob->Pos = _pos;
if (processedSize)
@@ -176,10 +173,10 @@ STDMETHODIMP CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *
#ifdef USE_MIXER_ST
-class CLockedSequentialInStreamST:
- public ISequentialInStream,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_COM_1(
+ CLockedSequentialInStreamST
+ , ISequentialInStream
+)
CLockedInStream *_glob;
UInt64 _pos;
CMyComPtr<IUnknown> _globRef;
@@ -190,22 +187,18 @@ public:
_glob = lockedInStream;
_pos = startPos;
}
-
- MY_UNKNOWN_IMP1(ISequentialInStream)
-
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
-STDMETHODIMP CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *processedSize))
{
if (_pos != _glob->Pos)
{
- RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL));
+ RINOK(InStream_SeekSet(_glob->Stream, _pos))
_glob->Pos = _pos;
}
UInt32 realProcessedSize = 0;
- HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize);
+ const HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize);
_pos += realProcessedSize;
_glob->Pos = _pos;
if (processedSize)
@@ -226,19 +219,23 @@ HRESULT CDecoder::Decode(
, ISequentialOutStream *outStream
, ICompressProgressInfo *compressProgress
+
, ISequentialInStream **
+ #ifdef USE_MIXER_ST
+ inStreamMainRes
+ #endif
- #ifdef USE_MIXER_ST
- inStreamMainRes
- #endif
+ , bool &dataAfterEnd_Error
- _7Z_DECODER_CRYPRO_VARS_DECL
+ Z7_7Z_DECODER_CRYPRO_VARS_DECL
- #if !defined(_7ZIP_ST) && !defined(_SFX)
- , bool mtMode, UInt32 numThreads
+ #if !defined(Z7_ST)
+ , bool mtMode, UInt32 numThreads, UInt64 memUsage
#endif
)
{
+ dataAfterEnd_Error = false;
+
const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]];
CFolderEx folderInfo;
folders.ParseFolderEx(folderIndex, folderInfo);
@@ -264,7 +261,7 @@ HRESULT CDecoder::Decode(
We don't need to init isEncrypted and passwordIsDefined
We must upgrade them only
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
isEncrypted = false;
passwordIsDefined = false;
#endif
@@ -272,6 +269,7 @@ HRESULT CDecoder::Decode(
if (!_bindInfoPrev_Defined || !AreBindInfoExEqual(bindInfo, _bindInfoPrev))
{
+ _bindInfoPrev_Defined = false;
_mixerRef.Release();
#ifdef USE_MIXER_MT
@@ -295,22 +293,22 @@ HRESULT CDecoder::Decode(
#endif
}
- RINOK(_mixer->SetBindInfo(bindInfo));
+ RINOK(_mixer->SetBindInfo(bindInfo))
FOR_VECTOR(i, folderInfo.Coders)
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
- #ifndef _SFX
+ #ifndef Z7_SFX
// we don't support RAR codecs here
if ((coderInfo.MethodID >> 8) == 0x403)
return E_NOTIMPL;
#endif
CCreatedCoder cod;
- RINOK(CreateCoder(
+ RINOK(CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
- coderInfo.MethodID, false, cod));
+ coderInfo.MethodID, false, cod))
if (coderInfo.IsSimpleCoder())
{
@@ -328,13 +326,13 @@ HRESULT CDecoder::Decode(
// now there is no codec that uses another external codec
/*
- #ifdef EXTERNAL_CODECS
+ #ifdef Z7_EXTERNAL_CODECS
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
if (setCompressCodecsInfo)
{
// we must use g_ExternalCodecs also
- RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs));
}
#endif
*/
@@ -344,83 +342,126 @@ HRESULT CDecoder::Decode(
_bindInfoPrev_Defined = true;
}
- _mixer->ReInit();
+ RINOK(_mixer->ReInit2())
UInt32 packStreamIndex = 0;
UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex];
unsigned i;
+ #if !defined(Z7_ST)
+ bool mt_wasUsed = false;
+ #endif
+
for (i = 0; i < folderInfo.Coders.Size(); i++)
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
IUnknown *decoder = _mixer->GetCoder(i).GetUnknown();
+ // now there is no codec that uses another external codec
+ /*
+ #ifdef Z7_EXTERNAL_CODECS
{
- CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
- decoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
- if (setDecoderProperties)
+ Z7_DECL_CMyComPtr_QI_FROM(ISetCompressCodecsInfo,
+ setCompressCodecsInfo, decoder)
+ if (setCompressCodecsInfo)
{
- const CByteBuffer &props = coderInfo.Props;
- size_t size = props.Size();
- if (size > 0xFFFFFFFF)
- return E_NOTIMPL;
- HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size);
- if (res == E_INVALIDARG)
- res = E_NOTIMPL;
- RINOK(res);
+ // we must use g_ExternalCodecs also
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs))
}
}
+ #endif
+ */
- #if !defined(_7ZIP_ST) && !defined(_SFX)
- if (mtMode)
+ #if !defined(Z7_ST)
+ if (!mt_wasUsed)
{
- CMyComPtr<ICompressSetCoderMt> setCoderMt;
- decoder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
- if (setCoderMt)
+ if (mtMode)
{
- RINOK(setCoderMt->SetNumberOfThreads(numThreads));
+ Z7_DECL_CMyComPtr_QI_FROM(ICompressSetCoderMt,
+ setCoderMt, decoder)
+ if (setCoderMt)
+ {
+ mt_wasUsed = true;
+ RINOK(setCoderMt->SetNumberOfThreads(numThreads))
+ }
+ }
+ // if (memUsage != 0)
+ {
+ Z7_DECL_CMyComPtr_QI_FROM(ICompressSetMemLimit,
+ setMemLimit, decoder)
+ if (setMemLimit)
+ {
+ mt_wasUsed = true;
+ RINOK(setMemLimit->SetMemLimit(memUsage))
+ }
}
}
#endif
- #ifndef _NO_CRYPTO
{
- CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
- decoder->QueryInterface(IID_ICryptoSetPassword, (void **)&cryptoSetPassword);
+ Z7_DECL_CMyComPtr_QI_FROM(
+ ICompressSetDecoderProperties2,
+ setDecoderProperties, decoder)
+ const CByteBuffer &props = coderInfo.Props;
+ const UInt32 size32 = (UInt32)props.Size();
+ if (props.Size() != size32)
+ return E_NOTIMPL;
+ if (setDecoderProperties)
+ {
+ HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, size32);
+ if (res == E_INVALIDARG)
+ res = E_NOTIMPL;
+ RINOK(res)
+ }
+ else if (size32 != 0)
+ {
+ // v23: we fail, if decoder doesn't support properties
+ return E_NOTIMPL;
+ }
+ }
+
+ #ifndef Z7_NO_CRYPTO
+ {
+ Z7_DECL_CMyComPtr_QI_FROM(
+ ICryptoSetPassword,
+ cryptoSetPassword, decoder)
if (cryptoSetPassword)
{
isEncrypted = true;
if (!getTextPassword)
return E_NOTIMPL;
- CMyComBSTR passwordBSTR;
- RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
+ CMyComBSTR_Wipe passwordBSTR;
+ RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR))
passwordIsDefined = true;
- password.Empty();
+ password.Wipe_and_Empty();
size_t len = 0;
if (passwordBSTR)
{
password = passwordBSTR;
len = password.Len();
}
- CByteBuffer buffer(len * 2);
+ CByteBuffer_Wipe buffer(len * 2);
for (size_t k = 0; k < len; k++)
{
- wchar_t c = passwordBSTR[k];
+ const wchar_t c = passwordBSTR[k];
((Byte *)buffer)[k * 2] = (Byte)c;
((Byte *)buffer)[k * 2 + 1] = (Byte)(c >> 8);
}
- RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size()));
+ RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size()))
}
}
#endif
+ bool finishMode = false;
{
- CMyComPtr<ICompressSetFinishMode> setFinishMode;
- decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
+ Z7_DECL_CMyComPtr_QI_FROM(
+ ICompressSetFinishMode,
+ setFinishMode, decoder)
if (setFinishMode)
{
- RINOK(setFinishMode->SetFinishMode(BoolToInt(fullUnpack)));
+ finishMode = fullUnpack;
+ RINOK(setFinishMode->SetFinishMode(BoolToUInt(finishMode)))
}
}
@@ -450,7 +491,7 @@ HRESULT CDecoder::Decode(
unpackSize :
&folders.CoderUnpackSizes[unpackStreamIndexStart + i];
- _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers);
+ _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers, finishMode);
}
if (outStream)
@@ -463,36 +504,49 @@ HRESULT CDecoder::Decode(
CLockedInStream *lockedInStreamSpec = new CLockedInStream;
CMyComPtr<IUnknown> lockedInStream = lockedInStreamSpec;
- bool needMtLock = false;
+ #ifdef USE_MIXER_MT
+ #ifdef USE_MIXER_ST
+ bool needMtLock = _useMixerMT;
+ #endif
+ #endif
if (folderInfo.PackStreams.Size() > 1)
{
// lockedInStream.Pos = (UInt64)(Int64)-1;
- // RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &lockedInStream.Pos));
- RINOK(inStream->Seek(startPos + packPositions[0], STREAM_SEEK_SET, &lockedInStreamSpec->Pos));
+ // RINOK(InStream_GetPos(inStream, lockedInStream.Pos))
+ RINOK(inStream->Seek((Int64)(startPos + packPositions[0]), STREAM_SEEK_SET, &lockedInStreamSpec->Pos))
lockedInStreamSpec->Stream = inStream;
+ #ifdef USE_MIXER_MT
#ifdef USE_MIXER_ST
- if (_mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex))
- #endif
+ /*
+ For ST-mixer mode:
+ If parallel input stream reading from pack streams is possible,
+ we must use MT-lock for packed streams.
+ Internal decoders in 7-Zip will not read pack streams in parallel in ST-mixer mode.
+ So we force to needMtLock mode only if there is unknown (external) decoder.
+ */
+ if (!needMtLock && _mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex))
needMtLock = true;
+ #endif
+ #endif
}
for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++)
{
CMyComPtr<ISequentialInStream> packStream;
- UInt64 packPos = startPos + packPositions[j];
+ const UInt64 packPos = startPos + packPositions[j];
if (folderInfo.PackStreams.Size() == 1)
{
- RINOK(inStream->Seek(packPos, STREAM_SEEK_SET, NULL));
+ RINOK(InStream_SeekSet(inStream, packPos))
packStream = inStream;
}
else
{
#ifdef USE_MIXER_MT
#ifdef USE_MIXER_ST
- if (_useMixerMT || needMtLock)
+ if (needMtLock)
#endif
{
CLockedSequentialInStreamMT *lockedStreamImpSpec = new CLockedSequentialInStreamMT;
@@ -518,7 +572,7 @@ HRESULT CDecoder::Decode(
streamSpec->Init(packPositions[j + 1] - packPositions[j]);
}
- unsigned num = inStreams.Size();
+ const unsigned num = inStreams.Size();
CObjArray<ISequentialInStream *> inStreamPointers(num);
for (i = 0; i < num; i++)
inStreamPointers[i] = inStreams[i];
@@ -530,7 +584,9 @@ HRESULT CDecoder::Decode(
progress2 = new CDecProgress(compressProgress);
ISequentialOutStream *outStreamPointer = outStream;
- return _mixer->Code(inStreamPointers, &outStreamPointer, progress2 ? (ICompressProgressInfo *)progress2 : compressProgress);
+ return _mixer->Code(inStreamPointers, &outStreamPointer,
+ progress2 ? (ICompressProgressInfo *)progress2 : compressProgress,
+ dataAfterEnd_Error);
}
#ifdef USE_MIXER_ST
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h
index 5b729f6c86d..ee9d9c255b1 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h
@@ -1,7 +1,7 @@
// 7zDecode.h
-#ifndef __7Z_DECODE_H
-#define __7Z_DECODE_H
+#ifndef ZIP7_INC_7Z_DECODE_H
+#define ZIP7_INC_7Z_DECODE_H
#include "../Common/CoderMixer2.h"
@@ -24,10 +24,13 @@ struct CBindInfoEx: public NCoderMixer2::CBindInfo
class CDecoder
{
bool _bindInfoPrev_Defined;
+ #ifdef USE_MIXER_ST
+ #ifdef USE_MIXER_MT
+ bool _useMixerMT;
+ #endif
+ #endif
CBindInfoEx _bindInfoPrev;
- bool _useMixerMT;
-
#ifdef USE_MIXER_ST
NCoderMixer2::CMixerST *_mixerST;
#endif
@@ -53,12 +56,14 @@ public:
, ISequentialOutStream *outStream
, ICompressProgressInfo *compressProgress
+
, ISequentialInStream **inStreamMainRes
+ , bool &dataAfterEnd_Error
- _7Z_DECODER_CRYPRO_VARS_DECL
+ Z7_7Z_DECODER_CRYPRO_VARS_DECL
- #if !defined(_7ZIP_ST) && !defined(_SFX)
- , bool mtMode, UInt32 numThreads
+ #if !defined(Z7_ST)
+ , bool mtMode, UInt32 numThreads, UInt64 memUsage
#endif
);
};
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp
index 97e9ad7adb8..78c91cfa28b 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../../../Common/ComTry.h"
+
#include "../../Common/CreateCoder.h"
#include "../../Common/FilterCoder.h"
#include "../../Common/LimitedStreams.h"
@@ -19,11 +21,11 @@ void CEncoder::InitBindConv()
{
unsigned numIn = _bindInfo.Coders.Size();
- _SrcIn_to_DestOut.ClearAndSetSize(numIn);
- _DestOut_to_SrcIn.ClearAndSetSize(numIn);
+ SrcIn_to_DestOut.ClearAndSetSize(numIn);
+ DestOut_to_SrcIn.ClearAndSetSize(numIn);
unsigned numOut = _bindInfo.GetNum_Bonds_and_PackStreams();
- _SrcOut_to_DestIn.ClearAndSetSize(numOut);
+ SrcOut_to_DestIn.ClearAndSetSize(numOut);
// _DestIn_to_SrcOut.ClearAndSetSize(numOut);
UInt32 destIn = 0;
@@ -38,15 +40,15 @@ void CEncoder::InitBindConv()
numIn--;
numOut -= coder.NumStreams;
- _SrcIn_to_DestOut[numIn] = destOut;
- _DestOut_to_SrcIn[destOut] = numIn;
+ SrcIn_to_DestOut[numIn] = destOut;
+ DestOut_to_SrcIn[destOut] = numIn;
destOut++;
for (UInt32 j = 0; j < coder.NumStreams; j++, destIn++)
{
UInt32 index = numOut + j;
- _SrcOut_to_DestIn[index] = destIn;
+ SrcOut_to_DestIn[index] = destIn;
// _DestIn_to_SrcOut[destIn] = index;
}
}
@@ -62,8 +64,8 @@ void CEncoder::SetFolder(CFolder &folder)
{
CBond &fb = folder.Bonds[i];
const NCoderMixer2::CBond &mixerBond = _bindInfo.Bonds[_bindInfo.Bonds.Size() - 1 - i];
- fb.PackIndex = _SrcOut_to_DestIn[mixerBond.PackIndex];
- fb.UnpackIndex = _SrcIn_to_DestOut[mixerBond.UnpackIndex];
+ fb.PackIndex = SrcOut_to_DestIn[mixerBond.PackIndex];
+ fb.UnpackIndex = SrcIn_to_DestOut[mixerBond.UnpackIndex];
}
folder.Coders.SetSize(_bindInfo.Coders.Size());
@@ -81,15 +83,16 @@ void CEncoder::SetFolder(CFolder &folder)
folder.PackStreams.SetSize(_bindInfo.PackStreams.Size());
for (i = 0; i < _bindInfo.PackStreams.Size(); i++)
- folder.PackStreams[i] = _SrcOut_to_DestIn[_bindInfo.PackStreams[i]];
+ folder.PackStreams[i] = SrcOut_to_DestIn[_bindInfo.PackStreams[i]];
}
static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder)
{
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
+ Z7_DECL_CMyComPtr_QI_FROM(
+ ICompressSetCoderProperties,
+ setCoderProperties, coder)
if (setCoderProperties)
return props.SetCoderProps(setCoderProperties, dataSizeReduce);
return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK;
@@ -103,11 +106,11 @@ void CMtEncMultiProgress::Init(ICompressProgressInfo *progress)
OutSize = 0;
}
-STDMETHODIMP CMtEncMultiProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)
+Z7_COM7F_IMF(CMtEncMultiProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */))
{
UInt64 outSize2;
{
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
#endif
outSize2 = OutSize;
@@ -146,7 +149,7 @@ HRESULT CEncoder::CreateMixerCoder(
#endif
}
- RINOK(_mixer->SetBindInfo(_bindInfo));
+ RINOK(_mixer->SetBindInfo(_bindInfo))
FOR_VECTOR (m, _options.Methods)
{
@@ -154,29 +157,46 @@ HRESULT CEncoder::CreateMixerCoder(
CCreatedCoder cod;
- RINOK(CreateCoder(
+ if (methodFull.CodecIndex >= 0)
+ {
+ RINOK(CreateCoder_Index(
+ EXTERNAL_CODECS_LOC_VARS
+ (unsigned)methodFull.CodecIndex, true, cod))
+ }
+ else
+ {
+ RINOK(CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
- methodFull.Id, true, cod));
+ methodFull.Id, true, cod))
+ }
- if (cod.NumStreams != methodFull.NumStreams)
- return E_FAIL;
if (!cod.Coder && !cod.Coder2)
+ {
+ return E_NOTIMPL; // unsupported method, if encoder
+ // return E_FAIL;
+ }
+
+ if (cod.NumStreams != methodFull.NumStreams)
return E_FAIL;
CMyComPtr<IUnknown> encoderCommon = cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2;
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
+ if (methodFull.Set_NumThreads)
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
if (setCoderMt)
{
- RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));
+ RINOK(setCoderMt->SetNumberOfThreads(
+ /* _options.NumThreads */
+ methodFull.NumThreads
+ ))
}
}
#endif
- RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon));
+ RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon))
/*
CMyComPtr<ICryptoResetSalt> resetSalt;
@@ -189,13 +209,13 @@ HRESULT CEncoder::CreateMixerCoder(
// now there is no codec that uses another external codec
/*
- #ifdef EXTERNAL_CODECS
+ #ifdef Z7_EXTERNAL_CODECS
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
if (setCompressCodecsInfo)
{
// we must use g_ExternalCodecs also
- RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs));
}
#endif
*/
@@ -206,14 +226,14 @@ HRESULT CEncoder::CreateMixerCoder(
if (cryptoSetPassword)
{
const unsigned sizeInBytes = _options.Password.Len() * 2;
- CByteBuffer buffer(sizeInBytes);
+ CByteBuffer_Wipe buffer(sizeInBytes);
for (unsigned i = 0; i < _options.Password.Len(); i++)
{
wchar_t c = _options.Password[i];
((Byte *)buffer)[i * 2] = (Byte)c;
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
}
- RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)sizeInBytes));
+ RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)sizeInBytes))
}
_mixer->AddCoder(cod);
@@ -223,84 +243,94 @@ HRESULT CEncoder::CreateMixerCoder(
-class CSequentialOutTempBufferImp2:
- public ISequentialOutStream,
- public CMyUnknownImp
-{
- CInOutTempBuffer *_buf;
+Z7_CLASS_IMP_COM_1(
+ CSequentialOutTempBufferImp2
+ , ISequentialOutStream
+)
public:
- CMtEncMultiProgress *_mtProgresSpec;
+ CInOutTempBuffer TempBuffer;
+ CMtEncMultiProgress *_mtProgressSpec;
- CSequentialOutTempBufferImp2(): _buf(0), _mtProgresSpec(NULL) {}
- void Init(CInOutTempBuffer *buffer) { _buf = buffer; }
- MY_UNKNOWN_IMP1(ISequentialOutStream)
-
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ CSequentialOutTempBufferImp2(): _mtProgressSpec(NULL) {}
};
-STDMETHODIMP CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed)
+Z7_COM7F_IMF(CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed))
{
- if (!_buf->Write(data, size))
- {
- if (processed)
- *processed = 0;
- return E_FAIL;
- }
+ COM_TRY_BEGIN
+ if (processed)
+ *processed = 0;
+ RINOK(TempBuffer.Write_HRESULT(data, size))
if (processed)
*processed = size;
- if (_mtProgresSpec)
- _mtProgresSpec->AddOutSize(size);
+ if (_mtProgressSpec)
+ _mtProgressSpec->AddOutSize(size);
return S_OK;
+ COM_TRY_END
}
-class CSequentialOutMtNotify:
- public ISequentialOutStream,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_COM_1(
+ CSequentialOutMtNotify
+ , ISequentialOutStream
+)
public:
CMyComPtr<ISequentialOutStream> _stream;
- CMtEncMultiProgress *_mtProgresSpec;
+ CMtEncMultiProgress *_mtProgressSpec;
- CSequentialOutMtNotify(): _mtProgresSpec(NULL) {}
- MY_UNKNOWN_IMP1(ISequentialOutStream)
-
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ CSequentialOutMtNotify(): _mtProgressSpec(NULL) {}
};
-STDMETHODIMP CSequentialOutMtNotify::Write(const void *data, UInt32 size, UInt32 *processed)
+Z7_COM7F_IMF(CSequentialOutMtNotify::Write(const void *data, UInt32 size, UInt32 *processed))
{
UInt32 realProcessed = 0;
HRESULT res = _stream->Write(data, size, &realProcessed);
if (processed)
*processed = realProcessed;
- if (_mtProgresSpec)
- _mtProgresSpec->AddOutSize(size);
+ if (_mtProgressSpec)
+ _mtProgressSpec->AddOutSize(size);
return res;
}
+static HRESULT FillProps_from_Coder(IUnknown *coder, CByteBuffer &props)
+{
+ Z7_DECL_CMyComPtr_QI_FROM(
+ ICompressWriteCoderProperties,
+ writeCoderProperties, coder)
+ if (writeCoderProperties)
+ {
+ CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
+ CMyComPtr<ISequentialOutStream> dynOutStream(outStreamSpec);
+ outStreamSpec->Init();
+ RINOK(writeCoderProperties->WriteCoderProperties(dynOutStream))
+ outStreamSpec->CopyToBuffer(props);
+ }
+ else
+ props.Free();
+ return S_OK;
+}
-HRESULT CEncoder::Encode(
+HRESULT CEncoder::Encode1(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream,
// const UInt64 *inStreamSize,
const UInt64 *inSizeForReduce,
+ UInt64 expectedDataSize,
CFolder &folderItem,
- CRecordVector<UInt64> &coderUnpackSizes,
- UInt64 &unpackSize,
+ // CRecordVector<UInt64> &coderUnpackSizes,
+ // UInt64 &unpackSize,
ISequentialOutStream *outStream,
CRecordVector<UInt64> &packSizes,
ICompressProgressInfo *compressProgress)
{
- RINOK(EncoderConstr());
+ RINOK(EncoderConstr())
if (!_mixerRef)
{
- RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
+ RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce))
}
- _mixer->ReInit();
+ RINOK(_mixer->ReInit2())
CMtEncMultiProgress *mtProgressSpec = NULL;
CMyComPtr<ICompressProgressInfo> mtProgress;
@@ -308,32 +338,23 @@ HRESULT CEncoder::Encode(
CSequentialOutMtNotify *mtOutStreamNotifySpec = NULL;
CMyComPtr<ISequentialOutStream> mtOutStreamNotify;
- CObjectVector<CInOutTempBuffer> inOutTempBuffers;
- CObjectVector<CSequentialOutTempBufferImp2 *> tempBufferSpecs;
+ CRecordVector<CSequentialOutTempBufferImp2 *> tempBufferSpecs;
CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
- unsigned numMethods = _bindInfo.Coders.Size();
-
unsigned i;
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
{
- CInOutTempBuffer &iotb = inOutTempBuffers.AddNew();
- iotb.Create();
- iotb.InitWriting();
- }
-
- for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
- {
- CSequentialOutTempBufferImp2 *tempBufferSpec = new CSequentialOutTempBufferImp2;
+ CSequentialOutTempBufferImp2 *tempBufferSpec = new CSequentialOutTempBufferImp2();
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
- tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
- tempBuffers.Add(tempBuffer);
tempBufferSpecs.Add(tempBufferSpec);
+ tempBuffers.Add(tempBuffer);
}
+ const unsigned numMethods = _bindInfo.Coders.Size();
+
for (i = 0; i < numMethods; i++)
- _mixer->SetCoderInfo(i, NULL, NULL);
+ _mixer->SetCoderInfo(i, NULL, NULL, false);
/* inStreamSize can be used by BCJ2 to set optimal range of conversion.
@@ -346,15 +367,19 @@ HRESULT CEncoder::Encode(
*/
+ /*
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
+ */
CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL;
CMyComPtr<ISequentialOutStream> outStreamSizeCount;
- inStreamSizeCountSpec->Init(inStream);
+ // inStreamSizeCountSpec->Init(inStream);
+
+ // ISequentialInStream *inStreamPointer = inStreamSizeCount;
+ ISequentialInStream *inStreamPointer = inStream;
- ISequentialInStream *inStreamPointer = inStreamSizeCount;
CRecordVector<ISequentialOutStream *> outStreamPointers;
SetFolder(folderItem);
@@ -362,38 +387,66 @@ HRESULT CEncoder::Encode(
for (i = 0; i < numMethods; i++)
{
IUnknown *coder = _mixer->GetCoder(i).GetUnknown();
+ /*
+ {
+ CEncoder *sfEncoder = NULL;
+ Z7_DECL_CMyComPtr_QI_FROM(
+ IGetSfEncoderInternal,
+ sf, coder)
+ if (sf)
+ {
+ RINOK(sf->GetSfEncoder(&sfEncoder));
+ if (!sfEncoder)
+ return E_FAIL;
- CMyComPtr<ICryptoResetInitVector> resetInitVector;
- coder->QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
- if (resetInitVector)
+ }
+ }
+ */
+ /*
+ #ifdef Z7_EXTERNAL_CODECS
{
- resetInitVector->ResetInitVector();
+ Z7_DECL_CMyComPtr_QI_FROM(
+ ISetCompressCodecsInfo,
+ setCompressCodecsInfo, coder)
+ if (setCompressCodecsInfo)
+ {
+ // we must use g_ExternalCodecs also
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs))
+ }
}
-
- CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
- coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
-
- CByteBuffer &props = folderItem.Coders[numMethods - 1 - i].Props;
-
- if (writeCoderProperties)
+ #endif
+ */
{
- CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
- CMyComPtr<ISequentialOutStream> dynOutStream(outStreamSpec);
- outStreamSpec->Init();
- writeCoderProperties->WriteCoderProperties(dynOutStream);
- outStreamSpec->CopyToBuffer(props);
+ Z7_DECL_CMyComPtr_QI_FROM(
+ ICryptoResetInitVector,
+ resetInitVector, coder)
+ if (resetInitVector)
+ {
+ RINOK(resetInitVector->ResetInitVector())
+ }
}
- else
- props.Free();
+ {
+ Z7_DECL_CMyComPtr_QI_FROM(
+ ICompressSetCoderPropertiesOpt,
+ optProps, coder)
+ if (optProps)
+ {
+ const PROPID propID = NCoderPropID::kExpectedDataSize;
+ NWindows::NCOM::CPropVariant prop = (UInt64)expectedDataSize;
+ RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1))
+ }
+ }
+ // we must write properties from coder after ResetInitVector()
+ RINOK(FillProps_from_Coder(coder, folderItem.Coders[numMethods - 1 - i].Props))
}
_mixer->SelectMainCoder(false);
- UInt32 mainCoder = _mixer->MainCoderIndex;
+ const UInt32 mainCoder = _mixer->MainCoderIndex;
bool useMtProgress = false;
if (!_mixer->Is_PackSize_Correct_for_Coder(mainCoder))
{
- #ifdef _7ZIP_ST
+ #ifdef Z7_ST
if (!_mixer->IsThere_ExternalCoder_in_PackTree(mainCoder))
#endif
useMtProgress = true;
@@ -408,11 +461,11 @@ HRESULT CEncoder::Encode(
mtOutStreamNotifySpec = new CSequentialOutMtNotify;
mtOutStreamNotify = mtOutStreamNotifySpec;
mtOutStreamNotifySpec->_stream = outStream;
- mtOutStreamNotifySpec->_mtProgresSpec = mtProgressSpec;
+ mtOutStreamNotifySpec->_mtProgressSpec = mtProgressSpec;
- FOR_VECTOR(t, tempBufferSpecs)
+ FOR_VECTOR (t, tempBufferSpecs)
{
- tempBufferSpecs[t]->_mtProgresSpec = mtProgressSpec;
+ tempBufferSpecs[t]->_mtProgressSpec = mtProgressSpec;
}
}
@@ -429,38 +482,54 @@ HRESULT CEncoder::Encode(
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
outStreamPointers.Add(tempBuffers[i - 1]);
+ bool dataAfterEnd_Error;
+
RINOK(_mixer->Code(
&inStreamPointer,
&outStreamPointers.Front(),
- mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress));
+ mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress, dataAfterEnd_Error))
if (_bindInfo.PackStreams.Size() != 0)
packSizes.Add(outStreamSizeCountSpec->GetSize());
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
{
- CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
- RINOK(inOutTempBuffer.WriteToStream(outStream));
- packSizes.Add(inOutTempBuffer.GetDataSize());
+ CInOutTempBuffer &iotb = tempBufferSpecs[i - 1]->TempBuffer;
+ RINOK(iotb.WriteToStream(outStream))
+ packSizes.Add(iotb.GetDataSize());
}
- unpackSize = 0;
-
- for (i = 0; i < _bindInfo.Coders.Size(); i++)
+ /* Code() in some future codec can change properties.
+ v23: so we fill properties again after Code() */
+ for (i = 0; i < numMethods; i++)
+ {
+ IUnknown *coder = _mixer->GetCoder(i).GetUnknown();
+ RINOK(FillProps_from_Coder(coder, folderItem.Coders[numMethods - 1 - i].Props))
+ }
+
+ return S_OK;
+}
+
+
+void CEncoder::Encode_Post(
+ UInt64 unpackSize,
+ CRecordVector<UInt64> &coderUnpackSizes)
+{
+ // unpackSize = 0;
+ for (unsigned i = 0; i < _bindInfo.Coders.Size(); i++)
{
- int bond = _bindInfo.FindBond_for_UnpackStream(_DestOut_to_SrcIn[i]);
+ const int bond = _bindInfo.FindBond_for_UnpackStream(DestOut_to_SrcIn[i]);
UInt64 streamSize;
if (bond < 0)
{
- streamSize = inStreamSizeCountSpec->GetSize();
- unpackSize = streamSize;
+ // streamSize = inStreamSizeCountSpec->GetSize();
+ // unpackSize = streamSize;
+ streamSize = unpackSize;
}
else
- streamSize = _mixer->GetBondStreamSize(bond);
+ streamSize = _mixer->GetBondStreamSize((unsigned)bond);
coderUnpackSizes.Add(streamSize);
}
-
- return S_OK;
}
@@ -583,17 +652,17 @@ HRESULT CEncoder::EncoderConstr()
if (_bindInfo.Coders[ci].NumStreams == 0)
break;
- UInt32 outIndex = _bindInfo.Coder_to_Stream[ci];
- int bond = _bindInfo.FindBond_for_PackStream(outIndex);
+ const UInt32 outIndex = _bindInfo.Coder_to_Stream[ci];
+ const int bond = _bindInfo.FindBond_for_PackStream(outIndex);
if (bond >= 0)
{
- ci = _bindInfo.Bonds[bond].UnpackIndex;
+ ci = _bindInfo.Bonds[(unsigned)bond].UnpackIndex;
continue;
}
- int si = _bindInfo.FindStream_in_PackStreams(outIndex);
+ const int si = _bindInfo.FindStream_in_PackStreams(outIndex);
if (si >= 0)
- _bindInfo.PackStreams.MoveToFront(si);
+ _bindInfo.PackStreams.MoveToFront((unsigned)si);
break;
}
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h
index f1a9b5ad720..849ac63b9f4 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h
@@ -1,7 +1,7 @@
// 7zEncode.h
-#ifndef __7Z_ENCODE_H
-#define __7Z_ENCODE_H
+#ifndef ZIP7_INC_7Z_ENCODE_H
+#define ZIP7_INC_7Z_ENCODE_H
#include "7zCompressionMode.h"
@@ -12,12 +12,12 @@
namespace NArchive {
namespace N7z {
-class CMtEncMultiProgress:
- public ICompressProgressInfo,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_COM_1(
+ CMtEncMultiProgress,
+ ICompressProgressInfo
+)
CMyComPtr<ICompressProgressInfo> _progress;
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
NWindows::NSynchronization::CCriticalSection CriticalSection;
#endif
@@ -30,18 +30,15 @@ public:
void AddOutSize(UInt64 addOutSize)
{
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
#endif
OutSize += addOutSize;
}
-
- MY_UNKNOWN_IMP1(ICompressProgressInfo)
-
- STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
-class CEncoder
+
+class CEncoder Z7_final MY_UNCOPYABLE
{
#ifdef USE_MIXER_ST
NCoderMixer2::CMixerST *_mixerST;
@@ -57,10 +54,10 @@ class CEncoder
NCoderMixer2::CBindInfo _bindInfo;
CRecordVector<CMethodId> _decompressionMethods;
- CRecordVector<UInt32> _SrcIn_to_DestOut;
- CRecordVector<UInt32> _SrcOut_to_DestIn;
- // CRecordVector<UInt32> _DestIn_to_SrcOut;
- CRecordVector<UInt32> _DestOut_to_SrcIn;
+ CRecordVector<UInt32> SrcIn_to_DestOut;
+ CRecordVector<UInt32> SrcOut_to_DestIn;
+ // CRecordVector<UInt32> DestIn_to_SrcOut;
+ CRecordVector<UInt32> DestOut_to_SrcIn;
void InitBindConv();
void SetFolder(CFolder &folder);
@@ -74,17 +71,23 @@ public:
CEncoder(const CCompressionMethodMode &options);
~CEncoder();
HRESULT EncoderConstr();
- HRESULT Encode(
+ HRESULT Encode1(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream,
// const UInt64 *inStreamSize,
const UInt64 *inSizeForReduce,
+ UInt64 expectedDataSize,
CFolder &folderItem,
- CRecordVector<UInt64> &coderUnpackSizes,
- UInt64 &unpackSize,
+ // CRecordVector<UInt64> &coderUnpackSizes,
+ // UInt64 &unpackSize,
ISequentialOutStream *outStream,
CRecordVector<UInt64> &packSizes,
ICompressProgressInfo *compressProgress);
+
+ void Encode_Post(
+ UInt64 unpackSize,
+ CRecordVector<UInt64> &coderUnpackSizes);
+
};
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp
index 05fd80de3fd..5498c590cee 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp
@@ -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;
@@ -152,6 +150,12 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
if (_fileIsOpen)
{
UInt32 cur = (size < _rem ? size : (UInt32)_rem);
+ if (_calcCrc)
+ {
+ const UInt32 k_Step = (UInt32)1 << 20;
+ if (cur > k_Step)
+ cur = k_Step;
+ }
HRESULT result = S_OK;
if (_stream)
result = _stream->Write(data, cur, &cur);
@@ -164,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
@@ -186,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;
@@ -198,19 +202,37 @@ 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;
+ // CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
+
COM_TRY_BEGIN
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
@@ -219,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();
@@ -234,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)
@@ -247,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;
@@ -258,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
@@ -271,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);
@@ -284,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;
@@ -293,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;
@@ -306,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;
@@ -320,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;
+ }
+
+ if (folderIndex == kNumNoIndex)
+ return E_FAIL;
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (extractCallback)
extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
@@ -341,14 +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 password;
+ UString_Wipe password;
#endif
+ bool dataAfterEnd_Error = false;
- HRESULT result = decoder.Decode(
+ const HRESULT result = decoder.Decode(
EXTERNAL_CODECS_VARS
_inStream,
_db.ArcInfo.DataStartPosition,
@@ -358,29 +387,36 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
outStream,
progress,
NULL // *inStreamMainRes
+ , dataAfterEnd_Error
- _7Z_DECODER_CRYPRO_VARS
- #if !defined(_7ZIP_ST) && !defined(_SFX)
- , true, _numThreads
+ Z7_7Z_DECODER_CRYPRO_VARS
+ #if !defined(Z7_ST)
+ , true, _numThreads, _memUsage_Decompress
#endif
);
- if (result == S_FALSE || result == E_NOTIMPL)
+ if (result == S_FALSE || result == E_NOTIMPL || dataAfterEnd_Error)
{
- bool wasFinished = folderOutStream->WasWritingFinished();
-
- int resOp = (result == S_FALSE ?
- NExtract::NOperationResult::kDataError :
- NExtract::NOperationResult::kUnsupportedMethod);
+ const bool wasFinished = folderOutStream->WasWritingFinished();
- RINOK(folderOutStream->FlushCorrupted(resOp));
+ int resOp = NExtract::NOperationResult::kDataError;
+
+ if (result != S_FALSE)
+ {
+ if (result == E_NOTIMPL)
+ resOp = NExtract::NOperationResult::kUnsupportedMethod;
+ else if (wasFinished && dataAfterEnd_Error)
+ resOp = NExtract::NOperationResult::kDataAfterEnd;
+ }
+
+ 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;
@@ -389,14 +425,15 @@ 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;
+ // return E_FAIL;
+ throw;
}
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp
index 14cdc436452..08231893905 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../../../Windows/TimeUtils.h"
+
#include "7zFolderInStream.h"
namespace NArchive {
@@ -13,66 +15,129 @@ void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
_updateCallback = updateCallback;
_indexes = indexes;
_numFiles = numFiles;
- _index = 0;
+
+ _totalSize_for_Coder = 0;
+ ClearFileInfo();
Processed.ClearAndReserve(numFiles);
- CRCs.ClearAndReserve(numFiles);
Sizes.ClearAndReserve(numFiles);
-
- _pos = 0;
- _crc = CRC_INIT_VAL;
- _size_Defined = false;
- _size = 0;
+ CRCs.ClearAndReserve(numFiles);
+ TimesDefined.ClearAndReserve(numFiles);
+ MTimes.ClearAndReserve(Need_MTime ? numFiles : (unsigned)0);
+ CTimes.ClearAndReserve(Need_CTime ? numFiles : (unsigned)0);
+ ATimes.ClearAndReserve(Need_ATime ? numFiles : (unsigned)0);
+ Attribs.ClearAndReserve(Need_Attrib ? numFiles : (unsigned)0);
+ // FolderCrc = CRC_INIT_VAL;
_stream.Release();
}
-HRESULT CFolderInStream::OpenStream()
+void CFolderInStream::ClearFileInfo()
{
_pos = 0;
_crc = CRC_INIT_VAL;
_size_Defined = false;
+ _times_Defined = false;
_size = 0;
+ FILETIME_Clear(_mTime);
+ FILETIME_Clear(_cTime);
+ FILETIME_Clear(_aTime);
+ _attrib = 0;
+}
- while (_index < _numFiles)
+HRESULT CFolderInStream::OpenStream()
+{
+ while (Processed.Size() < _numFiles)
{
CMyComPtr<ISequentialInStream> stream;
- HRESULT result = _updateCallback->GetStream(_indexes[_index], &stream);
- if (result != S_OK)
- {
- if (result != S_FALSE)
- return result;
- }
+ const HRESULT result = _updateCallback->GetStream(_indexes[Processed.Size()], &stream);
+ if (result != S_OK && result != S_FALSE)
+ return result;
_stream = stream;
if (stream)
{
- CMyComPtr<IStreamGetSize> streamGetSize;
- stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
- if (streamGetSize)
{
- if (streamGetSize->GetSize(&_size) == S_OK)
- _size_Defined = true;
+ CMyComPtr<IStreamGetProps> getProps;
+ stream.QueryInterface(IID_IStreamGetProps, (void **)&getProps);
+ if (getProps)
+ {
+ // access could be changed in first myx pass
+ if (getProps->GetProps(&_size,
+ Need_CTime ? &_cTime : NULL,
+ Need_ATime ? &_aTime : NULL,
+ Need_MTime ? &_mTime : NULL,
+ Need_Attrib ? &_attrib : NULL)
+ == S_OK)
+ {
+ _size_Defined = true;
+ _times_Defined = true;
+ }
+ return S_OK;
+ }
+ }
+ {
+ CMyComPtr<IStreamGetSize> streamGetSize;
+ stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
+ if (streamGetSize)
+ {
+ if (streamGetSize->GetSize(&_size) == S_OK)
+ _size_Defined = true;
+ }
+ return S_OK;
}
- return S_OK;
}
- _index++;
- RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
- AddFileInfo(result == S_OK);
+ RINOK(AddFileInfo(result == S_OK))
}
return S_OK;
}
-void CFolderInStream::AddFileInfo(bool isProcessed)
+static void AddFt(CRecordVector<UInt64> &vec, const FILETIME &ft)
{
- Processed.Add(isProcessed);
- Sizes.Add(_pos);
- CRCs.Add(CRC_GET_DIGEST(_crc));
+ vec.AddInReserved(FILETIME_To_UInt64(ft));
}
-STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+/*
+HRESULT ReportItemProps(IArchiveUpdateCallbackArcProp *reportArcProp,
+ UInt32 index, UInt64 size, const UInt32 *crc)
+{
+ PROPVARIANT prop;
+ prop.vt = VT_EMPTY;
+ prop.wReserved1 = 0;
+
+ NWindows::NCOM::PropVarEm_Set_UInt64(&prop, size);
+ RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidSize, &prop));
+ if (crc)
+ {
+ NWindows::NCOM::PropVarEm_Set_UInt32(&prop, *crc);
+ RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidCRC, &prop));
+ }
+ return reportArcProp->ReportFinished(NEventIndexType::kOutArcIndex, index, NUpdate::NOperationResult::kOK);
+}
+*/
+
+HRESULT CFolderInStream::AddFileInfo(bool isProcessed)
+{
+ // const UInt32 index = _indexes[Processed.Size()];
+ Processed.AddInReserved(isProcessed);
+ Sizes.AddInReserved(_pos);
+ CRCs.AddInReserved(CRC_GET_DIGEST(_crc));
+ if (Need_Attrib) Attribs.AddInReserved(_attrib);
+ TimesDefined.AddInReserved(_times_Defined);
+ if (Need_MTime) AddFt(MTimes, _mTime);
+ if (Need_CTime) AddFt(CTimes, _cTime);
+ if (Need_ATime) AddFt(ATimes, _aTime);
+ ClearFileInfo();
+ /*
+ if (isProcessed && _reportArcProp)
+ RINOK(ReportItemProps(_reportArcProp, index, _pos, &crc))
+ */
+ return _updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
+}
+
+Z7_COM7F_IMF(CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
{
if (processedSize)
*processedSize = 0;
@@ -80,43 +145,65 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
{
if (_stream)
{
- UInt32 processed2;
- RINOK(_stream->Read(data, size, &processed2));
- if (processed2 != 0)
+ /*
+ if (_pos == 0)
+ {
+ const UInt32 align = (UInt32)1 << AlignLog;
+ const UInt32 offset = (UInt32)_totalSize_for_Coder & (align - 1);
+ if (offset != 0)
+ {
+ UInt32 cur = align - offset;
+ if (cur > size)
+ cur = size;
+ memset(data, 0, cur);
+ data = (Byte *)data + cur;
+ size -= cur;
+ // _pos += cur; // for debug
+ _totalSize_for_Coder += cur;
+ if (processedSize)
+ *processedSize += cur;
+ continue;
+ }
+ }
+ */
+ UInt32 cur = size;
+ const UInt32 kMax = (UInt32)1 << 20;
+ if (cur > kMax)
+ cur = kMax;
+ RINOK(_stream->Read(data, cur, &cur))
+ if (cur != 0)
{
- _crc = CrcUpdate(_crc, data, processed2);
- _pos += processed2;
+ // if (Need_Crc)
+ _crc = CrcUpdate(_crc, data, cur);
+ /*
+ if (FolderCrc)
+ FolderCrc = CrcUpdate(FolderCrc, data, cur);
+ */
+ _pos += cur;
+ _totalSize_for_Coder += cur;
if (processedSize)
- *processedSize = processed2;
+ *processedSize = cur; // use +=cur, if continue is possible in loop
return S_OK;
}
_stream.Release();
- _index++;
- AddFileInfo(true);
-
- _pos = 0;
- _crc = CRC_INIT_VAL;
- _size_Defined = false;
- _size = 0;
-
- RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ RINOK(AddFileInfo(true))
}
- if (_index >= _numFiles)
+ if (Processed.Size() >= _numFiles)
break;
- RINOK(OpenStream());
+ RINOK(OpenStream())
}
return S_OK;
}
-STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
+Z7_COM7F_IMF(CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value))
{
*value = 0;
if (subStream > Sizes.Size())
return S_FALSE; // E_FAIL;
- unsigned index = (unsigned)subStream;
+ const unsigned index = (unsigned)subStream;
if (index < Sizes.Size())
{
*value = Sizes[index];
@@ -133,4 +220,45 @@ STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
return S_OK;
}
+
+/*
+HRESULT CFolderInStream::CloseCrcStream()
+{
+ if (!_crcStream)
+ return S_OK;
+ if (!_crcStream_Spec->WasFinished())
+ return E_FAIL;
+ _crc = _crcStream_Spec->GetCRC() ^ CRC_INIT_VAL; // change it
+ const UInt64 size = _crcStream_Spec->GetSize();
+ _pos = size;
+ _totalSize_for_Coder += size;
+ _crcStream.Release();
+ // _crcStream->ReleaseStream();
+ _stream.Release();
+ return AddFileInfo(true);
+}
+
+Z7_COM7F_IMF(CFolderInStream::GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream)
+{
+ RINOK(CloseCrcStream())
+ *stream = NULL;
+ *streamIndexRes = Processed.Size();
+ if (Processed.Size() >= _numFiles)
+ return S_OK;
+ RINOK(OpenStream());
+ if (!_stream)
+ return S_OK;
+ if (!_crcStream)
+ {
+ _crcStream_Spec = new CSequentialInStreamWithCRC;
+ _crcStream = _crcStream_Spec;
+ }
+ _crcStream_Spec->Init();
+ _crcStream_Spec->SetStream(_stream);
+ *stream = _crcStream;
+ _crcStream->AddRef();
+ return S_OK;
+}
+*/
+
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h
index 805db54e9d3..6447b25ca74 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h
@@ -1,12 +1,13 @@
// 7zFolderInStream.h
-#ifndef __7Z_FOLDER_IN_STREAM_H
-#define __7Z_FOLDER_IN_STREAM_H
+#ifndef ZIP7_INC_7Z_FOLDER_IN_STREAM_H
+#define ZIP7_INC_7Z_FOLDER_IN_STREAM_H
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
+// #include "../Common/InStreamWithCRC.h"
#include "../../ICoder.h"
#include "../IArchive.h"
@@ -14,39 +15,67 @@
namespace NArchive {
namespace N7z {
-class CFolderInStream:
- public ISequentialInStream,
- public ICompressGetSubStreamSize,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_COM_2(
+ CFolderInStream
+ , ISequentialInStream
+ , ICompressGetSubStreamSize
+)
+ /*
+ Z7_COM7F_IMP(GetNextStream(UInt64 *streamIndex))
+ Z7_IFACE_COM7_IMP(ICompressInSubStreams)
+ */
+
CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _totalSize_for_Coder;
UInt64 _pos;
UInt32 _crc;
bool _size_Defined;
+ bool _times_Defined;
UInt64 _size;
+ FILETIME _mTime;
+ FILETIME _cTime;
+ FILETIME _aTime;
+ UInt32 _attrib;
- const UInt32 *_indexes;
unsigned _numFiles;
- unsigned _index;
+ const UInt32 *_indexes;
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
+ void ClearFileInfo();
HRESULT OpenStream();
- void AddFileInfo(bool isProcessed);
-
+ HRESULT AddFileInfo(bool isProcessed);
+ // HRESULT CloseCrcStream();
public:
+ bool Need_MTime;
+ bool Need_CTime;
+ bool Need_ATime;
+ bool Need_Attrib;
+ // bool Need_Crc;
+ // bool Need_FolderCrc;
+ // unsigned AlignLog;
+
CRecordVector<bool> Processed;
- CRecordVector<UInt32> CRCs;
CRecordVector<UInt64> Sizes;
-
- MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
+ CRecordVector<UInt32> CRCs;
+ CRecordVector<UInt32> Attribs;
+ CRecordVector<bool> TimesDefined;
+ CRecordVector<UInt64> MTimes;
+ CRecordVector<UInt64> CTimes;
+ CRecordVector<UInt64> ATimes;
+ // UInt32 FolderCrc;
+
+ // UInt32 GetFolderCrc() const { return CRC_GET_DIGEST(FolderCrc); }
+ // CSequentialInStreamWithCRC *_crcStream_Spec;
+ // CMyComPtr<ISequentialInStream> _crcStream;
+ // CMyComPtr<IArchiveUpdateCallbackArcProp> _reportArcProp;
void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *indexes, unsigned numFiles);
- bool WasFinished() const { return _index == _numFiles; }
+ bool WasFinished() const { return Processed.Size() == _numFiles; }
+ UInt64 Get_TotalSize_for_Coder() const { return _totalSize_for_Coder; }
+ /*
UInt64 GetFullSize() const
{
UInt64 size = 0;
@@ -54,6 +83,17 @@ public:
size += Sizes[i];
return size;
}
+ */
+
+ CFolderInStream():
+ Need_MTime(false),
+ Need_CTime(false),
+ Need_ATime(false),
+ Need_Attrib(false)
+ // , Need_Crc(true)
+ // , Need_FolderCrc(false)
+ // , AlignLog(0)
+ {}
};
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp
index ccd2c624e66..23d3a9d56a7 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp
@@ -7,7 +7,7 @@
#include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h"
-#ifndef __7Z_SET_PROPERTIES
+#ifndef Z7_7Z_SET_PROPERTIES
#include "../../../Windows/System.h"
#endif
@@ -16,8 +16,8 @@
#include "7zHandler.h"
#include "7zProperties.h"
-#ifdef __7Z_SET_PROPERTIES
-#ifdef EXTRACT_ONLY
+#ifdef Z7_7Z_SET_PROPERTIES
+#ifdef Z7_EXTRACT_ONLY
#include "../Common/ParseProperties.h"
#endif
#endif
@@ -30,41 +30,40 @@ namespace N7z {
CHandler::CHandler()
{
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
_isEncrypted = false;
_passwordIsDefined = false;
#endif
- #ifdef EXTRACT_ONLY
+ #ifdef Z7_EXTRACT_ONLY
_crcSize = 4;
- #ifdef __7Z_SET_PROPERTIES
- _numThreads = NSystem::GetNumberOfProcessors();
+ #ifdef Z7_7Z_SET_PROPERTIES
_useMultiThreadMixer = true;
#endif
#endif
}
-STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
{
*numItems = _db.Files.Size();
return S_OK;
}
-#ifdef _SFX
+#ifdef Z7_SFX
IMP_IInArchive_ArcProps_NO_Table
-STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
+Z7_COM7F_IMF(CHandler::GetNumberOfProperties(UInt32 *numProps))
{
*numProps = 0;
return S_OK;
}
-STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
- BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
+Z7_COM7F_IMF(CHandler::GetPropertyInfo(UInt32 /* index */,
+ BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */))
{
return E_NOTIMPL;
}
@@ -108,34 +107,61 @@ static void ConvertMethodIdToString(AString &res, UInt64 id)
res += s + len - ConvertMethodIdToString_Back(s + len, id);
}
-static unsigned GetStringForSizeValue(char *s, UInt32 val)
+
+static char *GetStringForSizeValue(char *s, UInt32 val)
{
- unsigned i;
- for (i = 0; i <= 31; i++)
+ for (unsigned i = 0; i < 32; i++)
if (((UInt32)1 << i) == val)
{
- if (i < 10)
+ if (i >= 10)
{
- s[0] = (char)('0' + i);
- s[1] = 0;
- return 1;
+ *s++= (char)('0' + i / 10);
+ i %= 10;
}
- if (i < 20) { s[0] = '1'; s[1] = (char)('0' + i - 10); }
- else if (i < 30) { s[0] = '2'; s[1] = (char)('0' + i - 20); }
- else { s[0] = '3'; s[1] = (char)('0' + i - 30); }
- s[2] = 0;
- return 2;
+ *s++ = (char)('0' + i);
+ *s = 0;
+ return s;
}
+
char c = 'b';
if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
- ::ConvertUInt32ToString(val, s);
- unsigned pos = MyStringLen(s);
- s[pos++] = c;
- s[pos] = 0;
- return pos;
+ s = ConvertUInt32ToString(val, s);
+ *s++ = c;
+ *s = 0;
+ return s;
}
+
+static void GetLzma2String(char *s, unsigned d)
+{
+ if (d > 40)
+ {
+ *s = 0;
+ return;
+ // s = MyStpCpy(s, "unsup");
+ }
+ else if ((d & 1) == 0)
+ d = (d >> 1) + 12;
+ else
+ {
+ // s = GetStringForSizeValue(s, (UInt32)3 << ((d >> 1) + 11));
+ d = (d >> 1) + 1;
+ char c = 'k';
+ if (d >= 10)
+ {
+ c = 'm';
+ d -= 10;
+ }
+ s = ConvertUInt32ToString((UInt32)3 << d, s);
+ *s++ = c;
+ *s = 0;
+ return;
+ }
+ ConvertUInt32ToString(d, s);
+}
+
+
/*
static inline void AddHexToString(UString &res, Byte value)
{
@@ -148,8 +174,7 @@ static char *AddProp32(char *s, const char *name, UInt32 v)
{
*s++ = ':';
s = MyStpCpy(s, name);
- ::ConvertUInt32ToString(v, s);
- return s + MyStringLen(s);
+ return ConvertUInt32ToString(v, s);
}
void CHandler::AddMethodName(AString &s, UInt64 id)
@@ -164,15 +189,15 @@ void CHandler::AddMethodName(AString &s, UInt64 id)
#endif
-STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
{
- #ifndef _SFX
+ #ifndef Z7_SFX
COM_TRY_BEGIN
#endif
NCOM::CPropVariant prop;
switch (propID)
{
- #ifndef _SFX
+ #ifndef Z7_SFX
case kpidMethod:
{
AString s;
@@ -185,10 +210,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (id == k_LZMA2)
{
s += "LZMA2:";
- if ((pm.Lzma2Prop & 1) == 0)
- ConvertUInt32ToString((pm.Lzma2Prop >> 1) + 12, temp);
- else
- GetStringForSizeValue(temp, 3 << ((pm.Lzma2Prop >> 1) + 11));
+ GetLzma2String(temp, pm.Lzma2Prop);
s += temp;
}
else if (id == k_LZMA)
@@ -197,6 +219,12 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
GetStringForSizeValue(temp, pm.LzmaDic);
s += temp;
}
+ /*
+ else if (id == k_ZSTD)
+ {
+ s += "ZSTD";
+ }
+ */
else
AddMethodName(s, id);
}
@@ -237,36 +265,42 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = v;
break;
}
+
+ case kpidReadOnly:
+ {
+ if (!_db.CanUpdate())
+ prop = true;
+ break;
+ }
}
- prop.Detach(value);
- return S_OK;
- #ifndef _SFX
+ return prop.Detach(value);
+ #ifndef Z7_SFX
COM_TRY_END
#endif
}
-static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, int index)
+static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, unsigned index)
{
UInt64 value;
if (v.GetItem(index, value))
- PropVarEm_Set_FileTime64(prop, value);
+ PropVarEm_Set_FileTime64_Prec(prop, value, k_PropVar_TimePrec_100ns);
}
bool CHandler::IsFolderEncrypted(CNum folderIndex) const
{
if (folderIndex == kNumNoIndex)
return false;
- size_t startPos = _db.FoCodersDataOffset[folderIndex];
+ const size_t startPos = _db.FoCodersDataOffset[folderIndex];
const Byte *p = _db.CodersData + startPos;
- size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos;
+ const size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos;
CInByte2 inByte;
inByte.Init(p, size);
CNum numCoders = inByte.ReadNum();
for (; numCoders != 0; numCoders--)
{
- Byte mainByte = inByte.ReadByte();
- unsigned idSize = (mainByte & 0xF);
+ const Byte mainByte = inByte.ReadByte();
+ const unsigned idSize = (mainByte & 0xF);
const Byte *longID = inByte.GetPtr();
UInt64 id64 = 0;
for (unsigned j = 0; j < idSize; j++)
@@ -280,20 +314,20 @@ bool CHandler::IsFolderEncrypted(CNum folderIndex) const
return false;
}
-STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps)
+Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps))
{
*numProps = 0;
return S_OK;
}
-STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)
+Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID))
{
*name = NULL;
*propID = kpidNtSecure;
return S_OK;
}
-STDMETHODIMP CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)
+Z7_COM7F_IMF(CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType))
{
/*
const CFileItem &file = _db.Files[index];
@@ -305,7 +339,7 @@ STDMETHODIMP CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *par
return S_OK;
}
-STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
+Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType))
{
*data = NULL;
*dataSize = 0;
@@ -347,7 +381,7 @@ STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data
return S_OK;
}
-#ifndef _SFX
+#ifndef Z7_SFX
HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
{
@@ -360,9 +394,9 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
unsigned pos = kTempSize;
temp[--pos] = 0;
- size_t startPos = _db.FoCodersDataOffset[folderIndex];
+ const size_t startPos = _db.FoCodersDataOffset[folderIndex];
const Byte *p = _db.CodersData + startPos;
- size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos;
+ const size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos;
CInByte2 inByte;
inByte.Init(p, size);
@@ -374,10 +408,10 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
{
if (pos < 32) // max size of property
break;
- Byte mainByte = inByte.ReadByte();
- unsigned idSize = (mainByte & 0xF);
- const Byte *longID = inByte.GetPtr();
+ const Byte mainByte = inByte.ReadByte();
UInt64 id64 = 0;
+ const unsigned idSize = (mainByte & 0xF);
+ const Byte *longID = inByte.GetPtr();
for (unsigned j = 0; j < idSize; j++)
id64 = ((id64 << 8) | longID[j]);
inByte.SkipDataNoCheck(idSize);
@@ -403,21 +437,21 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
if (id64 <= (UInt32)0xFFFFFFFF)
{
- UInt32 id = (UInt32)id64;
+ const UInt32 id = (UInt32)id64;
if (id == k_LZMA)
{
name = "LZMA";
if (propsSize == 5)
{
- UInt32 dicSize = GetUi32((const Byte *)props + 1);
- char *dest = s + GetStringForSizeValue(s, dicSize);
+ const UInt32 dicSize = GetUi32((const Byte *)props + 1);
+ char *dest = GetStringForSizeValue(s, dicSize);
UInt32 d = props[0];
if (d != 0x5D)
{
- UInt32 lc = d % 9;
+ const UInt32 lc = d % 9;
d /= 9;
- UInt32 pb = d / 5;
- UInt32 lp = d % 5;
+ const UInt32 pb = d / 5;
+ const UInt32 lp = d % 5;
if (lc != 3) dest = AddProp32(dest, "lc", lc);
if (lp != 0) dest = AddProp32(dest, "lp", lp);
if (pb != 2) dest = AddProp32(dest, "pb", pb);
@@ -428,24 +462,16 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
{
name = "LZMA2";
if (propsSize == 1)
- {
- Byte d = props[0];
- if ((d & 1) == 0)
- ConvertUInt32ToString((UInt32)((d >> 1) + 12), s);
- else
- GetStringForSizeValue(s, 3 << ((d >> 1) + 11));
- }
+ GetLzma2String(s, props[0]);
}
else if (id == k_PPMD)
{
name = "PPMD";
if (propsSize == 5)
{
- Byte order = *props;
char *dest = s;
*dest++ = 'o';
- ConvertUInt32ToString(order, dest);
- dest += MyStringLen(dest);
+ dest = ConvertUInt32ToString(*props, dest);
dest = MyStpCpy(dest, ":mem");
GetStringForSizeValue(dest, GetUi32(props + 1));
}
@@ -456,6 +482,16 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
if (propsSize == 1)
ConvertUInt32ToString((UInt32)props[0] + 1, s);
}
+ else if (id == k_ARM64)
+ {
+ name = "ARM64";
+ if (propsSize == 4)
+ ConvertUInt32ToString(GetUi32(props), s);
+ /*
+ else if (propsSize != 0)
+ MyStringCopy(s, "unsupported");
+ */
+ }
else if (id == k_BCJ2) name = "BCJ2";
else if (id == k_BCJ) name = "BCJ";
else if (id == k_AES)
@@ -463,8 +499,8 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
name = "7zAES";
if (propsSize >= 1)
{
- Byte firstByte = props[0];
- UInt32 numCyclesPower = firstByte & 0x3F;
+ const Byte firstByte = props[0];
+ const UInt32 numCyclesPower = firstByte & 0x3F;
ConvertUInt32ToString(numCyclesPower, s);
}
}
@@ -472,8 +508,8 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
if (name)
{
- unsigned nameLen = MyStringLen(name);
- unsigned propsLen = MyStringLen(s);
+ const unsigned nameLen = MyStringLen(name);
+ const unsigned propsLen = MyStringLen(s);
unsigned totalLen = nameLen + propsLen;
if (propsLen != 0)
totalLen++;
@@ -502,7 +538,7 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
pos -= ConvertMethodIdToString_Back(temp + pos, id64);
else
{
- unsigned len = methodName.Len();
+ const unsigned len = methodName.Len();
if (len + 5 > pos)
break;
pos -= len;
@@ -526,9 +562,9 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
#endif
-STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
{
- PropVariant_Clear(value);
+ RINOK(PropVariant_Clear(value))
// COM_TRY_BEGIN
// NCOM::CPropVariant prop;
@@ -540,7 +576,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
*/
const CFileItem &item = _db.Files[index];
- UInt32 index2 = index;
+ const UInt32 index2 = index;
switch (propID)
{
@@ -555,7 +591,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
// prop = ref2.PackSize;
{
- CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
+ const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2)
@@ -575,7 +611,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidCTime: SetFileTimeProp_From_UInt64Def(value, _db.CTime, index2); break;
case kpidATime: SetFileTimeProp_From_UInt64Def(value, _db.ATime, index2); break;
case kpidMTime: SetFileTimeProp_From_UInt64Def(value, _db.MTime, index2); break;
- case kpidAttrib: if (item.AttribDefined) PropVarEm_Set_UInt32(value, item.Attrib); break;
+ case kpidAttrib: if (_db.Attrib.ValidAndDefined(index2)) PropVarEm_Set_UInt32(value, _db.Attrib.Vals[index2]); break;
case kpidCRC: if (item.CrcDefined) PropVarEm_Set_UInt32(value, item.Crc); break;
case kpidEncrypted: PropVarEm_Set_Bool(value, IsFolderEncrypted(_db.FileIndexToFolderIndexMap[index2])); break;
case kpidIsAnti: PropVarEm_Set_Bool(value, _db.IsItemAnti(index2)); break;
@@ -596,24 +632,24 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPath: return _db.GetPath_Prop(index, value);
- #ifndef _SFX
+ #ifndef Z7_SFX
case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value);
case kpidBlock:
{
- CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
+ const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
PropVarEm_Set_UInt32(value, (UInt32)folderIndex);
}
break;
- /*
+ #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES
case kpidPackedSize0:
case kpidPackedSize1:
case kpidPackedSize2:
case kpidPackedSize3:
case kpidPackedSize4:
{
- CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
+ const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
@@ -627,22 +663,22 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
PropVarEm_Set_UInt64(value, 0);
}
break;
- */
+ #endif
#endif
}
- // prop.Detach(value);
+ // return prop.Detach(value);
return S_OK;
// COM_TRY_END
}
-STDMETHODIMP CHandler::Open(IInStream *stream,
+Z7_COM7F_IMF(CHandler::Open(IInStream *stream,
const UInt64 *maxCheckStartPosition,
- IArchiveOpenCallback *openArchiveCallback)
+ IArchiveOpenCallback *openArchiveCallback))
{
COM_TRY_BEGIN
Close();
- #ifndef _SFX
+ #ifndef Z7_SFX
_fileInfoPopIDs.Clear();
#endif
@@ -650,31 +686,31 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
{
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (openArchiveCallback)
openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
#endif
CInArchive archive(
- #ifdef __7Z_SET_PROPERTIES
+ #ifdef Z7_7Z_SET_PROPERTIES
_useMultiThreadMixer
#else
true
#endif
);
_db.IsArc = false;
- RINOK(archive.Open(stream, maxCheckStartPosition));
+ RINOK(archive.Open(stream, maxCheckStartPosition))
_db.IsArc = true;
HRESULT result = archive.ReadDatabase(
EXTERNAL_CODECS_VARS
_db
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
, getTextPassword, _isEncrypted, _passwordIsDefined, _password
#endif
);
- RINOK(result);
+ RINOK(result)
_inStream = stream;
}
@@ -687,35 +723,35 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
return E_OUTOFMEMORY;
}
// _inStream = stream;
- #ifndef _SFX
+ #ifndef Z7_SFX
FillPopIDs();
#endif
return S_OK;
COM_TRY_END
}
-STDMETHODIMP CHandler::Close()
+Z7_COM7F_IMF(CHandler::Close())
{
COM_TRY_BEGIN
_inStream.Release();
_db.Clear();
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
_isEncrypted = false;
_passwordIsDefined = false;
- _password.Empty();
+ _password.Wipe_and_Empty();
#endif
return S_OK;
COM_TRY_END
}
-#ifdef __7Z_SET_PROPERTIES
-#ifdef EXTRACT_ONLY
+#ifdef Z7_7Z_SET_PROPERTIES
+#ifdef Z7_EXTRACT_ONLY
-STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
+Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
{
COM_TRY_BEGIN
- const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
- _numThreads = numProcessors;
+
+ InitCommon();
_useMultiThreadMixer = true;
for (UInt32 i = 0; i < numProps; i++)
@@ -726,21 +762,23 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
UInt32 number;
- unsigned index = ParseStringToUInt32(name, number);
+ const unsigned index = ParseStringToUInt32(name, number);
if (index == 0)
{
if (name.IsEqualTo("mtf"))
{
- RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer));
+ RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer))
continue;
}
- if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
- RINOK(ParseMtProp(name.Ptr(2), value, numProcessors, _numThreads));
- continue;
+ HRESULT hres;
+ if (SetCommonProperty(name, value, hres))
+ {
+ RINOK(hres)
+ continue;
+ }
}
- else
- return E_INVALIDARG;
+ return E_INVALIDARG;
}
}
return S_OK;
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h
index d46401afe3c..b1c04669832 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h
@@ -1,45 +1,43 @@
// 7z/Handler.h
-#ifndef __7Z_HANDLER_H
-#define __7Z_HANDLER_H
+#ifndef ZIP7_7Z_HANDLER_H
+#define ZIP7_7Z_HANDLER_H
#include "../../ICoder.h"
#include "../IArchive.h"
#include "../../Common/CreateCoder.h"
-#ifndef EXTRACT_ONLY
-#include "../Common/HandlerOut.h"
+#ifndef Z7_7Z_SET_PROPERTIES
+
+#ifdef Z7_EXTRACT_ONLY
+ #if !defined(Z7_ST) && !defined(Z7_SFX)
+ #define Z7_7Z_SET_PROPERTIES
+ #endif
+#else
+ #define Z7_7Z_SET_PROPERTIES
+#endif
+
#endif
+// #ifdef Z7_7Z_SET_PROPERTIES
+#include "../Common/HandlerOut.h"
+// #endif
+
#include "7zCompressionMode.h"
#include "7zIn.h"
namespace NArchive {
namespace N7z {
-#ifndef __7Z_SET_PROPERTIES
-
-#ifdef EXTRACT_ONLY
- #if !defined(_7ZIP_ST) && !defined(_SFX)
- #define __7Z_SET_PROPERTIES
- #endif
-#else
- #define __7Z_SET_PROPERTIES
-#endif
-
-#endif
-
-#ifndef EXTRACT_ONLY
+#ifndef Z7_EXTRACT_ONLY
class COutHandler: public CMultiMethodProps
{
HRESULT SetSolidFromString(const UString &s);
HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value);
public:
- bool _removeSfxBlock;
-
UInt64 _numSolidFiles;
UInt64 _numSolidBytes;
bool _numSolidBytesDefined;
@@ -51,12 +49,14 @@ public:
bool _encryptHeaders;
// bool _useParents; 9.26
- CBoolPair Write_CTime;
- CBoolPair Write_ATime;
- CBoolPair Write_MTime;
+ CHandlerTimeOptions TimeOptions;
+
+ CBoolPair Write_Attrib;
bool _useMultiThreadMixer;
+ bool _removeSfxBlock;
+
// bool _volumeMode;
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
@@ -69,72 +69,73 @@ public:
_numSolidBytesDefined = false;
}
+ void InitProps7z();
void InitProps();
- COutHandler() { InitProps(); }
+ COutHandler() { InitProps7z(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
#endif
-class CHandler:
+class CHandler Z7_final:
public IInArchive,
public IArchiveGetRawProps,
- #ifdef __7Z_SET_PROPERTIES
+
+ #ifdef Z7_7Z_SET_PROPERTIES
public ISetProperties,
#endif
- #ifndef EXTRACT_ONLY
+
+ #ifndef Z7_EXTRACT_ONLY
public IOutArchive,
#endif
- PUBLIC_ISetCompressCodecsInfo
- public CMyUnknownImp
- #ifndef EXTRACT_ONLY
- , public COutHandler
- #endif
-{
-public:
- MY_QUERYINTERFACE_BEGIN2(IInArchive)
- MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
- #ifdef __7Z_SET_PROPERTIES
- MY_QUERYINTERFACE_ENTRY(ISetProperties)
- #endif
- #ifndef EXTRACT_ONLY
- MY_QUERYINTERFACE_ENTRY(IOutArchive)
- #endif
- QUERY_ENTRY_ISetCompressCodecsInfo
- MY_QUERYINTERFACE_END
- MY_ADDREF_RELEASE
-
- INTERFACE_IInArchive(;)
- INTERFACE_IArchiveGetRawProps(;)
-
- #ifdef __7Z_SET_PROPERTIES
- STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
- #endif
+
+ Z7_PUBLIC_ISetCompressCodecsInfo_IFEC
+
+ public CMyUnknownImp,
- #ifndef EXTRACT_ONLY
- INTERFACE_IOutArchive(;)
+ #ifndef Z7_EXTRACT_ONLY
+ public COutHandler
+ #else
+ public CCommonMethodProps
#endif
-
+{
+ Z7_COM_QI_BEGIN2(IInArchive)
+ Z7_COM_QI_ENTRY(IArchiveGetRawProps)
+ #ifdef Z7_7Z_SET_PROPERTIES
+ Z7_COM_QI_ENTRY(ISetProperties)
+ #endif
+ #ifndef Z7_EXTRACT_ONLY
+ Z7_COM_QI_ENTRY(IOutArchive)
+ #endif
+ Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC
+ Z7_COM_QI_END
+ Z7_COM_ADDREF_RELEASE
+
+ Z7_IFACE_COM7_IMP(IInArchive)
+ Z7_IFACE_COM7_IMP(IArchiveGetRawProps)
+ #ifdef Z7_7Z_SET_PROPERTIES
+ Z7_IFACE_COM7_IMP(ISetProperties)
+ #endif
+ #ifndef Z7_EXTRACT_ONLY
+ Z7_IFACE_COM7_IMP(IOutArchive)
+ #endif
DECL_ISetCompressCodecsInfo
- CHandler();
-
private:
CMyComPtr<IInStream> _inStream;
NArchive::N7z::CDbEx _db;
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
bool _isEncrypted;
bool _passwordIsDefined;
- UString _password;
- #endif
+ UString _password; // _Wipe
+ #endif
- #ifdef EXTRACT_ONLY
+ #ifdef Z7_EXTRACT_ONLY
- #ifdef __7Z_SET_PROPERTIES
- UInt32 _numThreads;
+ #ifdef Z7_7Z_SET_PROPERTIES
bool _useMultiThreadMixer;
#endif
@@ -146,17 +147,12 @@ private:
HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
- HRESULT SetMainMethod(CCompressionMethodMode &method
- #ifndef _7ZIP_ST
- , UInt32 numThreads
- #endif
- );
-
+ HRESULT SetMainMethod(CCompressionMethodMode &method);
#endif
bool IsFolderEncrypted(CNum folderIndex) const;
- #ifndef _SFX
+ #ifndef Z7_SFX
CRecordVector<UInt64> _fileInfoPopIDs;
void FillPopIDs();
@@ -166,6 +162,13 @@ private:
#endif
DECL_EXTERNAL_CODECS_VARS
+
+public:
+ CHandler();
+ ~CHandler()
+ {
+ Close();
+ }
};
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
index 2b86ed26ab7..ff8735f0f7e 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
@@ -13,16 +13,19 @@
#include "7zOut.h"
#include "7zUpdate.h"
+#ifndef Z7_EXTRACT_ONLY
+
using namespace NWindows;
namespace NArchive {
namespace N7z {
-static const char *k_LZMA_Name = "LZMA";
-static const char *kDefaultMethodName = "LZMA2";
-static const char *k_Copy_Name = "Copy";
+#define k_LZMA_Name "LZMA"
+#define kDefaultMethodName "LZMA2"
+#define k_Copy_Name "Copy"
+
+#define k_MatchFinder_ForHeaders "BT2"
-static const char *k_MatchFinder_ForHeaders = "BT2";
static const UInt32 k_NumFastBytes_ForHeaders = 273;
static const UInt32 k_Level_ForHeaders = 5;
static const UInt32 k_Dictionary_ForHeaders =
@@ -32,7 +35,7 @@ static const UInt32 k_Dictionary_ForHeaders =
1 << 20;
#endif
-STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
+Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type))
{
*type = NFileTimeType::kWindows;
return S_OK;
@@ -40,9 +43,12 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m)
{
- if (!FindMethod(
+ bool isFilter;
+ dest.CodecIndex = FindMethod_Index(
EXTERNAL_CODECS_VARS
- m.MethodName, dest.Id, dest.NumStreams))
+ m.MethodName, true,
+ dest.Id, dest.NumStreams, isFilter);
+ if (dest.CodecIndex < 0)
return E_INVALIDARG;
(CProps &)dest = (CProps &)m;
return S_OK;
@@ -64,15 +70,12 @@ HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
return PropsMethod_To_FullMethod(methodFull, m);
}
-HRESULT CHandler::SetMainMethod(
- CCompressionMethodMode &methodMode
- #ifndef _7ZIP_ST
- , UInt32 numThreads
- #endif
- )
+
+HRESULT CHandler::SetMainMethod(CCompressionMethodMode &methodMode)
{
methodMode.Bonds = _bonds;
+ // we create local copy of _methods. So we can modify it.
CObjectVector<COneMethodInfo> methods = _methods;
{
@@ -106,60 +109,200 @@ HRESULT CHandler::SetMainMethod(
}
const UInt64 kSolidBytes_Min = (1 << 24);
- const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
+ const UInt64 kSolidBytes_Max = ((UInt64)1 << 32);
bool needSolid = false;
FOR_VECTOR (i, methods)
{
COneMethodInfo &oneMethodInfo = methods[i];
- SetGlobalLevelAndThreads(oneMethodInfo
- #ifndef _7ZIP_ST
- , numThreads
- #endif
- );
+
+ SetGlobalLevelTo(oneMethodInfo);
+
+ #ifndef Z7_ST
+ const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0);
+ if (!numThreads_WasSpecifiedInMethod)
+ {
+ // here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already
+ CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, methodMode.NumThreads);
+ }
+ #endif
CMethodFull &methodFull = methodMode.Methods.AddNew();
- RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
+ RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo))
+
+ #ifndef Z7_ST
+ methodFull.Set_NumThreads = true;
+ methodFull.NumThreads = methodMode.NumThreads;
+ #endif
if (methodFull.Id != k_Copy)
needSolid = true;
- if (_numSolidBytesDefined)
- continue;
-
- UInt32 dicSize;
+ UInt64 dicSize;
switch (methodFull.Id)
{
case k_LZMA:
case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break;
case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break;
case k_Deflate: dicSize = (UInt32)1 << 15; break;
+ case k_Deflate64: dicSize = (UInt32)1 << 16; break;
case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
+ // case k_ZSTD: dicSize = 1 << 23; break;
default: continue;
}
-
- _numSolidBytes = (UInt64)dicSize << 7;
- if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
- if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
+
+ UInt64 numSolidBytes;
+
+ /*
+ if (methodFull.Id == k_ZSTD)
+ {
+ // continue;
+ NCompress::NZstd::CEncoderProps encoderProps;
+ RINOK(oneMethodInfo.Set_PropsTo_zstd(encoderProps));
+ CZstdEncProps &zstdProps = encoderProps.EncProps;
+ ZstdEncProps_NormalizeFull(&zstdProps);
+ UInt64 cs = (UInt64)(zstdProps.jobSize);
+ UInt32 winSize = (UInt32)(1 << zstdProps.windowLog);
+ if (cs < winSize)
+ cs = winSize;
+ numSolidBytes = cs << 6;
+ const UInt64 kSolidBytes_Zstd_Max = ((UInt64)1 << 34);
+ if (numSolidBytes > kSolidBytes_Zstd_Max)
+ numSolidBytes = kSolidBytes_Zstd_Max;
+
+ methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder
+
+ #ifndef Z7_ST
+ if (!numThreads_WasSpecifiedInMethod
+ && !methodMode.NumThreads_WasForced
+ && methodMode.MemoryUsageLimit_WasSet
+ )
+ {
+ const UInt32 numThreads_Original = methodMode.NumThreads;
+ const UInt32 numThreads_New = ZstdEncProps_GetNumThreads_for_MemUsageLimit(
+ &zstdProps,
+ methodMode.MemoryUsageLimit,
+ numThreads_Original);
+ if (numThreads_Original != numThreads_New)
+ {
+ CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New);
+ }
+ }
+ #endif
+ }
+ else
+ */
+ if (methodFull.Id == k_LZMA2)
+ {
+ // he we calculate default chunk Size for LZMA2 as defined in LZMA2 encoder code
+ /* lzma2 code use dictionary up to fake 4 GiB to calculate ChunkSize.
+ So we do same */
+ UInt64 cs = (UInt64)dicSize << 2;
+ const UInt32 kMinSize = (UInt32)1 << 20;
+ const UInt32 kMaxSize = (UInt32)1 << 28;
+ if (cs < kMinSize) cs = kMinSize;
+ if (cs > kMaxSize) cs = kMaxSize;
+ if (cs < dicSize) cs = dicSize;
+ cs += (kMinSize - 1);
+ cs &= ~(UInt64)(kMinSize - 1);
+ // we want to use at least 64 chunks (threads) per one solid block.
+
+ // here we don't use chunkSize property
+ numSolidBytes = cs << 6;
+
+ // here we get real chunkSize
+ cs = oneMethodInfo.Get_Xz_BlockSize();
+ if (dicSize > cs)
+ dicSize = cs;
+
+ const UInt64 kSolidBytes_Lzma2_Max = ((UInt64)1 << 34);
+ if (numSolidBytes > kSolidBytes_Lzma2_Max)
+ numSolidBytes = kSolidBytes_Lzma2_Max;
+
+ methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder
+
+ #ifndef Z7_ST
+ if (!numThreads_WasSpecifiedInMethod
+ && !methodMode.NumThreads_WasForced
+ && methodMode.MemoryUsageLimit_WasSet
+ )
+ {
+ const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads();
+ const UInt32 numBlockThreads_Original = methodMode.NumThreads / lzmaThreads;
+
+ if (numBlockThreads_Original > 1)
+ {
+ /*
+ const UInt32 kNumThreads_Max = 1024;
+ if (numBlockThreads > kNumMaxThreads)
+ numBlockThreads = kNumMaxThreads;
+ */
+
+ UInt32 numBlockThreads = numBlockThreads_Original;
+ const UInt64 lzmaMemUsage = oneMethodInfo.Get_Lzma_MemUsage(false); // solid
+
+ for (; numBlockThreads > 1; numBlockThreads--)
+ {
+ UInt64 size = numBlockThreads * (lzmaMemUsage + cs);
+ UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1;
+ if (cs < ((UInt32)1 << 26)) numPackChunks++;
+ if (cs < ((UInt32)1 << 24)) numPackChunks++;
+ if (cs < ((UInt32)1 << 22)) numPackChunks++;
+ size += numPackChunks * cs;
+ // printf("\nnumBlockThreads = %d, size = %d\n", (unsigned)(numBlockThreads), (unsigned)(size >> 20));
+ if (size <= methodMode.MemoryUsageLimit)
+ break;
+ }
+
+ if (numBlockThreads == 0)
+ numBlockThreads = 1;
+ if (numBlockThreads != numBlockThreads_Original)
+ {
+ const UInt32 numThreads_New = numBlockThreads * lzmaThreads;
+ CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New);
+ }
+ }
+ }
+ #endif
+ }
+ else
+ {
+ numSolidBytes = (UInt64)dicSize << 7;
+ if (numSolidBytes > kSolidBytes_Max)
+ numSolidBytes = kSolidBytes_Max;
+ }
+
+ if (_numSolidBytesDefined)
+ continue;
+
+ if (numSolidBytes < kSolidBytes_Min)
+ numSolidBytes = kSolidBytes_Min;
+ _numSolidBytes = numSolidBytes;
_numSolidBytesDefined = true;
}
if (!_numSolidBytesDefined)
+ {
if (needSolid)
_numSolidBytes = kSolidBytes_Max;
else
_numSolidBytes = 0;
+ }
_numSolidBytesDefined = true;
+
+
return S_OK;
}
-static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, UInt64 &ft, bool &ftDefined)
+
+
+static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, unsigned index, PROPID propID, UInt64 &ft, bool &ftDefined)
{
// ft = 0;
// ftDefined = false;
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(index, propID, &prop));
+ RINOK(updateCallback->GetProperty(index, propID, &prop))
if (prop.vt == VT_FILETIME)
{
ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32);
@@ -242,13 +385,13 @@ static int AddFolder(CObjectVector<CTreeFolder> &treeFolders, int cur, const USt
}
*/
-STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
- IArchiveUpdateCallback *updateCallback)
+Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback))
{
COM_TRY_BEGIN
- const CDbEx *db = 0;
- #ifdef _7Z_VOL
+ const CDbEx *db = NULL;
+ #ifdef Z7_7Z_VOL
if (_volumes.Size() > 1)
return E_FAIL;
const CVolume *volume = 0;
@@ -258,13 +401,17 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
db = &volume->Database;
}
#else
- if (_inStream != 0)
+ if (_inStream)
db = &_db;
#endif
+ if (db && !db->CanUpdate())
+ return E_NOTIMPL;
+
/*
- CMyComPtr<IArchiveGetRawProps> getRawProps;
- updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps);
+ Z7_DECL_CMyComPtr_QI_FROM(
+ IArchiveGetRawProps,
+ getRawProps, updateCallback)
CUniqBlocks secureBlocks;
secureBlocks.AddUniq(NULL, 0);
@@ -279,18 +426,21 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CObjectVector<CUpdateItem> updateItems;
- bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
- bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
- bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
+ bool need_CTime = (TimeOptions.Write_CTime.Def && TimeOptions.Write_CTime.Val);
+ bool need_ATime = (TimeOptions.Write_ATime.Def && TimeOptions.Write_ATime.Val);
+ bool need_MTime = (TimeOptions.Write_MTime.Def ? TimeOptions.Write_MTime.Val : true);
+ bool need_Attrib = (Write_Attrib.Def ? Write_Attrib.Val : true);
if (db && !db->Files.IsEmpty())
{
- if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
- if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
- if (!Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty();
+ if (!TimeOptions.Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
+ if (!TimeOptions.Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
+ if (!TimeOptions.Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty();
+ if (!Write_Attrib.Def) need_Attrib = !db->Attrib.Defs.IsEmpty();
}
- UString s;
+ // UString s;
+ UString name;
for (UInt32 i = 0; i < numItems; i++)
{
@@ -298,45 +448,46 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
UInt32 indexInArchive;
if (!updateCallback)
return E_FAIL;
- RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive));
+ RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive))
CUpdateItem ui;
ui.NewProps = IntToBool(newProps);
ui.NewData = IntToBool(newData);
- ui.IndexInArchive = indexInArchive;
+ ui.IndexInArchive = (int)indexInArchive;
ui.IndexInClient = i;
ui.IsAnti = false;
ui.Size = 0;
- UString name;
+ name.Empty();
// bool isAltStream = false;
if (ui.IndexInArchive != -1)
{
- if (db == 0 || (unsigned)ui.IndexInArchive >= db->Files.Size())
+ if (!db || (unsigned)ui.IndexInArchive >= db->Files.Size())
return E_INVALIDARG;
- const CFileItem &fi = db->Files[ui.IndexInArchive];
+ const CFileItem &fi = db->Files[(unsigned)ui.IndexInArchive];
if (!ui.NewProps)
{
- _db.GetPath(ui.IndexInArchive, name);
+ _db.GetPath((unsigned)ui.IndexInArchive, name);
}
ui.IsDir = fi.IsDir;
ui.Size = fi.Size;
// isAltStream = fi.IsAltStream;
- ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
+ ui.IsAnti = db->IsItemAnti((unsigned)ui.IndexInArchive);
if (!ui.NewProps)
{
- ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
- ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
- ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
+ ui.CTimeDefined = db->CTime.GetItem((unsigned)ui.IndexInArchive, ui.CTime);
+ ui.ATimeDefined = db->ATime.GetItem((unsigned)ui.IndexInArchive, ui.ATime);
+ ui.MTimeDefined = db->MTime.GetItem((unsigned)ui.IndexInArchive, ui.MTime);
}
}
if (ui.NewProps)
{
bool folderStatusIsDefined;
+ if (need_Attrib)
{
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
+ RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop))
if (prop.vt == VT_EMPTY)
ui.AttribDefined = false;
else if (prop.vt != VT_UI4)
@@ -349,9 +500,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
// we need MTime to sort files.
- if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined));
- if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined));
- if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined));
+ if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined))
+ if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined))
+ if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined))
/*
if (getRawProps)
@@ -369,7 +520,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
+ RINOK(updateCallback->GetProperty(i, kpidPath, &prop))
if (prop.vt == VT_EMPTY)
{
}
@@ -377,12 +528,13 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
else
{
- name = NItemName::MakeLegalName(prop.bstrVal);
+ name = prop.bstrVal;
+ NItemName::ReplaceSlashes_OsToUnix(name);
}
}
{
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop));
+ RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop))
if (prop.vt == VT_EMPTY)
folderStatusIsDefined = false;
else if (prop.vt != VT_BOOL)
@@ -396,7 +548,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop));
+ RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop))
if (prop.vt == VT_EMPTY)
ui.IsAnti = false;
else if (prop.vt != VT_BOOL)
@@ -513,7 +665,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (!ui.IsDir)
{
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
+ RINOK(updateCallback->GetProperty(i, kpidSize, &prop))
if (prop.vt != VT_UI8)
return E_INVALIDARG;
ui.Size = (UInt64)prop.uhVal.QuadPart;
@@ -537,32 +689,39 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CCompressionMethodMode methodMode, headerMethod;
- HRESULT res = SetMainMethod(methodMode
- #ifndef _7ZIP_ST
- , _numThreads
- #endif
- );
- RINOK(res);
+ methodMode.MemoryUsageLimit = _memUsage_Compress;
+ methodMode.MemoryUsageLimit_WasSet = _memUsage_WasSet;
- RINOK(SetHeaderMethod(headerMethod));
-
- #ifndef _7ZIP_ST
- methodMode.NumThreads = _numThreads;
- methodMode.MultiThreadMixer = _useMultiThreadMixer;
- headerMethod.NumThreads = 1;
- headerMethod.MultiThreadMixer = _useMultiThreadMixer;
+ #ifndef Z7_ST
+ {
+ UInt32 numThreads = _numThreads;
+ const UInt32 kNumThreads_Max = 1024;
+ if (numThreads > kNumThreads_Max)
+ numThreads = kNumThreads_Max;
+ methodMode.NumThreads = numThreads;
+ methodMode.NumThreads_WasForced = _numThreads_WasForced;
+ methodMode.MultiThreadMixer = _useMultiThreadMixer;
+ // headerMethod.NumThreads = 1;
+ headerMethod.MultiThreadMixer = _useMultiThreadMixer;
+ }
#endif
- CMyComPtr<ICryptoGetTextPassword2> getPassword2;
- updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2);
+ const HRESULT res = SetMainMethod(methodMode);
+ RINOK(res)
+
+ RINOK(SetHeaderMethod(headerMethod))
+
+ Z7_DECL_CMyComPtr_QI_FROM(
+ ICryptoGetTextPassword2,
+ getPassword2, updateCallback)
methodMode.PasswordIsDefined = false;
- methodMode.Password.Empty();
+ methodMode.Password.Wipe_and_Empty();
if (getPassword2)
{
- CMyComBSTR password;
+ CMyComBSTR_Wipe password;
Int32 passwordIsDefined;
- RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password));
+ RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password))
methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
if (methodMode.PasswordIsDefined && password)
methodMode.Password = password;
@@ -572,7 +731,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
bool encryptHeaders = false;
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
if (!methodMode.PasswordIsDefined && _passwordIsDefined)
{
// if header is compressed, we use that password for updated archive
@@ -585,7 +744,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
if (_encryptHeadersSpecified)
encryptHeaders = _encryptHeaders;
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
else
encryptHeaders = _passwordIsDefined;
#endif
@@ -600,9 +759,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (numItems < 2)
compressMainHeader = false;
- int level = GetLevel();
+ const int level = GetLevel();
CUpdateOptions options;
+ options.Need_CTime = need_CTime;
+ options.Need_ATime = need_ATime;
+ options.Need_MTime = need_MTime;
+ options.Need_Attrib = need_Attrib;
+ // options.Need_Crc = (_crcSize != 0); // for debug
+
options.Method = &methodMode;
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : NULL;
options.UseFilters = (level != 0 && _autoFilter && !methodMode.Filter_was_Inserted);
@@ -614,6 +779,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options.HeaderOptions.WriteCTime = Write_CTime;
options.HeaderOptions.WriteATime = Write_ATime;
options.HeaderOptions.WriteMTime = Write_MTime;
+ options.HeaderOptions.WriteAttrib = Write_Attrib;
*/
options.NumSolidFiles = _numSolidFiles;
@@ -626,12 +792,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options.MultiThreadMixer = _useMultiThreadMixer;
- COutArchive archive;
- CArchiveDatabaseOut newDatabase;
-
- CMyComPtr<ICryptoGetTextPassword> getPassword;
- updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword);
-
/*
if (secureBlocks.Sorted.Size() > 1)
{
@@ -644,9 +804,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
*/
- res = Update(
+ return Update(
EXTERNAL_CODECS_VARS
- #ifdef _7Z_VOL
+ #ifdef Z7_7Z_VOL
volume ? volume->Stream: 0,
volume ? db : 0,
#else
@@ -656,18 +816,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
updateItems,
// treeFolders,
// secureBlocks,
- archive, newDatabase, outStream, updateCallback, options
- #ifndef _NO_CRYPTO
- , getPassword
- #endif
- );
-
- RINOK(res);
-
- updateItems.ClearAndFree();
-
- return archive.WriteDatabase(EXTERNAL_CODECS_VARS
- newDatabase, options.HeaderMethod, options.HeaderOptions);
+ outStream, updateCallback, options);
COM_TRY_END
}
@@ -676,7 +825,7 @@ static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
{
stream = 0;
{
- unsigned index = ParseStringToUInt32(srcString, coder);
+ const unsigned index = ParseStringToUInt32(srcString, coder);
if (index == 0)
return E_INVALIDARG;
srcString.DeleteFrontal(index);
@@ -684,7 +833,7 @@ static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
if (srcString[0] == 's')
{
srcString.Delete(0);
- unsigned index = ParseStringToUInt32(srcString, stream);
+ const unsigned index = ParseStringToUInt32(srcString, stream);
if (index == 0)
return E_INVALIDARG;
srcString.DeleteFrontal(index);
@@ -692,19 +841,16 @@ static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
return S_OK;
}
-void COutHandler::InitProps()
+void COutHandler::InitProps7z()
{
- CMultiMethodProps::Init();
-
_removeSfxBlock = false;
_compressHeaders = true;
_encryptHeadersSpecified = false;
_encryptHeaders = false;
// _useParents = false;
- Write_CTime.Init();
- Write_ATime.Init();
- Write_MTime.Init();
+ TimeOptions.Init();
+ Write_Attrib.Init();
_useMultiThreadMixer = true;
@@ -714,6 +860,14 @@ void COutHandler::InitProps()
_useTypeSorting = false;
}
+void COutHandler::InitProps()
+{
+ CMultiMethodProps::Init();
+ InitProps7z();
+}
+
+
+
HRESULT COutHandler::SetSolidFromString(const UString &s)
{
UString s2 = s;
@@ -730,10 +884,10 @@ HRESULT COutHandler::SetSolidFromString(const UString &s)
_solidExtension = true;
continue;
}
- i += (int)(end - start);
+ i += (unsigned)(end - start);
if (i == s2.Len())
return E_INVALIDARG;
- wchar_t c = s2[i++];
+ const wchar_t c = s2[i++];
if (c == 'f')
{
if (v < 1)
@@ -754,6 +908,10 @@ HRESULT COutHandler::SetSolidFromString(const UString &s)
}
_numSolidBytes = (v << numBits);
_numSolidBytesDefined = true;
+ /*
+ if (_numSolidBytes == 0)
+ _numSolidFiles = 1;
+ */
}
}
return S_OK;
@@ -781,7 +939,7 @@ HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value)
static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest)
{
- RINOK(PROPVARIANT_to_bool(prop, dest.Val));
+ RINOK(PROPVARIANT_to_bool(prop, dest.Val))
dest.Def = true;
return S_OK;
}
@@ -802,9 +960,9 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
return E_INVALIDARG;
return SetSolidFromString(name);
}
-
+
UInt32 number;
- int index = ParseStringToUInt32(name, number);
+ const unsigned index = ParseStringToUInt32(name, number);
// UString realName = name.Ptr(index);
if (index == 0)
{
@@ -815,20 +973,32 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
if (name.IsEqualTo("hcf"))
{
bool compressHeadersFull = true;
- RINOK(PROPVARIANT_to_bool(value, compressHeadersFull));
+ RINOK(PROPVARIANT_to_bool(value, compressHeadersFull))
return compressHeadersFull ? S_OK: E_INVALIDARG;
}
if (name.IsEqualTo("he"))
{
- RINOK(PROPVARIANT_to_bool(value, _encryptHeaders));
+ RINOK(PROPVARIANT_to_bool(value, _encryptHeaders))
_encryptHeadersSpecified = true;
return S_OK;
}
- if (name.IsEqualTo("tc")) return PROPVARIANT_to_BoolPair(value, Write_CTime);
- if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
- if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
+ {
+ bool processed;
+ RINOK(TimeOptions.Parse(name, value, processed))
+ if (processed)
+ {
+ if ( TimeOptions.Prec != (UInt32)(Int32)-1
+ && TimeOptions.Prec != k_PropVar_TimePrec_0
+ && TimeOptions.Prec != k_PropVar_TimePrec_HighPrec
+ && TimeOptions.Prec != k_PropVar_TimePrec_100ns)
+ return E_INVALIDARG;
+ return S_OK;
+ }
+ }
+
+ if (name.IsEqualTo("tr")) return PROPVARIANT_to_BoolPair(value, Write_Attrib);
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
@@ -839,7 +1009,7 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
return CMultiMethodProps::SetProperty(name, value);
}
-STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
+Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
{
COM_TRY_BEGIN
_bonds.Clear();
@@ -854,6 +1024,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
const PROPVARIANT &value = values[i];
+ if (name.Find(L':') >= 0) // 'b' was used as NCoderPropID::kBlockSize2 before v23
if (name[0] == 'b')
{
if (value.vt != VT_EMPTY)
@@ -861,12 +1032,12 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
name.Delete(0);
CBond2 bond;
- RINOK(ParseBond(name, bond.OutCoder, bond.OutStream));
+ RINOK(ParseBond(name, bond.OutCoder, bond.OutStream))
if (name[0] != ':')
return E_INVALIDARG;
name.Delete(0);
UInt32 inStream = 0;
- RINOK(ParseBond(name, bond.InCoder, inStream));
+ RINOK(ParseBond(name, bond.InCoder, inStream))
if (inStream != 0)
return E_INVALIDARG;
if (!name.IsEmpty())
@@ -875,7 +1046,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
continue;
}
- RINOK(SetProperty(name, value));
+ RINOK(SetProperty(name, value))
}
unsigned numEmptyMethods = GetNumEmptyMethods();
@@ -911,3 +1082,5 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
}
}}
+
+#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp
index acff2fdd8d9..d5f94973b14 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp
@@ -8,7 +8,7 @@ namespace NArchive {
namespace N7z {
Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
-#ifdef _7Z_VOL
+#ifdef Z7_7Z_VOL
Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h
index d7f0ae365b9..bd96ca3c61a 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h
@@ -1,7 +1,7 @@
// 7z/7zHeader.h
-#ifndef __7Z_HEADER_H
-#define __7Z_HEADER_H
+#ifndef ZIP7_INC_7Z_HEADER_H
+#define ZIP7_INC_7Z_HEADER_H
#include "../../../Common/MyTypes.h"
@@ -11,13 +11,13 @@ namespace N7z {
const unsigned kSignatureSize = 6;
extern Byte kSignature[kSignatureSize];
-// #define _7Z_VOL
+// #define Z7_7Z_VOL
// 7z-MultiVolume is not finished yet.
// It can work already, but I still do not like some
// things of that new multivolume format.
// So please keep it commented.
-#ifdef _7Z_VOL
+#ifdef Z7_7Z_VOL
extern Byte kFinishSignature[kSignatureSize];
#endif
@@ -38,7 +38,7 @@ struct CStartHeader
const UInt32 kStartHeaderSize = 20;
-#ifdef _7Z_VOL
+#ifdef Z7_7Z_VOL
struct CFinishHeader: public CStartHeader
{
UInt64 ArchiveStartOffset; // data offset from end if that struct
@@ -99,6 +99,7 @@ namespace NID
const UInt32 k_Copy = 0;
const UInt32 k_Delta = 3;
+const UInt32 k_ARM64 = 0xa;
const UInt32 k_LZMA2 = 0x21;
@@ -108,8 +109,9 @@ const UInt32 k_SWAP4 = 0x20304;
const UInt32 k_LZMA = 0x30101;
const UInt32 k_PPMD = 0x30401;
-const UInt32 k_Deflate = 0x40108;
-const UInt32 k_BZip2 = 0x40202;
+const UInt32 k_Deflate = 0x40108;
+const UInt32 k_Deflate64 = 0x40109;
+const UInt32 k_BZip2 = 0x40202;
const UInt32 k_BCJ = 0x3030103;
const UInt32 k_BCJ2 = 0x303011B;
@@ -121,14 +123,17 @@ const UInt32 k_SPARC = 0x3030805;
const UInt32 k_AES = 0x6F10701;
+// const UInt32 k_ZSTD = 0x4015D; // winzip zstd
+// 0x4F71101, 7z-zstd
static inline bool IsFilterMethod(UInt64 m)
{
- if (m > (UInt64)0xFFFFFFFF)
+ if (m > (UInt32)0xFFFFFFFF)
return false;
switch ((UInt32)m)
{
case k_Delta:
+ case k_ARM64:
case k_BCJ:
case k_BCJ2:
case k_PPC:
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp
index d8c2717501c..4defd272b39 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp
@@ -11,6 +11,9 @@
#include "../../../../C/7zCrc.h"
#include "../../../../C/CpuArch.h"
+#include "../../../Common/MyBuffer2.h"
+// #include "../../../Common/UTFConvert.h"
+
#include "../../Common/StreamObjects.h"
#include "../../Common/StreamUtils.h"
@@ -22,7 +25,7 @@
#define Get64(p) GetUi64(p)
// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader
-#ifndef _SFX
+#ifndef Z7_SFX
#define FORMAT_7Z_RECOVERY
#endif
@@ -32,6 +35,25 @@ using namespace NCOM;
namespace NArchive {
namespace N7z {
+#define k_Scan_NumCoders_MAX 64
+#define k_Scan_NumCodersStreams_in_Folder_MAX 64
+
+unsigned BoolVector_CountSum(const CBoolVector &v);
+unsigned BoolVector_CountSum(const CBoolVector &v)
+{
+ unsigned sum = 0;
+ const unsigned size = v.Size();
+ for (unsigned i = 0; i < size; i++)
+ if (v[i])
+ sum++;
+ return sum;
+}
+
+static inline bool BoolVector_Item_IsValidAndTrue(const CBoolVector &v, unsigned i)
+{
+ return (i < v.Size() ? v[i] : false);
+}
+
static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
{
v.ClearAndSetSize(size);
@@ -40,12 +62,17 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
p[i] = false;
}
+
class CInArchiveException {};
class CUnsupportedFeatureException: public CInArchiveException {};
+Z7_ATTR_NORETURN
static void ThrowException() { throw CInArchiveException(); }
+Z7_ATTR_NORETURN
static inline void ThrowEndOfData() { ThrowException(); }
+Z7_ATTR_NORETURN
static inline void ThrowUnsupported() { throw CUnsupportedFeatureException(); }
+Z7_ATTR_NORETURN
static inline void ThrowIncorrect() { ThrowException(); }
class CStreamSwitch
@@ -90,12 +117,12 @@ void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer)
void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector)
{
Remove();
- Byte external = archive->ReadByte();
+ const Byte external = archive->ReadByte();
if (external != 0)
{
if (!dataVector)
ThrowIncorrect();
- CNum dataIndex = archive->ReadNum();
+ const CNum dataIndex = archive->ReadNum();
if (dataIndex >= dataVector->Size())
ThrowIncorrect();
Set(archive, (*dataVector)[dataIndex]);
@@ -148,7 +175,7 @@ static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed)
return 0;
}
- unsigned b = *p++;
+ const unsigned b = *p++;
size--;
if ((b & 0x80) == 0)
@@ -169,10 +196,10 @@ static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed)
for (unsigned i = 1; i < 8; i++)
{
- unsigned mask = (unsigned)0x80 >> i;
+ const unsigned mask = (unsigned)0x80 >> i;
if ((b & mask) == 0)
{
- UInt64 high = b & (mask - 1);
+ const UInt64 high = b & (mask - 1);
value |= (high << (i * 8));
processed = i + 1;
return value;
@@ -196,7 +223,7 @@ static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed)
UInt64 CInByte2::ReadNumber()
{
size_t processed;
- UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed);
+ const UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed);
if (processed == 0)
ThrowEndOfData();
_pos += processed;
@@ -216,7 +243,7 @@ CNum CInByte2::ReadNum()
}
}
*/
- UInt64 value = ReadNumber();
+ const UInt64 value = ReadNumber();
if (value > kNumMax)
ThrowUnsupported();
return (CNum)value;
@@ -226,7 +253,7 @@ UInt32 CInByte2::ReadUInt32()
{
if (_pos + 4 > _size)
ThrowEndOfData();
- UInt32 res = Get32(_buffer + _pos);
+ const UInt32 res = Get32(_buffer + _pos);
_pos += 4;
return res;
}
@@ -235,54 +262,101 @@ UInt64 CInByte2::ReadUInt64()
{
if (_pos + 8 > _size)
ThrowEndOfData();
- UInt64 res = Get64(_buffer + _pos);
+ const UInt64 res = Get64(_buffer + _pos);
_pos += 8;
return res;
}
-#define CHECK_SIGNATURE if (p[0] != '7' || p[1] != 'z' || p[2] != 0xBC || p[3] != 0xAF || p[4] != 0x27 || p[5] != 0x1C) return false;
+#define Y0 '7'
+#define Y1 'z'
+#define Y2 0xBC
+#define Y3 0xAF
+#define Y4 0x27
+#define Y5 0x1C
+
+#define IS_SIGNATURE(p)( \
+ (p)[2] == Y2 && \
+ (p)[3] == Y3 && \
+ (p)[5] == Y5 && \
+ (p)[4] == Y4 && \
+ (p)[1] == Y1 && \
+ (p)[0] == Y0)
+
+/* FindSignature_10() is allowed to access data up to and including &limit[9].
+ limit[10] access is not allowed.
+ return:
+ (return_ptr < limit) : signature was found at (return_ptr)
+ (return_ptr >= limit) : limit was reached or crossed. So no signature found before limit
+*/
+Z7_NO_INLINE
+static const Byte *FindSignature_10(const Byte *p, const Byte *limit)
+{
+ for (;;)
+ {
+ for (;;)
+ {
+ if (p >= limit)
+ return limit;
+ const Byte b = p[5];
+ p += 6;
+ if (b == Y0) { break; }
+ if (b == Y1) { p -= 1; break; }
+ if (b == Y2) { p -= 2; break; }
+ if (b == Y3) { p -= 3; break; }
+ if (b == Y4) { p -= 4; break; }
+ if (b == Y5) { p -= 5; break; }
+ }
+ if (IS_SIGNATURE(p - 1))
+ return p - 1;
+ }
+}
-static inline bool TestSignature(const Byte *p)
+
+static inline bool TestStartCrc(const Byte *p)
{
- CHECK_SIGNATURE
return CrcCalc(p + 12, 20) == Get32(p + 8);
}
-#ifdef FORMAT_7Z_RECOVERY
static inline bool TestSignature2(const Byte *p)
{
- CHECK_SIGNATURE;
- if (CrcCalc(p + 12, 20) == Get32(p + 8))
+ if (!IS_SIGNATURE(p))
+ return false;
+ #ifdef FORMAT_7Z_RECOVERY
+ if (TestStartCrc(p))
return true;
for (unsigned i = 8; i < kHeaderSize; i++)
if (p[i] != 0)
return false;
return (p[6] != 0 || p[7] != 0);
+ #else
+ return TestStartCrc(p);
+ #endif
}
-#else
-#define TestSignature2(p) TestSignature(p)
-#endif
+
HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{
- RINOK(ReadStream_FALSE(stream, _header, kHeaderSize));
+ RINOK(ReadStream_FALSE(stream, _header, kHeaderSize))
if (TestSignature2(_header))
return S_OK;
if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0)
return S_FALSE;
- const UInt32 kBufSize = 1 << 15;
- CByteArr buf(kBufSize);
+ const UInt32 kBufSize = (1 << 15) + kHeaderSize; // must be > (kHeaderSize * 2)
+ CAlignedBuffer1 buf(kBufSize);
memcpy(buf, _header, kHeaderSize);
UInt64 offset = 0;
for (;;)
{
- UInt32 readSize = kBufSize - kHeaderSize;
+ UInt32 readSize =
+ (offset == 0) ?
+ kBufSize - kHeaderSize - kHeaderSize :
+ kBufSize - kHeaderSize;
if (searchHeaderSizeLimit)
{
- UInt64 rem = *searchHeaderSizeLimit - offset;
+ const UInt64 rem = *searchHeaderSizeLimit - offset;
if (readSize > rem)
readSize = (UInt32)rem;
if (readSize == 0)
@@ -290,29 +364,28 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
}
UInt32 processed = 0;
- RINOK(stream->Read(buf + kHeaderSize, readSize, &processed));
+ RINOK(stream->Read(buf + kHeaderSize, readSize, &processed))
if (processed == 0)
return S_FALSE;
+
+ /* &buf[0] was already tested for signature before.
+ So first search here will be for &buf[1] */
for (UInt32 pos = 0;;)
{
const Byte *p = buf + pos + 1;
- const Byte *lim = buf + processed;
- for (; p <= lim; p += 4)
- {
- if (p[0] == '7') break;
- if (p[1] == '7') { p += 1; break; }
- if (p[2] == '7') { p += 2; break; }
- if (p[3] == '7') { p += 3; break; }
- };
- if (p > lim)
+ const Byte *lim = buf + processed + 1;
+ /* we have (kHeaderSize - 1 = 31) filled bytes starting from (lim),
+ and it's safe to access just 10 bytes in that reserved area */
+ p = FindSignature_10(p, lim);
+ if (p >= lim)
break;
pos = (UInt32)(p - buf);
- if (TestSignature(p))
+ if (TestStartCrc(p))
{
memcpy(_header, p, kHeaderSize);
_arhiveBeginStreamPosition += offset + pos;
- return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL);
+ return InStream_SeekSet(stream, _arhiveBeginStreamPosition + kHeaderSize);
}
}
@@ -326,10 +399,8 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{
HeadersSize = 0;
Close();
- RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
- RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition))
- RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL))
- RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
+ RINOK(InStream_GetPos_GetSize(stream, _arhiveBeginStreamPosition, _fileEndPosition))
+ RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit))
_stream = stream;
return S_OK;
}
@@ -355,9 +426,9 @@ void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)
void CInByte2::ParseFolder(CFolder &folder)
{
- UInt32 numCoders = ReadNum();
+ const UInt32 numCoders = ReadNum();
- if (numCoders == 0)
+ if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX)
ThrowUnsupported();
folder.Coders.SetSize(numCoders);
@@ -368,10 +439,10 @@ void CInByte2::ParseFolder(CFolder &folder)
{
CCoderInfo &coder = folder.Coders[i];
{
- Byte mainByte = ReadByte();
+ const Byte mainByte = ReadByte();
if ((mainByte & 0xC0) != 0)
ThrowUnsupported();
- unsigned idSize = (mainByte & 0xF);
+ const unsigned idSize = (mainByte & 0xF);
if (idSize > 8 || idSize > GetRem())
ThrowUnsupported();
const Byte *longID = GetPtr();
@@ -384,7 +455,9 @@ void CInByte2::ParseFolder(CFolder &folder)
if ((mainByte & 0x10) != 0)
{
coder.NumStreams = ReadNum();
+ // if (coder.NumStreams > k_Scan_NumCodersStreams_in_Folder_MAX) ThrowUnsupported();
/* numOutStreams = */ ReadNum();
+ // if (ReadNum() != 1) // numOutStreams ThrowUnsupported();
}
else
{
@@ -393,7 +466,7 @@ void CInByte2::ParseFolder(CFolder &folder)
if ((mainByte & 0x20) != 0)
{
- CNum propsSize = ReadNum();
+ const CNum propsSize = ReadNum();
coder.Props.Alloc((size_t)propsSize);
ReadBytes((Byte *)coder.Props, (size_t)propsSize);
}
@@ -403,7 +476,7 @@ void CInByte2::ParseFolder(CFolder &folder)
numInStreams += coder.NumStreams;
}
- UInt32 numBonds = numCoders - 1;
+ const UInt32 numBonds = numCoders - 1;
folder.Bonds.SetSize(numBonds);
for (i = 0; i < numBonds; i++)
{
@@ -414,7 +487,7 @@ void CInByte2::ParseFolder(CFolder &folder)
if (numInStreams < numBonds)
ThrowUnsupported();
- UInt32 numPackStreams = numInStreams - numBonds;
+ const UInt32 numPackStreams = numInStreams - numBonds;
folder.PackStreams.SetSize(numPackStreams);
if (numPackStreams == 1)
@@ -435,7 +508,7 @@ void CInByte2::ParseFolder(CFolder &folder)
void CFolders::ParseFolderInfo(unsigned folderIndex, CFolder &folder) const
{
- size_t startPos = FoCodersDataOffset[folderIndex];
+ const size_t startPos = FoCodersDataOffset[folderIndex];
CInByte2 inByte;
inByte.Init(CodersData + startPos, FoCodersDataOffset[folderIndex + 1] - startPos);
inByte.ParseFolder(folder);
@@ -450,8 +523,8 @@ void CDatabase::GetPath(unsigned index, UString &path) const
if (!NameOffsets || !NamesBuf)
return;
- size_t offset = NameOffsets[index];
- size_t size = NameOffsets[index + 1] - offset;
+ const size_t offset = NameOffsets[index];
+ const size_t size = NameOffsets[index + 1] - offset;
if (size >= (1 << 28))
return;
@@ -462,7 +535,7 @@ void CDatabase::GetPath(unsigned index, UString &path) const
#if defined(_WIN32) && defined(MY_CPU_LE)
- wmemcpy(s, (const wchar_t *)p, size);
+ wmemcpy(s, (const wchar_t *)(const void *)p, size);
#else
@@ -484,16 +557,33 @@ HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
if (!NameOffsets || !NamesBuf)
return S_OK;
- size_t offset = NameOffsets[index];
- size_t size = NameOffsets[index + 1] - offset;
+ const size_t offset = NameOffsets[index];
+ const size_t size = NameOffsets[index + 1] - offset;
if (size >= (1 << 14))
return S_OK;
- RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1));
+ // (size) includes null terminator
+
+ /*
+ #if WCHAR_MAX > 0xffff
+
+ const Byte *p = ((const Byte *)NamesBuf + offset * 2);
+ size = Utf16LE__Get_Num_WCHARs(p, size - 1);
+ // (size) doesn't include null terminator
+ RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size));
wchar_t *s = path->bstrVal;
+ wchar_t *sEnd = Utf16LE__To_WCHARs_Sep(p, size, s);
+ *sEnd = 0;
+ if (s + size != sEnd) return E_FAIL;
+
+ #else
+ */
+ RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1))
+ wchar_t *s = path->bstrVal;
const Byte *p = ((const Byte *)NamesBuf + offset * 2);
+ // Utf16LE__To_WCHARs_Sep(p, size, s);
for (size_t i = 0; i < size; i++)
{
@@ -502,10 +592,14 @@ HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
#if WCHAR_PATH_SEPARATOR != L'/'
if (c == L'/')
c = WCHAR_PATH_SEPARATOR;
+ else if (c == L'\\')
+ c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme
#endif
*s++ = c;
}
+ // #endif
+
return S_OK;
/*
@@ -557,7 +651,7 @@ void CInArchive::WaitId(UInt64 id)
{
for (;;)
{
- UInt64 type = ReadID();
+ const UInt64 type = ReadID();
if (type == id)
return;
if (type == NID::kEnd)
@@ -566,27 +660,33 @@ void CInArchive::WaitId(UInt64 id)
}
}
-void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
+
+void CInArchive::Read_UInt32_Vector(CUInt32DefVector &v)
{
- ReadBoolVector2(numItems, crcs.Defs);
- crcs.Vals.ClearAndSetSize(numItems);
- UInt32 *p = &crcs.Vals[0];
- const bool *defs = &crcs.Defs[0];
+ const unsigned numItems = v.Defs.Size();
+ v.Vals.ClearAndSetSize(numItems);
+ UInt32 *p = &v.Vals[0];
+ const bool *defs = &v.Defs[0];
for (unsigned i = 0; i < numItems; i++)
{
- UInt32 crc = 0;
+ UInt32 a = 0;
if (defs[i])
- crc = ReadUInt32();
- p[i] = crc;
+ a = ReadUInt32();
+ p[i] = a;
}
}
-#define k_Scan_NumCoders_MAX 64
-#define k_Scan_NumCodersStreams_in_Folder_MAX 64
+
+void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
+{
+ ReadBoolVector2(numItems, crcs.Defs);
+ Read_UInt32_Vector(crcs);
+}
+
void CInArchive::ReadPackInfo(CFolders &f)
{
- CNum numPackStreams = ReadNum();
+ const CNum numPackStreams = ReadNum();
WaitId(NID::kSize);
f.PackPositions.Alloc(numPackStreams + 1);
@@ -595,7 +695,7 @@ void CInArchive::ReadPackInfo(CFolders &f)
for (CNum i = 0; i < numPackStreams; i++)
{
f.PackPositions[i] = sum;
- UInt64 packSize = ReadNumber();
+ const UInt64 packSize = ReadNumber();
sum += packSize;
if (sum < packSize)
ThrowIncorrect();
@@ -623,7 +723,7 @@ void CInArchive::ReadUnpackInfo(
CFolders &folders)
{
WaitId(NID::kFolder);
- CNum numFolders = ReadNum();
+ const CNum numFolders = ReadNum();
CNum numCodersOutStreams = 0;
{
@@ -648,21 +748,21 @@ void CInArchive::ReadUnpackInfo(
{
UInt32 indexOfMainStream = 0;
UInt32 numPackStreams = 0;
- folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
+ folders.FoCodersDataOffset[fo] = (size_t)(_inByteBack->GetPtr() - startBufPtr);
CNum numInStreams = 0;
- CNum numCoders = inByte->ReadNum();
+ const CNum numCoders = inByte->ReadNum();
if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX)
ThrowUnsupported();
for (CNum ci = 0; ci < numCoders; ci++)
{
- Byte mainByte = inByte->ReadByte();
+ const Byte mainByte = inByte->ReadByte();
if ((mainByte & 0xC0) != 0)
ThrowUnsupported();
- unsigned idSize = (mainByte & 0xF);
+ const unsigned idSize = (mainByte & 0xF);
if (idSize > 8)
ThrowUnsupported();
if (idSize > inByte->GetRem())
@@ -691,18 +791,18 @@ void CInArchive::ReadUnpackInfo(
if ((mainByte & 0x20) != 0)
{
- CNum propsSize = inByte->ReadNum();
+ const CNum propsSize = inByte->ReadNum();
if (propsSize > inByte->GetRem())
ThrowEndOfData();
if (id == k_LZMA2 && propsSize == 1)
{
- Byte v = *_inByteBack->GetPtr();
+ const Byte v = *_inByteBack->GetPtr();
if (folders.ParsedMethods.Lzma2Prop < v)
folders.ParsedMethods.Lzma2Prop = v;
}
else if (id == k_LZMA && propsSize == 5)
{
- UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1);
+ const UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1);
if (folders.ParsedMethods.LzmaDic < dicSize)
folders.ParsedMethods.LzmaDic = dicSize;
}
@@ -718,7 +818,7 @@ void CInArchive::ReadUnpackInfo(
else
{
UInt32 i;
- CNum numBonds = numCoders - 1;
+ const CNum numBonds = numCoders - 1;
if (numInStreams < numBonds)
ThrowUnsupported();
@@ -743,7 +843,7 @@ void CInArchive::ReadUnpackInfo(
if (numPackStreams != 1)
for (i = 0; i < numPackStreams; i++)
{
- CNum index = inByte->ReadNum(); // PackStreams
+ const CNum index = inByte->ReadNum(); // PackStreams
if (index >= numInStreams || StreamUsed[index])
ThrowUnsupported();
StreamUsed[index] = true;
@@ -769,10 +869,10 @@ void CInArchive::ReadUnpackInfo(
folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
}
- size_t dataSize = _inByteBack->GetPtr() - startBufPtr;
+ const size_t dataSize = (size_t)(_inByteBack->GetPtr() - startBufPtr);
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
- folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
+ folders.FoCodersDataOffset[fo] = (size_t)(_inByteBack->GetPtr() - startBufPtr);
folders.CodersData.CopyFrom(startBufPtr, dataSize);
// if (folders.NumPackStreams != packStreamIndex) ThrowUnsupported();
@@ -785,7 +885,7 @@ void CInArchive::ReadUnpackInfo(
for (;;)
{
- UInt64 type = ReadID();
+ const UInt64 type = ReadID();
if (type == NID::kEnd)
return;
if (type == NID::kCRC)
@@ -829,19 +929,19 @@ void CInArchive::ReadSubStreamsInfo(
{
// v3.13 incorrectly worked with empty folders
// v4.07: we check that folder is empty
- CNum numSubstreams = folders.NumUnpackStreamsVector[i];
+ const CNum numSubstreams = folders.NumUnpackStreamsVector[i];
if (numSubstreams == 0)
continue;
UInt64 sum = 0;
for (CNum j = 1; j < numSubstreams; j++)
{
- UInt64 size = ReadNumber();
+ const UInt64 size = ReadNumber();
unpackSizes.Add(size);
sum += size;
if (sum < size)
ThrowIncorrect();
}
- UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i);
+ const UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i);
if (folderUnpackSize < sum)
ThrowIncorrect();
unpackSizes.Add(folderUnpackSize - sum);
@@ -854,7 +954,7 @@ void CInArchive::ReadSubStreamsInfo(
{
/* v9.26 - v9.29 incorrectly worked:
if (folders.NumUnpackStreamsVector[i] == 0), it threw error */
- CNum val = folders.NumUnpackStreamsVector[i];
+ const CNum val = folders.NumUnpackStreamsVector[i];
if (val > 1)
ThrowIncorrect();
if (val == 1)
@@ -865,7 +965,7 @@ void CInArchive::ReadSubStreamsInfo(
unsigned numDigests = 0;
for (i = 0; i < folders.NumFolders; i++)
{
- CNum numSubstreams = folders.NumUnpackStreamsVector[i];
+ const CNum numSubstreams = folders.NumUnpackStreamsVector[i];
if (numSubstreams != 1 || !folders.FolderCRCs.ValidAndDefined(i))
numDigests += numSubstreams;
}
@@ -888,7 +988,7 @@ void CInArchive::ReadSubStreamsInfo(
for (i = 0; i < folders.NumFolders; i++)
{
- CNum numSubstreams = folders.NumUnpackStreamsVector[i];
+ const CNum numSubstreams = folders.NumUnpackStreamsVector[i];
if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i))
{
digests.Defs[k] = true;
@@ -920,7 +1020,7 @@ void CInArchive::ReadSubStreamsInfo(
unsigned k = 0;
for (i = 0; i < folders.NumFolders; i++)
{
- CNum numSubstreams = folders.NumUnpackStreamsVector[i];
+ const CNum numSubstreams = folders.NumUnpackStreamsVector[i];
if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i))
{
digests.Defs[k] = true;
@@ -937,6 +1037,8 @@ void CInArchive::ReadSubStreamsInfo(
}
}
+
+
void CInArchive::ReadStreamsInfo(
const CObjectVector<CByteBuffer> *dataVector,
UInt64 &dataOffset,
@@ -949,7 +1051,11 @@ void CInArchive::ReadStreamsInfo(
if (type == NID::kPackInfo)
{
dataOffset = ReadNumber();
+ if (dataOffset > _rangeLimit)
+ ThrowIncorrect();
ReadPackInfo(folders);
+ if (folders.PackPositions[folders.NumPackStreams] > _rangeLimit - dataOffset)
+ ThrowIncorrect();
type = ReadID();
}
@@ -1004,13 +1110,13 @@ void CInArchive::ReadBoolVector(unsigned numItems, CBoolVector &v)
mask = 0x80;
}
p[i] = ((b & mask) != 0);
- mask >>= 1;
+ mask = (Byte)(mask >> 1);
}
}
void CInArchive::ReadBoolVector2(unsigned numItems, CBoolVector &v)
{
- Byte allAreDefined = ReadByte();
+ const Byte allAreDefined = ReadByte();
if (allAreDefined == 0)
{
ReadBoolVector(numItems, v);
@@ -1047,7 +1153,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 baseOffset,
UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
- _7Z_DECODER_CRYPRO_VARS_DECL
+ Z7_7Z_DECODER_CRYPRO_VARS_DECL
)
{
CFolders folders;
@@ -1065,8 +1171,8 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
for (CNum i = 0; i < folders.NumFolders; i++)
{
CByteBuffer &data = dataVector.AddNew();
- UInt64 unpackSize64 = folders.GetFolderUnpackSize(i);
- size_t unpackSize = (size_t)unpackSize64;
+ const UInt64 unpackSize64 = folders.GetFolderUnpackSize(i);
+ const size_t unpackSize = (size_t)unpackSize64;
if (unpackSize != unpackSize64)
ThrowUnsupported();
data.Alloc(unpackSize);
@@ -1075,24 +1181,36 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->Init(data, unpackSize);
+ bool dataAfterEnd_Error = false;
+
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_LOC_VARS
_stream, baseOffset + dataOffset,
folders, i,
- NULL, // *unpackSize
+ NULL, // &unpackSize64
outStream,
NULL, // *compressProgress
+
NULL // **inStreamMainRes
+ , dataAfterEnd_Error
- _7Z_DECODER_CRYPRO_VARS
- #if !defined(_7ZIP_ST) && !defined(_SFX)
+ Z7_7Z_DECODER_CRYPRO_VARS
+ #if !defined(Z7_ST)
, false // mtMode
, 1 // numThreads
+ , 0 // memUsage
#endif
);
- RINOK(result);
+ RINOK(result)
+
+ if (dataAfterEnd_Error)
+ ThereIsHeaderError = true;
+
+ if (unpackSize != outStreamSpec->GetPos())
+ ThrowIncorrect();
+
if (folders.FolderCRCs.ValidAndDefined(i))
if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
ThrowIncorrect();
@@ -1107,7 +1225,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
HRESULT CInArchive::ReadHeader(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
- _7Z_DECODER_CRYPRO_VARS_DECL
+ Z7_7Z_DECODER_CRYPRO_VARS_DECL
)
{
UInt64 type = ReadID();
@@ -1122,14 +1240,14 @@ HRESULT CInArchive::ReadHeader(
if (type == NID::kAdditionalStreamsInfo)
{
- HRESULT result = ReadAndDecodePackedStreams(
+ const HRESULT result = ReadAndDecodePackedStreams(
EXTERNAL_CODECS_LOC_VARS
db.ArcInfo.StartPositionAfterHeader,
db.ArcInfo.DataStartPosition2,
dataVector
- _7Z_DECODER_CRYPRO_VARS
+ Z7_7Z_DECODER_CRYPRO_VARS
);
- RINOK(result);
+ RINOK(result)
db.ArcInfo.DataStartPosition2 += db.ArcInfo.StartPositionAfterHeader;
type = ReadID();
}
@@ -1148,19 +1266,10 @@ HRESULT CInArchive::ReadHeader(
type = ReadID();
}
- db.Files.Clear();
-
if (type == NID::kFilesInfo)
{
const CNum numFiles = ReadNum();
- db.Files.ClearAndSetSize(numFiles);
- /*
- db.Files.Reserve(numFiles);
- CNum i;
- for (i = 0; i < numFiles; i++)
- db.Files.Add(CFileItem());
- */
db.ArcInfo.FileInfoPopIDs.Add(NID::kSize);
// if (!db.PackSizes.IsEmpty())
@@ -1169,7 +1278,6 @@ HRESULT CInArchive::ReadHeader(
db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC);
CBoolVector emptyStreamVector;
- BoolVector_Fill_False(emptyStreamVector, (unsigned)numFiles);
CBoolVector emptyFileVector;
CBoolVector antiFileVector;
CNum numEmptyStreams = 0;
@@ -1179,7 +1287,7 @@ HRESULT CInArchive::ReadHeader(
const UInt64 type2 = ReadID();
if (type2 == NID::kEnd)
break;
- UInt64 size = ReadNumber();
+ const UInt64 size = ReadNumber();
if (size > _inByteBack->GetRem())
ThrowIncorrect();
CStreamSwitch switchProp;
@@ -1194,16 +1302,16 @@ HRESULT CInArchive::ReadHeader(
{
CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector);
- size_t rem = _inByteBack->GetRem();
+ const size_t rem = _inByteBack->GetRem();
db.NamesBuf.Alloc(rem);
ReadBytes(db.NamesBuf, rem);
- db.NameOffsets.Alloc(db.Files.Size() + 1);
+ db.NameOffsets.Alloc(numFiles + 1);
size_t pos = 0;
unsigned i;
- for (i = 0; i < db.Files.Size(); i++)
+ for (i = 0; i < numFiles; i++)
{
- size_t curRem = (rem - pos) / 2;
- const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos);
+ const size_t curRem = (rem - pos) / 2;
+ const UInt16 *buf = (const UInt16 *)(const void *)(db.NamesBuf + pos);
size_t j;
for (j = 0; j < curRem && buf[j] != 0; j++);
if (j == curRem)
@@ -1216,36 +1324,31 @@ HRESULT CInArchive::ReadHeader(
ThereIsHeaderError = true;
break;
}
+
case NID::kWinAttrib:
{
- CBoolVector boolVector;
- ReadBoolVector2(db.Files.Size(), boolVector);
+ ReadBoolVector2(numFiles, db.Attrib.Defs);
CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector);
- for (CNum i = 0; i < numFiles; i++)
- {
- CFileItem &file = db.Files[i];
- file.AttribDefined = boolVector[i];
- if (file.AttribDefined)
- file.Attrib = ReadUInt32();
- }
+ Read_UInt32_Vector(db.Attrib);
break;
}
+
/*
case NID::kIsAux:
{
- ReadBoolVector(db.Files.Size(), db.IsAux);
+ ReadBoolVector(numFiles, db.IsAux);
break;
}
case NID::kParent:
{
db.IsTree = true;
// CBoolVector boolVector;
- // ReadBoolVector2(db.Files.Size(), boolVector);
+ // ReadBoolVector2(numFiles, boolVector);
// CStreamSwitch streamSwitch;
// streamSwitch.Set(this, &dataVector);
CBoolVector boolVector;
- ReadBoolVector2(db.Files.Size(), boolVector);
+ ReadBoolVector2(numFiles, boolVector);
db.ThereAreAltStreams = false;
for (i = 0; i < numFiles; i++)
@@ -1264,14 +1367,9 @@ HRESULT CInArchive::ReadHeader(
case NID::kEmptyStream:
{
ReadBoolVector(numFiles, emptyStreamVector);
- numEmptyStreams = 0;
- for (CNum i = 0; i < (CNum)emptyStreamVector.Size(); i++)
- if (emptyStreamVector[i])
- numEmptyStreams++;
-
- BoolVector_Fill_False(emptyFileVector, numEmptyStreams);
- BoolVector_Fill_False(antiFileVector, numEmptyStreams);
-
+ numEmptyStreams = BoolVector_CountSum(emptyStreamVector);
+ emptyFileVector.Clear();
+ antiFileVector.Clear();
break;
}
case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break;
@@ -1314,7 +1412,7 @@ HRESULT CInArchive::ReadHeader(
ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset);
}
db.SecureIDs.Clear();
- for (unsigned i = 0; i < db.Files.Size(); i++)
+ for (unsigned i = 0; i < numFiles; i++)
{
db.SecureIDs.Add(ReadNum());
// db.SecureIDs.Add(ReadUInt32());
@@ -1359,22 +1457,21 @@ HRESULT CInArchive::ReadHeader(
CNum emptyFileIndex = 0;
CNum sizeIndex = 0;
- CNum numAntiItems = 0;
+ const CNum numAntiItems = BoolVector_CountSum(antiFileVector);
- CNum i;
+ if (numAntiItems != 0)
+ db.IsAnti.ClearAndSetSize(numFiles);
- for (i = 0; i < numEmptyStreams; i++)
- if (antiFileVector[i])
- numAntiItems++;
+ db.Files.ClearAndSetSize(numFiles);
- for (i = 0; i < numFiles; i++)
+ for (CNum i = 0; i < numFiles; i++)
{
CFileItem &file = db.Files[i];
bool isAnti;
- file.HasStream = !emptyStreamVector[i];
file.Crc = 0;
- if (file.HasStream)
+ if (!BoolVector_Item_IsValidAndTrue(emptyStreamVector, i))
{
+ file.HasStream = true;
file.IsDir = false;
isAnti = false;
file.Size = unpackSizes[sizeIndex];
@@ -1385,26 +1482,31 @@ HRESULT CInArchive::ReadHeader(
}
else
{
- file.IsDir = !emptyFileVector[emptyFileIndex];
- isAnti = antiFileVector[emptyFileIndex];
+ file.HasStream = false;
+ file.IsDir = !BoolVector_Item_IsValidAndTrue(emptyFileVector, emptyFileIndex);
+ isAnti = BoolVector_Item_IsValidAndTrue(antiFileVector, emptyFileIndex);
emptyFileIndex++;
file.Size = 0;
file.CrcDefined = false;
}
if (numAntiItems != 0)
- db.IsAnti.Add(isAnti);
+ db.IsAnti[i] = isAnti;
}
+
}
+
db.FillLinks();
- /*
- if (type != NID::kEnd)
- ThrowIncorrect();
- if (_inByteBack->GetRem() != 0)
- ThrowIncorrect();
- */
+
+ if (type != NID::kEnd || _inByteBack->GetRem() != 0)
+ {
+ db.UnsupportedFeatureWarning = true;
+ // ThrowIncorrect();
+ }
+
return S_OK;
}
+
void CDbEx::FillLinks()
{
FolderStartFileIndex.Alloc(NumFolders);
@@ -1416,7 +1518,7 @@ void CDbEx::FillLinks()
for (i = 0; i < Files.Size(); i++)
{
- bool emptyStream = !Files[i].HasStream;
+ const bool emptyStream = !Files[i].HasStream;
if (indexInFolder == 0)
{
if (emptyStream)
@@ -1447,29 +1549,33 @@ void CDbEx::FillLinks()
}
if (indexInFolder != 0)
+ {
folderIndex++;
- /*
- if (indexInFolder != 0)
- ThrowIncorrect();
- */
+ // 18.06
+ ThereIsHeaderError = true;
+ // ThrowIncorrect();
+ }
for (;;)
{
if (folderIndex >= NumFolders)
return;
FolderStartFileIndex[folderIndex] = i;
- /*
if (NumUnpackStreamsVector[folderIndex] != 0)
- ThrowIncorrect();;
- */
+ {
+ // 18.06
+ ThereIsHeaderError = true;
+ // ThrowIncorrect();
+ }
folderIndex++;
}
}
+
HRESULT CInArchive::ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
- _7Z_DECODER_CRYPRO_VARS_DECL
+ Z7_7Z_DECODER_CRYPRO_VARS_DECL
)
{
db.Clear();
@@ -1489,22 +1595,22 @@ HRESULT CInArchive::ReadDatabase2(
UInt32 nextHeaderCRC = Get32(_header + 28);
#ifdef FORMAT_7Z_RECOVERY
- UInt32 crcFromArc = Get32(_header + 8);
+ const UInt32 crcFromArc = Get32(_header + 8);
if (crcFromArc == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0)
{
UInt64 cur, fileSize;
- RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur));
+ RINOK(InStream_GetPos(_stream, cur))
const unsigned kCheckSize = 512;
Byte buf[kCheckSize];
- RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize));
- UInt64 rem = fileSize - cur;
+ RINOK(InStream_GetSize_SeekToEnd(_stream, fileSize))
+ const UInt64 rem = fileSize - cur;
unsigned checkSize = kCheckSize;
if (rem < kCheckSize)
checkSize = (unsigned)(rem);
if (checkSize < 3)
return S_FALSE;
- RINOK(_stream->Seek(fileSize - checkSize, STREAM_SEEK_SET, NULL));
- RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize));
+ RINOK(InStream_SeekSet(_stream, fileSize - checkSize))
+ RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize))
if (buf[checkSize - 1] != 0)
return S_FALSE;
@@ -1512,8 +1618,8 @@ HRESULT CInArchive::ReadDatabase2(
unsigned i;
for (i = checkSize - 2;; i--)
{
- if (buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo ||
- buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo)
+ if ((buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo) ||
+ (buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo))
break;
if (i == 0)
return S_FALSE;
@@ -1521,7 +1627,7 @@ HRESULT CInArchive::ReadDatabase2(
nextHeaderSize = checkSize - i;
nextHeaderOffset = rem - nextHeaderSize;
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
- RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
+ RINOK(InStream_SeekSet(_stream, cur))
db.StartHeaderWasRecovered = true;
}
else
@@ -1538,32 +1644,39 @@ HRESULT CInArchive::ReadDatabase2(
if ((Int64)nextHeaderOffset < 0 ||
nextHeaderSize > ((UInt64)1 << 62))
return S_FALSE;
+
+ HeadersSize = kHeaderSize;
+
if (nextHeaderSize == 0)
{
if (nextHeaderOffset != 0)
return S_FALSE;
db.IsArc = true;
+ db.HeadersSize = HeadersSize;
return S_OK;
}
if (!db.StartHeaderWasRecovered)
db.IsArc = true;
- HeadersSize += kHeaderSize + nextHeaderSize;
+ HeadersSize += nextHeaderSize;
+ // db.EndHeaderOffset = nextHeaderOffset;
+ _rangeLimit = nextHeaderOffset;
+
db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;
if (_fileEndPosition - db.ArcInfo.StartPositionAfterHeader < nextHeaderOffset + nextHeaderSize)
{
db.UnexpectedEnd = true;
return S_FALSE;
}
- RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
+ RINOK(_stream->Seek((Int64)nextHeaderOffset, STREAM_SEEK_CUR, NULL))
- size_t nextHeaderSize_t = (size_t)nextHeaderSize;
+ const size_t nextHeaderSize_t = (size_t)nextHeaderSize;
if (nextHeaderSize_t != nextHeaderSize)
return E_OUTOFMEMORY;
CByteBuffer buffer2(nextHeaderSize_t);
- RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t));
+ RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t))
if (CrcCalc(buffer2, nextHeaderSize_t) != nextHeaderCRC)
ThrowIncorrect();
@@ -1576,19 +1689,19 @@ HRESULT CInArchive::ReadDatabase2(
CObjectVector<CByteBuffer> dataVector;
- UInt64 type = ReadID();
+ const UInt64 type = ReadID();
if (type != NID::kHeader)
{
if (type != NID::kEncodedHeader)
ThrowIncorrect();
- HRESULT result = ReadAndDecodePackedStreams(
+ const HRESULT result = ReadAndDecodePackedStreams(
EXTERNAL_CODECS_LOC_VARS
db.ArcInfo.StartPositionAfterHeader,
db.ArcInfo.DataStartPosition2,
dataVector
- _7Z_DECODER_CRYPRO_VARS
+ Z7_7Z_DECODER_CRYPRO_VARS
);
- RINOK(result);
+ RINOK(result)
if (dataVector.Size() == 0)
return S_OK;
if (dataVector.Size() > 1)
@@ -1606,21 +1719,22 @@ HRESULT CInArchive::ReadDatabase2(
return ReadHeader(
EXTERNAL_CODECS_LOC_VARS
db
- _7Z_DECODER_CRYPRO_VARS
+ Z7_7Z_DECODER_CRYPRO_VARS
);
}
+
HRESULT CInArchive::ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
- _7Z_DECODER_CRYPRO_VARS_DECL
+ Z7_7Z_DECODER_CRYPRO_VARS_DECL
)
{
try
{
- HRESULT res = ReadDatabase2(
+ const HRESULT res = ReadDatabase2(
EXTERNAL_CODECS_LOC_VARS db
- _7Z_DECODER_CRYPRO_VARS
+ Z7_7Z_DECODER_CRYPRO_VARS
);
if (ThereIsHeaderError)
db.ThereIsHeaderError = true;
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h
index 3592e99b530..a9c14fb3b88 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h
@@ -1,7 +1,7 @@
// 7zIn.h
-#ifndef __7Z_IN_H
-#define __7Z_IN_H
+#ifndef ZIP7_INC_7Z_IN_H
+#define ZIP7_INC_7Z_IN_H
#include "../../../Common/MyCom.h"
@@ -22,12 +22,12 @@ namespace N7z {
We don't need to init isEncrypted and passwordIsDefined
We must upgrade them only */
-#ifdef _NO_CRYPTO
-#define _7Z_DECODER_CRYPRO_VARS_DECL
-#define _7Z_DECODER_CRYPRO_VARS
+#ifdef Z7_NO_CRYPTO
+#define Z7_7Z_DECODER_CRYPRO_VARS_DECL
+#define Z7_7Z_DECODER_CRYPRO_VARS
#else
-#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password
-#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password
+#define Z7_7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password
+#define Z7_7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password
#endif
struct CParsedMethods
@@ -115,6 +115,7 @@ struct CDatabase: public CFolders
CUInt64DefVector ATime;
CUInt64DefVector MTime;
CUInt64DefVector StartPos;
+ CUInt32DefVector Attrib;
CBoolVector IsAnti;
/*
CBoolVector IsAux;
@@ -146,6 +147,7 @@ struct CDatabase: public CFolders
ATime.Clear();
MTime.Clear();
StartPos.Clear();
+ Attrib.Clear();
IsAnti.Clear();
// IsAux.Clear();
}
@@ -172,13 +174,14 @@ struct CDatabase: public CFolders
HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw();
};
+
struct CInArchiveInfo
{
CArchiveVersion Version;
- UInt64 StartPosition;
- UInt64 StartPositionAfterHeader;
- UInt64 DataStartPosition;
- UInt64 DataStartPosition2;
+ UInt64 StartPosition; // in stream
+ UInt64 StartPositionAfterHeader; // in stream
+ UInt64 DataStartPosition; // in stream
+ UInt64 DataStartPosition2; // in stream. it's for headers
CRecordVector<UInt64> FileInfoPopIDs;
void Clear()
@@ -191,6 +194,7 @@ struct CInArchiveInfo
}
};
+
struct CDbEx: public CDatabase
{
CInArchiveInfo ArcInfo;
@@ -200,6 +204,7 @@ struct CDbEx: public CDatabase
UInt64 HeadersSize;
UInt64 PhySize;
+ // UInt64 EndHeaderOffset; // relative to position after StartHeader (32 bytes)
/*
CRecordVector<size_t> SecureOffsets;
@@ -253,6 +258,17 @@ struct CDbEx: public CDatabase
HeadersSize = 0;
PhySize = 0;
+ // EndHeaderOffset = 0;
+ }
+
+ bool CanUpdate() const
+ {
+ if (ThereIsHeaderError
+ || UnexpectedEnd
+ || StartHeaderWasRecovered
+ || UnsupportedFeatureError)
+ return false;
+ return true;
}
void FillLinks();
@@ -337,6 +353,8 @@ class CInArchive
UInt64 _arhiveBeginStreamPosition;
UInt64 _fileEndPosition;
+ UInt64 _rangeLimit; // relative to position after StartHeader (32 bytes)
+
Byte _header[kHeaderSize];
UInt64 HeadersSize;
@@ -369,6 +387,8 @@ class CInArchive
void SkipData() { _inByteBack->SkipData(); }
void WaitId(UInt64 id);
+ void Read_UInt32_Vector(CUInt32DefVector &v);
+
void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs);
@@ -398,17 +418,17 @@ class CInArchive
DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 baseOffset, UInt64 &dataOffset,
CObjectVector<CByteBuffer> &dataVector
- _7Z_DECODER_CRYPRO_VARS_DECL
+ Z7_7Z_DECODER_CRYPRO_VARS_DECL
);
HRESULT ReadHeader(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
- _7Z_DECODER_CRYPRO_VARS_DECL
+ Z7_7Z_DECODER_CRYPRO_VARS_DECL
);
HRESULT ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
- _7Z_DECODER_CRYPRO_VARS_DECL
+ Z7_7Z_DECODER_CRYPRO_VARS_DECL
);
public:
CInArchive(bool useMixerMT):
@@ -422,7 +442,7 @@ public:
HRESULT ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
- _7Z_DECODER_CRYPRO_VARS_DECL
+ Z7_7Z_DECODER_CRYPRO_VARS_DECL
);
};
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h
index 5e2b58f2ef4..e8c68bee1e5 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h
@@ -1,7 +1,7 @@
// 7zItem.h
-#ifndef __7Z_ITEM_H
-#define __7Z_ITEM_H
+#ifndef ZIP7_INC_7Z_ITEM_H
+#define ZIP7_INC_7Z_ITEM_H
#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyString.h"
@@ -26,15 +26,17 @@ struct CCoderInfo
bool IsSimpleCoder() const { return NumStreams == 1; }
};
+
struct CBond
{
UInt32 PackIndex;
UInt32 UnpackIndex;
};
+
struct CFolder
{
- CLASS_NO_COPY(CFolder)
+ Z7_CLASS_NO_COPY(CFolder)
public:
CObjArray2<CCoderInfo> Coders;
CObjArray2<CBond> Bonds;
@@ -48,7 +50,7 @@ public:
{
FOR_VECTOR(i, PackStreams)
if (PackStreams[i] == packStream)
- return i;
+ return (int)i;
return -1;
}
@@ -56,7 +58,7 @@ public:
{
FOR_VECTOR(i, Bonds)
if (Bonds[i].PackIndex == packStream)
- return i;
+ return (int)i;
return -1;
}
@@ -87,6 +89,7 @@ public:
}
};
+
struct CUInt32DefVector
{
CBoolVector Defs;
@@ -110,9 +113,30 @@ struct CUInt32DefVector
Vals.ReserveDown();
}
+ bool GetItem(unsigned index, UInt32 &value) const
+ {
+ if (index < Defs.Size() && Defs[index])
+ {
+ value = Vals[index];
+ return true;
+ }
+ value = 0;
+ return false;
+ }
+
bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; }
+
+ bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
+
+ void SetItem(unsigned index, bool defined, UInt32 value);
+ void if_NonEmpty_FillResedue_with_false(unsigned numItems)
+ {
+ if (Defs.Size() != 0 && Defs.Size() < numItems)
+ SetItem(numItems - 1, false, 0);
+ }
};
+
struct CUInt64DefVector
{
CBoolVector Defs;
@@ -141,15 +165,15 @@ struct CUInt64DefVector
return false;
}
- void SetItem(unsigned index, bool defined, UInt64 value);
-
bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
+
+ void SetItem(unsigned index, bool defined, UInt64 value);
};
+
struct CFileItem
{
UInt64 Size;
- UInt32 Attrib;
UInt32 Crc;
/*
int Parent;
@@ -159,23 +183,23 @@ struct CFileItem
// stream in some folder. It can be empty stream
bool IsDir;
bool CrcDefined;
- bool AttribDefined;
+
+ /*
+ void Clear()
+ {
+ HasStream = true;
+ IsDir = false;
+ CrcDefined = false;
+ }
CFileItem():
- /*
- Parent(-1),
- IsAltStream(false),
- */
+ // Parent(-1),
+ // IsAltStream(false),
HasStream(true),
IsDir(false),
CrcDefined(false),
- AttribDefined(false)
{}
- void SetAttrib(UInt32 attrib)
- {
- AttribDefined = true;
- Attrib = attrib;
- }
+ */
};
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp
index 3e70f466e7b..7f8fa5b5229 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp
@@ -5,6 +5,7 @@
#include "../../../../C/7zCrc.h"
#include "../../../Common/AutoPtr.h"
+// #include "../../../Common/UTFConvert.h"
#include "../../Common/StreamObjects.h"
@@ -13,16 +14,14 @@
namespace NArchive {
namespace N7z {
-HRESULT COutArchive::WriteSignature()
+static void FillSignature(Byte *buf)
{
- Byte buf[8];
memcpy(buf, kSignature, kSignatureSize);
buf[kSignatureSize] = kMajorVersion;
buf[kSignatureSize + 1] = 4;
- return WriteDirect(buf, 8);
}
-#ifdef _7Z_VOL
+#ifdef Z7_7Z_VOL
HRESULT COutArchive::WriteFinishSignature()
{
RINOK(WriteDirect(kFinishSignature, kSignatureSize));
@@ -48,15 +47,16 @@ static void SetUInt64(Byte *p, UInt64 d)
HRESULT COutArchive::WriteStartHeader(const CStartHeader &h)
{
- Byte buf[24];
- SetUInt64(buf + 4, h.NextHeaderOffset);
- SetUInt64(buf + 12, h.NextHeaderSize);
- SetUInt32(buf + 20, h.NextHeaderCRC);
- SetUInt32(buf, CrcCalc(buf + 4, 20));
- return WriteDirect(buf, 24);
+ Byte buf[32];
+ FillSignature(buf);
+ SetUInt64(buf + 8 + 4, h.NextHeaderOffset);
+ SetUInt64(buf + 8 + 12, h.NextHeaderSize);
+ SetUInt32(buf + 8 + 20, h.NextHeaderCRC);
+ SetUInt32(buf + 8, CrcCalc(buf + 8 + 4, 20));
+ return WriteDirect(buf, sizeof(buf));
}
-#ifdef _7Z_VOL
+#ifdef Z7_7Z_VOL
HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h)
{
CCRC crc;
@@ -74,15 +74,15 @@ HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h)
}
#endif
-HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
+HRESULT COutArchive::Create_and_WriteStartPrefix(ISequentialOutStream *stream /* , bool endMarker */)
{
Close();
- #ifdef _7Z_VOL
+ #ifdef Z7_7Z_VOL
// endMarker = false;
_endMarker = endMarker;
#endif
SeqStream = stream;
- if (!endMarker)
+ // if (!endMarker)
{
SeqStream.QueryInterface(IID_IOutStream, &Stream);
if (!Stream)
@@ -90,8 +90,13 @@ HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
return E_NOTIMPL;
// endMarker = true;
}
+ RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_signatureHeaderPos))
+ Byte buf[32];
+ FillSignature(buf);
+ memset(&buf[8], 0, 32 - 8);
+ return WriteDirect(buf, sizeof(buf));
}
- #ifdef _7Z_VOL
+ #ifdef Z7_7Z_VOL
if (endMarker)
{
/*
@@ -100,17 +105,10 @@ HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
sh.NextHeaderSize = (UInt32)(Int32)-1;
sh.NextHeaderCRC = 0;
WriteStartHeader(sh);
+ return S_OK;
*/
}
- else
#endif
- {
- if (!Stream)
- return E_FAIL;
- RINOK(WriteSignature());
- RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos));
- }
- return S_OK;
}
void COutArchive::Close()
@@ -119,17 +117,6 @@ void COutArchive::Close()
Stream.Release();
}
-HRESULT COutArchive::SkipPrefixArchiveHeader()
-{
- #ifdef _7Z_VOL
- if (_endMarker)
- return S_OK;
- #endif
- Byte buf[24];
- memset(buf, 0, 24);
- return WriteDirect(buf, 24);
-}
-
UInt64 COutArchive::GetPos() const
{
if (_countMode)
@@ -196,7 +183,7 @@ void COutArchive::WriteNumber(UInt64 value)
break;
}
firstByte |= mask;
- mask >>= 1;
+ mask = (Byte)(mask >> 1);
}
WriteByte(firstByte);
for (; i > 0; i--)
@@ -206,16 +193,16 @@ void COutArchive::WriteNumber(UInt64 value)
}
}
-static UInt32 GetBigNumberSize(UInt64 value)
+static unsigned GetBigNumberSize(UInt64 value)
{
- int i;
+ unsigned i;
for (i = 1; i < 9; i++)
if (value < (((UInt64)1 << (i * 7))))
break;
return i;
}
-#ifdef _7Z_VOL
+#ifdef Z7_7Z_VOL
UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props)
{
UInt32 result = GetBigNumberSize(dataSize) * 2 + 41;
@@ -264,18 +251,18 @@ void COutArchive::WriteFolder(const CFolder &folder)
for (idSize = 1; idSize < sizeof(id); idSize++)
if ((id >> (8 * idSize)) == 0)
break;
- idSize &= 0xF;
+ // idSize &= 0xF; // idSize is smaller than 16 already
Byte temp[16];
for (unsigned t = idSize; t != 0; t--, id >>= 8)
temp[t] = (Byte)(id & 0xFF);
- Byte b = (Byte)(idSize);
- bool isComplex = !coder.IsSimpleCoder();
+ unsigned b = idSize;
+ const bool isComplex = !coder.IsSimpleCoder();
b |= (isComplex ? 0x10 : 0);
- size_t propsSize = coder.Props.Size();
+ const size_t propsSize = coder.Props.Size();
b |= ((propsSize != 0) ? 0x20 : 0);
- temp[0] = b;
+ temp[0] = (Byte)b;
WriteBytes(temp, idSize + 1);
if (isComplex)
{
@@ -309,7 +296,7 @@ void COutArchive::WriteBoolVector(const CBoolVector &boolVector)
{
if (boolVector[i])
b |= mask;
- mask >>= 1;
+ mask = (Byte)(mask >> 1);
if (mask == 0)
{
WriteByte(b);
@@ -330,13 +317,11 @@ void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector)
WriteBoolVector(boolVector);
}
+unsigned BoolVector_CountSum(const CBoolVector &v);
+
void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
{
- unsigned numDefined = 0;
- unsigned i;
- for (i = 0; i < digests.Defs.Size(); i++)
- if (digests.Defs[i])
- numDefined++;
+ const unsigned numDefined = BoolVector_CountSum(digests.Defs);
if (numDefined == 0)
return;
@@ -348,7 +333,8 @@ void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
WriteByte(0);
WriteBoolVector(digests.Defs);
}
- for (i = 0; i < digests.Defs.Size(); i++)
+
+ for (unsigned i = 0; i < digests.Defs.Size(); i++)
if (digests.Defs[i])
WriteUInt32(digests.Vals[i]);
}
@@ -453,10 +439,12 @@ void COutArchive::WriteSubStreamsInfo(const CObjectVector<CFolder> &folders,
// 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field.
-void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
+void COutArchive::SkipToAligned(unsigned pos, unsigned alignShifts)
{
if (!_useAlign)
return;
+
+ const unsigned alignSize = (unsigned)1 << alignShifts;
pos += (unsigned)GetPos();
pos &= (alignSize - 1);
if (pos == 0)
@@ -471,11 +459,11 @@ void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
WriteByte(0);
}
-void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize)
+void COutArchive::WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts)
{
const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);
- const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2;
- SkipAlign(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSize);
+ const UInt64 dataSize = ((UInt64)numDefined << itemSizeShifts) + bvSize + 2;
+ SkipToAligned(3 + bvSize + GetBigNumberSize(dataSize), itemSizeShifts);
WriteByte(type);
WriteNumber(dataSize);
@@ -486,24 +474,18 @@ void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefin
WriteByte(0);
WriteBoolVector(v);
}
- WriteByte(0);
+ WriteByte(0); // 0 means no switching to external stream
}
void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type)
{
- unsigned numDefined = 0;
-
- unsigned i;
- for (i = 0; i < v.Defs.Size(); i++)
- if (v.Defs[i])
- numDefined++;
-
+ const unsigned numDefined = BoolVector_CountSum(v.Defs);
if (numDefined == 0)
return;
- WriteAlignedBoolHeader(v.Defs, numDefined, type, 8);
+ WriteAlignedBools(v.Defs, numDefined, type, 3);
- for (i = 0; i < v.Defs.Size(); i++)
+ for (unsigned i = 0; i < v.Defs.Size(); i++)
if (v.Defs[i])
WriteUInt64(v.Vals[i]);
}
@@ -519,14 +501,20 @@ HRESULT COutArchive::EncodeStream(
outFolders.FolderUnpackCRCs.Defs.Add(true);
outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size()));
// outFolders.NumUnpackStreamsVector.Add(1);
- UInt64 dataSize64 = data.Size();
- UInt64 unpackSize;
- RINOK(encoder.Encode(
+ const UInt64 dataSize64 = data.Size();
+ const UInt64 expectSize = data.Size();
+ RINOK(encoder.Encode1(
EXTERNAL_CODECS_LOC_VARS
stream,
// NULL,
- &dataSize64,
- folders.AddNew(), outFolders.CoderUnpackSizes, unpackSize, SeqStream, packSizes, NULL))
+ &dataSize64, // inSizeForReduce
+ expectSize,
+ folders.AddNew(),
+ // outFolders.CoderUnpackSizes, unpackSize,
+ SeqStream, packSizes, NULL))
+ if (!streamSpec->WasFinished())
+ return E_FAIL;
+ encoder.Encode_Post(dataSize64, outFolders.CoderUnpackSizes);
return S_OK;
}
@@ -550,7 +538,39 @@ void COutArchive::WriteHeader(
WriteByte(NID::kHeader);
- // Archive Properties
+ /*
+ {
+ // It's example for per archive properies writing
+
+ WriteByte(NID::kArchiveProperties);
+
+ // you must use random 40-bit number that will identify you
+ // then you can use same kDeveloperID for any properties and methods
+ const UInt64 kDeveloperID = 0x123456789A; // change that value to real random 40-bit number
+
+ #define GENERATE_7Z_ID(developerID, subID) (((UInt64)0x3F << 56) | ((UInt64)developerID << 16) | subID)
+
+ {
+ const UInt64 kSubID = 0x1; // you can use small number for subID
+ const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID);
+ WriteNumber(kID);
+ const unsigned kPropsSize = 3; // it's example size
+ WriteNumber(kPropsSize);
+ for (unsigned i = 0; i < kPropsSize; i++)
+ WriteByte((Byte)(i & 0xFF));
+ }
+ {
+ const UInt64 kSubID = 0x2; // you can use small number for subID
+ const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID);
+ WriteNumber(kID);
+ const unsigned kPropsSize = 5; // it's example size
+ WriteNumber(kPropsSize);
+ for (unsigned i = 0; i < kPropsSize; i++)
+ WriteByte((Byte)(i + 16));
+ }
+ WriteByte(NID::kEnd);
+ }
+ */
if (db.Folders.Size() > 0)
{
@@ -642,13 +662,21 @@ void COutArchive::WriteHeader(
const UString &name = db.Names[i];
if (!name.IsEmpty())
numDefined++;
- namesDataSize += (name.Len() + 1) * 2;
+ const size_t numUtfChars =
+ /*
+ #if WCHAR_MAX > 0xffff
+ Get_Num_Utf16_chars_from_wchar_string(name.Ptr());
+ #else
+ */
+ name.Len();
+ // #endif
+ namesDataSize += (numUtfChars + 1) * 2;
}
if (numDefined > 0)
{
namesDataSize++;
- SkipAlign(2 + GetBigNumberSize(namesDataSize), 16);
+ SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4);
WriteByte(NID::kName);
WriteNumber(namesDataSize);
@@ -659,6 +687,25 @@ void COutArchive::WriteHeader(
for (unsigned t = 0; t <= name.Len(); t++)
{
wchar_t c = name[t];
+
+ /*
+ #if WCHAR_MAX > 0xffff
+ if (c >= 0x10000)
+ {
+ c -= 0x10000;
+ if (c < (1 << 20))
+ {
+ unsigned c0 = 0xd800 + ((c >> 10) & 0x3FF);
+ WriteByte((Byte)c0);
+ WriteByte((Byte)(c0 >> 8));
+ c = 0xdc00 + (c & 0x3FF);
+ }
+ else
+ c = '_'; // we change character unsupported by UTF16
+ }
+ #endif
+ */
+
WriteByte((Byte)c);
WriteByte((Byte)(c >> 8));
}
@@ -673,28 +720,15 @@ void COutArchive::WriteHeader(
{
/* ---------- Write Attrib ---------- */
- CBoolVector boolVector;
- boolVector.ClearAndSetSize(db.Files.Size());
- unsigned numDefined = 0;
-
- {
- FOR_VECTOR (i, db.Files)
- {
- bool defined = db.Files[i].AttribDefined;
- boolVector[i] = defined;
- if (defined)
- numDefined++;
- }
- }
+ const unsigned numDefined = BoolVector_CountSum(db.Attrib.Defs);
if (numDefined != 0)
{
- WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttrib, 4);
- FOR_VECTOR (i, db.Files)
+ WriteAlignedBools(db.Attrib.Defs, numDefined, NID::kWinAttrib, 2);
+ FOR_VECTOR (i, db.Attrib.Defs)
{
- const CFileItem &file = db.Files[i];
- if (file.AttribDefined)
- WriteUInt32(file.Attrib);
+ if (db.Attrib.Defs[i])
+ WriteUInt32(db.Attrib.Vals[i]);
}
}
}
@@ -702,18 +736,8 @@ void COutArchive::WriteHeader(
/*
{
// ---------- Write IsAux ----------
- unsigned numAux = 0;
- const CBoolVector &isAux = db.IsAux;
- for (i = 0; i < isAux.Size(); i++)
- if (isAux[i])
- numAux++;
- if (numAux > 0)
- {
- const unsigned bvSize = Bv_GetSizeInBytes(isAux);
- WriteByte(NID::kIsAux);
- WriteNumber(bvSize);
- WriteBoolVector(isAux);
- }
+ if (BoolVector_CountSum(db.IsAux) != 0)
+ WritePropBoolVector(NID::kIsAux, db.IsAux);
}
{
@@ -734,10 +758,10 @@ void COutArchive::WriteHeader(
}
if (numParentLinks > 0)
{
- // WriteAlignedBoolHeader(boolVector, numDefined, NID::kParent, 4);
+ // WriteAlignedBools(boolVector, numDefined, NID::kParent, 2);
const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector);
const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1;
- SkipAlign(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 4);
+ SkipToAligned(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 2);
WriteByte(NID::kParent);
WriteNumber(dataSize);
@@ -765,7 +789,7 @@ void COutArchive::WriteHeader(
// secureDataSize += db.SecureIDs.Size() * 4;
for (i = 0; i < db.SecureIDs.Size(); i++)
secureDataSize += GetBigNumberSize(db.SecureIDs[i]);
- SkipAlign(2 + GetBigNumberSize(secureDataSize), 4);
+ SkipToAligned(2 + GetBigNumberSize(secureDataSize), 2);
WriteByte(NID::kNtSecure);
WriteNumber(secureDataSize);
WriteByte(0);
@@ -801,15 +825,15 @@ HRESULT COutArchive::WriteDatabase(
{
headerSize = 0;
headerOffset = 0;
- headerCRC = CrcCalc(0, 0);
+ headerCRC = CrcCalc(NULL, 0);
}
else
{
bool encodeHeaders = false;
- if (options != 0)
+ if (options)
if (options->IsEmpty())
- options = 0;
- if (options != 0)
+ options = NULL;
+ if (options)
if (options->PasswordIsDefined || headerOptions.CompressMainHeader)
encodeHeaders = true;
@@ -844,7 +868,7 @@ HRESULT COutArchive::WriteDatabase(
RINOK(EncodeStream(
EXTERNAL_CODECS_LOC_VARS
encoder, buf,
- packSizes, folders, outFolders));
+ packSizes, folders, outFolders))
_writeToStream = true;
@@ -858,11 +882,11 @@ HRESULT COutArchive::WriteDatabase(
FOR_VECTOR (i, packSizes)
headerOffset += packSizes[i];
}
- RINOK(_outByte.Flush());
+ RINOK(_outByte.Flush())
headerCRC = CRC_GET_DIGEST(_crc);
headerSize = _outByte.GetProcessedSize();
}
- #ifdef _7Z_VOL
+ #ifdef Z7_7Z_VOL
if (_endMarker)
{
CFinishHeader h;
@@ -878,14 +902,28 @@ HRESULT COutArchive::WriteDatabase(
}
else
#endif
+ if (Stream)
{
CStartHeader h;
h.NextHeaderSize = headerSize;
h.NextHeaderCRC = headerCRC;
h.NextHeaderOffset = headerOffset;
- RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL));
+ RINOK(Stream->Seek((Int64)_signatureHeaderPos, STREAM_SEEK_SET, NULL))
return WriteStartHeader(h);
}
+ return S_OK;
+}
+
+void CUInt32DefVector::SetItem(unsigned index, bool defined, UInt32 value)
+{
+ while (index >= Defs.Size())
+ Defs.Add(false);
+ Defs[index] = defined;
+ if (!defined)
+ return;
+ while (index >= Vals.Size())
+ Vals.Add(0);
+ Vals[index] = value;
}
void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value)
@@ -907,6 +945,7 @@ void CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2
ATime.SetItem(index, file2.ATimeDefined, file2.ATime);
MTime.SetItem(index, file2.MTimeDefined, file2.MTime);
StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos);
+ Attrib.SetItem(index, file2.AttribDefined, file2.Attrib);
SetItem_Anti(index, file2.IsAnti);
// SetItem_Aux(index, file2.IsAux);
Names.Add(name);
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h
index 6c902668939..940cafcdfb4 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h
@@ -1,7 +1,7 @@
// 7zOut.h
-#ifndef __7Z_OUT_H
-#define __7Z_OUT_H
+#ifndef ZIP7_INC_7Z_OUT_H
+#define ZIP7_INC_7Z_OUT_H
#include "7zCompressionMode.h"
#include "7zEncode.h"
@@ -14,6 +14,8 @@
namespace NArchive {
namespace N7z {
+const unsigned k_StartHeadersRewriteSize = 32;
+
class CWriteBufferLoc
{
Byte *_data;
@@ -45,6 +47,7 @@ public:
size_t GetPos() const { return _pos; }
};
+
struct CHeaderOptions
{
bool CompressMainHeader;
@@ -71,24 +74,31 @@ struct CFileItem2
UInt64 ATime;
UInt64 MTime;
UInt64 StartPos;
+ UInt32 Attrib;
+
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
bool StartPosDefined;
+ bool AttribDefined;
bool IsAnti;
// bool IsAux;
+ /*
void Init()
{
CTimeDefined = false;
ATimeDefined = false;
MTimeDefined = false;
StartPosDefined = false;
+ AttribDefined = false;
IsAnti = false;
// IsAux = false;
}
+ */
};
+
struct COutFolders
{
CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
@@ -111,6 +121,7 @@ struct COutFolders
}
};
+
struct CArchiveDatabaseOut: public COutFolders
{
CRecordVector<UInt64> PackSizes;
@@ -123,10 +134,11 @@ struct CArchiveDatabaseOut: public COutFolders
CUInt64DefVector ATime;
CUInt64DefVector MTime;
CUInt64DefVector StartPos;
- CRecordVector<bool> IsAnti;
+ CUInt32DefVector Attrib;
+ CBoolVector IsAnti;
/*
- CRecordVector<bool> IsAux;
+ CBoolVector IsAux;
CByteBuffer SecureBuf;
CRecordVector<UInt32> SecureSizes;
@@ -154,6 +166,7 @@ struct CArchiveDatabaseOut: public COutFolders
ATime.Clear();
MTime.Clear();
StartPos.Clear();
+ Attrib.Clear();
IsAnti.Clear();
/*
@@ -176,6 +189,7 @@ struct CArchiveDatabaseOut: public COutFolders
ATime.ReserveDown();
MTime.ReserveDown();
StartPos.ReserveDown();
+ Attrib.ReserveDown();
IsAnti.ReserveDown();
/*
@@ -196,11 +210,12 @@ struct CArchiveDatabaseOut: public COutFolders
{
unsigned size = Files.Size();
return (
- CTime.CheckSize(size) &&
- ATime.CheckSize(size) &&
- MTime.CheckSize(size) &&
- StartPos.CheckSize(size) &&
- (size == IsAnti.Size() || IsAnti.Size() == 0));
+ CTime.CheckSize(size)
+ && ATime.CheckSize(size)
+ && MTime.CheckSize(size)
+ && StartPos.CheckSize(size)
+ && Attrib.CheckSize(size)
+ && (size == IsAnti.Size() || IsAnti.Size() == 0));
}
bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
@@ -224,10 +239,9 @@ struct CArchiveDatabaseOut: public COutFolders
void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name);
};
+
class COutArchive
{
- UInt64 _prefixHeaderPos;
-
HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); }
UInt64 GetPos() const;
@@ -261,8 +275,8 @@ class COutArchive
const CRecordVector<UInt64> &unpackSizes,
const CUInt32DefVector &digests);
- void SkipAlign(unsigned pos, unsigned alignSize);
- void WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize);
+ void SkipToAligned(unsigned pos, unsigned alignShifts);
+ void WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts);
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
HRESULT EncodeStream(
@@ -276,44 +290,39 @@ class COutArchive
bool _countMode;
bool _writeToStream;
- size_t _countSize;
- UInt32 _crc;
- COutBuffer _outByte;
- CWriteBufferLoc _outByte2;
-
- #ifdef _7Z_VOL
+ bool _useAlign;
+ #ifdef Z7_7Z_VOL
bool _endMarker;
#endif
+ UInt32 _crc;
+ size_t _countSize;
+ CWriteBufferLoc _outByte2;
+ COutBuffer _outByte;
+ UInt64 _signatureHeaderPos;
+ CMyComPtr<IOutStream> Stream;
- bool _useAlign;
-
- HRESULT WriteSignature();
- #ifdef _7Z_VOL
+ #ifdef Z7_7Z_VOL
HRESULT WriteFinishSignature();
- #endif
- HRESULT WriteStartHeader(const CStartHeader &h);
- #ifdef _7Z_VOL
HRESULT WriteFinishHeader(const CFinishHeader &h);
#endif
- CMyComPtr<IOutStream> Stream;
+ HRESULT WriteStartHeader(const CStartHeader &h);
+
public:
+ CMyComPtr<ISequentialOutStream> SeqStream;
COutArchive() { _outByte.Create(1 << 16); }
- CMyComPtr<ISequentialOutStream> SeqStream;
- HRESULT Create(ISequentialOutStream *stream, bool endMarker);
+ HRESULT Create_and_WriteStartPrefix(ISequentialOutStream *stream /* , bool endMarker */);
void Close();
- HRESULT SkipPrefixArchiveHeader();
HRESULT WriteDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
const CArchiveDatabaseOut &db,
const CCompressionMethodMode *options,
const CHeaderOptions &headerOptions);
- #ifdef _7Z_VOL
+ #ifdef Z7_7Z_VOL
static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false);
static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false);
#endif
-
};
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp
index 4cb5a5e6469..d3b3cbe57dc 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp
@@ -2,56 +2,63 @@
#include "StdAfx.h"
-#include "7zProperties.h"
-#include "7zHeader.h"
#include "7zHandler.h"
-
-// #define _MULTI_PACK
+#include "7zProperties.h"
namespace NArchive {
namespace N7z {
struct CPropMap
{
- UInt32 FilePropID;
- CStatProp StatProp;
+ Byte FilePropID;
+ // CStatProp StatProp;
+ VARTYPE vt;
+ UInt32 StatPropID;
};
+// #define STAT_PROP(name, id, vt) { name, id, vt }
+#define STAT_PROP(name, id, vt) vt, id
+
+#define STAT_PROP2(id, vt) STAT_PROP(NULL, id, vt)
+
+#define k_7z_id_Encrypted 97
+#define k_7z_id_Method 98
+#define k_7z_id_Block 99
+
static const CPropMap kPropMap[] =
{
- { NID::kName, { NULL, kpidPath, VT_BSTR } },
- { NID::kSize, { NULL, kpidSize, VT_UI8 } },
- { NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },
+ { NID::kName, STAT_PROP2(kpidPath, VT_BSTR) },
+ { NID::kSize, STAT_PROP2(kpidSize, VT_UI8) },
+ { NID::kPackInfo, STAT_PROP2(kpidPackSize, VT_UI8) },
- #ifdef _MULTI_PACK
- { 100, { "Pack0", kpidPackedSize0, VT_UI8 } },
- { 101, { "Pack1", kpidPackedSize1, VT_UI8 } },
- { 102, { "Pack2", kpidPackedSize2, VT_UI8 } },
- { 103, { "Pack3", kpidPackedSize3, VT_UI8 } },
- { 104, { "Pack4", kpidPackedSize4, VT_UI8 } },
+ #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES
+#define k_7z_id_PackedSize0 100
+ { k_7z_id_PackedSize0 + 0, STAT_PROP("Pack0", kpidPackedSize0, VT_UI8) },
+ { k_7z_id_PackedSize0 + 1, STAT_PROP("Pack1", kpidPackedSize1, VT_UI8) },
+ { k_7z_id_PackedSize0 + 2, STAT_PROP("Pack2", kpidPackedSize2, VT_UI8) },
+ { k_7z_id_PackedSize0 + 3, STAT_PROP("Pack3", kpidPackedSize3, VT_UI8) },
+ { k_7z_id_PackedSize0 + 4, STAT_PROP("Pack4", kpidPackedSize4, VT_UI8) },
#endif
- { NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },
- { NID::kMTime, { NULL, kpidMTime, VT_FILETIME } },
- { NID::kATime, { NULL, kpidATime, VT_FILETIME } },
- { NID::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } },
- { NID::kStartPos, { NULL, kpidPosition, VT_UI8 } },
+ { NID::kCTime, STAT_PROP2(kpidCTime, VT_FILETIME) },
+ { NID::kMTime, STAT_PROP2(kpidMTime, VT_FILETIME) },
+ { NID::kATime, STAT_PROP2(kpidATime, VT_FILETIME) },
+ { NID::kWinAttrib, STAT_PROP2(kpidAttrib, VT_UI4) },
+ { NID::kStartPos, STAT_PROP2(kpidPosition, VT_UI8) },
- { NID::kCRC, { NULL, kpidCRC, VT_UI4 } },
-
-// { NID::kIsAux, { NULL, kpidIsAux, VT_BOOL } },
- { NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } }
-
- #ifndef _SFX
- ,
- { 97, { NULL, kpidEncrypted, VT_BOOL } },
- { 98, { NULL, kpidMethod, VT_BSTR } },
- { 99, { NULL, kpidBlock, VT_UI4 } }
+ { NID::kCRC, STAT_PROP2(kpidCRC, VT_UI4) },
+ // { NID::kIsAux, STAT_PROP2(kpidIsAux, VT_BOOL) },
+ { NID::kAnti, STAT_PROP2(kpidIsAnti, VT_BOOL) }
+
+ #ifndef Z7_SFX
+ , { k_7z_id_Encrypted, STAT_PROP2(kpidEncrypted, VT_BOOL) }
+ , { k_7z_id_Method, STAT_PROP2(kpidMethod, VT_BSTR) }
+ , { k_7z_id_Block, STAT_PROP2(kpidBlock, VT_UI4) }
#endif
};
static void CopyOneItem(CRecordVector<UInt64> &src,
- CRecordVector<UInt64> &dest, UInt32 item)
+ CRecordVector<UInt64> &dest, const UInt32 item)
{
FOR_VECTOR (i, src)
if (src[i] == item)
@@ -62,7 +69,7 @@ static void CopyOneItem(CRecordVector<UInt64> &src,
}
}
-static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
+static void RemoveOneItem(CRecordVector<UInt64> &src, const UInt32 item)
{
FOR_VECTOR (i, src)
if (src[i] == item)
@@ -72,7 +79,7 @@ static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
}
}
-static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
+static void InsertToHead(CRecordVector<UInt64> &dest, const UInt32 item)
{
FOR_VECTOR (i, dest)
if (dest[i] == item)
@@ -89,7 +96,7 @@ void CHandler::FillPopIDs()
{
_fileInfoPopIDs.Clear();
- #ifdef _7Z_VOL
+ #ifdef Z7_7Z_VOL
if (_volumes.Size() < 1)
return;
const CVolume &volume = _volumes.Front();
@@ -105,34 +112,31 @@ void CHandler::FillPopIDs()
RemoveOneItem(fileInfoPopIDs, NID::kNtSecure);
*/
- COPY_ONE_ITEM(kName);
- COPY_ONE_ITEM(kAnti);
- COPY_ONE_ITEM(kSize);
- COPY_ONE_ITEM(kPackInfo);
- COPY_ONE_ITEM(kCTime);
- COPY_ONE_ITEM(kMTime);
- COPY_ONE_ITEM(kATime);
- COPY_ONE_ITEM(kWinAttrib);
- COPY_ONE_ITEM(kCRC);
- COPY_ONE_ITEM(kComment);
+ COPY_ONE_ITEM(kName)
+ COPY_ONE_ITEM(kAnti)
+ COPY_ONE_ITEM(kSize)
+ COPY_ONE_ITEM(kPackInfo)
+ COPY_ONE_ITEM(kCTime)
+ COPY_ONE_ITEM(kMTime)
+ COPY_ONE_ITEM(kATime)
+ COPY_ONE_ITEM(kWinAttrib)
+ COPY_ONE_ITEM(kCRC)
+ COPY_ONE_ITEM(kComment)
_fileInfoPopIDs += fileInfoPopIDs;
- #ifndef _SFX
- _fileInfoPopIDs.Add(97);
- _fileInfoPopIDs.Add(98);
- _fileInfoPopIDs.Add(99);
+ #ifndef Z7_SFX
+ _fileInfoPopIDs.Add(k_7z_id_Encrypted);
+ _fileInfoPopIDs.Add(k_7z_id_Method);
+ _fileInfoPopIDs.Add(k_7z_id_Block);
#endif
- #ifdef _MULTI_PACK
- _fileInfoPopIDs.Add(100);
- _fileInfoPopIDs.Add(101);
- _fileInfoPopIDs.Add(102);
- _fileInfoPopIDs.Add(103);
- _fileInfoPopIDs.Add(104);
+ #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES
+ for (unsigned i = 0; i < 5; i++)
+ _fileInfoPopIDs.Add(k_7z_id_PackedSize0 + i);
#endif
- #ifndef _SFX
+ #ifndef Z7_SFX
InsertToHead(_fileInfoPopIDs, NID::kMTime);
InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
InsertToHead(_fileInfoPopIDs, NID::kSize);
@@ -140,25 +144,29 @@ void CHandler::FillPopIDs()
#endif
}
-STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
+Z7_COM7F_IMF(CHandler::GetNumberOfProperties(UInt32 *numProps))
{
*numProps = _fileInfoPopIDs.Size();
return S_OK;
}
-STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
+Z7_COM7F_IMF(CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType))
{
if (index >= _fileInfoPopIDs.Size())
return E_INVALIDARG;
- UInt64 id = _fileInfoPopIDs[index];
- for (unsigned i = 0; i < ARRAY_SIZE(kPropMap); i++)
+ const UInt64 id = _fileInfoPopIDs[index];
+ for (unsigned i = 0; i < Z7_ARRAY_SIZE(kPropMap); i++)
{
const CPropMap &pr = kPropMap[i];
if (pr.FilePropID == id)
{
+ *propID = pr.StatPropID;
+ *varType = pr.vt;
+ /*
const CStatProp &st = pr.StatProp;
*propID = st.PropID;
*varType = st.vt;
+ */
/*
if (st.lpwstrName)
*name = ::SysAllocString(st.lpwstrName);
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.h
index 66181795422..091c39b4037 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.h
@@ -1,13 +1,16 @@
// 7zProperties.h
-#ifndef __7Z_PROPERTIES_H
-#define __7Z_PROPERTIES_H
+#ifndef ZIP7_INC_7Z_PROPERTIES_H
+#define ZIP7_INC_7Z_PROPERTIES_H
#include "../../PropID.h"
namespace NArchive {
namespace N7z {
+// #define Z7_7Z_SHOW_PACK_STREAMS_SIZES // for debug
+
+#ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES
enum
{
kpidPackedSize0 = kpidUserDefined,
@@ -16,6 +19,7 @@ enum
kpidPackedSize3,
kpidPackedSize4
};
+#endif
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp
index 389b54074e4..1f11079e626 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp
@@ -15,7 +15,13 @@ REGISTER_ARC_IO_DECREMENT_SIG(
"7z", "7z", NULL, 7,
k_Signature_Dec,
0,
- NArcInfoFlags::kFindSignature,
- NULL);
+ NArcInfoFlags::kFindSignature
+ | NArcInfoFlags::kCTime
+ | NArcInfoFlags::kATime
+ | NArcInfoFlags::kMTime
+ | NArcInfoFlags::kMTime_Default
+ , TIME_PREC_TO_ARC_FLAGS_MASK(NFileTimeType::kWindows)
+ | TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT(NFileTimeType::kWindows)
+ , NULL)
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp
index 8e45d98756c..8b531bc7c9f 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp
@@ -4,19 +4,28 @@
#include "7zSpecStream.h"
-STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize)
+/*
+Z7_COM7F_IMF(CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize))
{
UInt32 realProcessedSize;
- HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ const HRESULT result = _stream->Read(data, size, &realProcessedSize);
_size += realProcessedSize;
if (processedSize)
*processedSize = realProcessedSize;
return result;
}
-STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value)
+Z7_COM7F_IMF(CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value))
{
if (!_getSubStreamSize)
return E_NOTIMPL;
return _getSubStreamSize->GetSubStreamSize(subStream, value);
}
+
+Z7_COM7F_IMF(CSequentialInStreamSizeCount2::GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream))
+{
+ if (!_compressGetSubStreamSize)
+ return E_NOTIMPL;
+ return _compressGetSubStreamSize->GetNextInSubStream(streamIndexRes, stream);
+}
+*/
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h
index 21155069f2d..78f631e432a 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h
@@ -1,35 +1,49 @@
// 7zSpecStream.h
-#ifndef __7Z_SPEC_STREAM_H
-#define __7Z_SPEC_STREAM_H
+#ifndef ZIP7_INC_7Z_SPEC_STREAM_H
+#define ZIP7_INC_7Z_SPEC_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../ICoder.h"
-class CSequentialInStreamSizeCount2:
+/*
+#define Z7_COM_QI_ENTRY_AG_2(i, sub0, sub) else if (iid == IID_ ## i) \
+ { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
+ { i *ti = this; *outObject = ti; } }
+
+class CSequentialInStreamSizeCount2 Z7_final:
public ISequentialInStream,
public ICompressGetSubStreamSize,
+ public ICompressInSubStreams,
public CMyUnknownImp
{
+ Z7_COM_QI_BEGIN2(ISequentialInStream)
+ Z7_COM_QI_ENTRY(ICompressGetSubStreamSize)
+ Z7_COM_QI_ENTRY_AG_2(ISequentialInStream, _stream, _compressGetSubStreamSize)
+ Z7_COM_QI_END
+ Z7_COM_ADDREF_RELEASE
+
+ Z7_IFACE_COM7_IMP(ISequentialInStream)
+ Z7_IFACE_COM7_IMP(ICompressGetSubStreamSize)
+ Z7_IFACE_COM7_IMP(ICompressInSubStreams)
+
CMyComPtr<ISequentialInStream> _stream;
CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize;
+ CMyComPtr<ICompressInSubStreams> _compressGetSubStreamSize;
UInt64 _size;
public:
void Init(ISequentialInStream *stream)
{
_size = 0;
_getSubStreamSize.Release();
+ _compressGetSubStreamSize.Release();
_stream = stream;
_stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
+ _stream.QueryInterface(IID_ICompressInSubStreams, &_compressGetSubStreamSize);
}
UInt64 GetSize() const { return _size; }
-
- MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
-
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
-
- STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
};
+*/
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp
index 68e57f09d5f..4e9ea5d4868 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp
@@ -4,6 +4,8 @@
#include "../../../../C/CpuArch.h"
+#include "../../../Common/MyLinux.h"
+#include "../../../Common/StringToInt.h"
#include "../../../Common/Wildcard.h"
#include "../../Common/CreateCoder.h"
@@ -24,24 +26,43 @@
namespace NArchive {
namespace N7z {
-
#define k_X86 k_BCJ
struct CFilterMode
{
UInt32 Id;
- UInt32 Delta;
-
- CFilterMode(): Id(0), Delta(0) {}
+ UInt32 Delta; // required File Size alignment, if Id is not k_Delta.
+ // (Delta == 0) means unknown alignment
+ UInt32 Offset; // for k_ARM64
+ // UInt32 AlignSizeOpt; // for k_ARM64
+
+ CFilterMode():
+ Id(0),
+ Delta(0),
+ Offset(0)
+ // , AlignSizeOpt(0)
+ {}
+
+ void ClearFilterMode()
+ {
+ Id = 0;
+ Delta = 0;
+ Offset = 0;
+ // AlignSizeOpt = 0;
+ }
+ // it sets Delta as Align value, if Id is exe filter
+ // in another cases it sets Delta = 0, that
void SetDelta()
{
if (Id == k_IA64)
Delta = 16;
- else if (Id == k_ARM || Id == k_PPC || Id == k_SPARC)
+ else if (Id == k_ARM64 || Id == k_ARM || Id == k_PPC || Id == k_SPARC)
Delta = 4;
else if (Id == k_ARMT)
Delta = 2;
+ else if (Id == k_BCJ || Id == k_BCJ2)
+ Delta = 1; // do we need it?
else
Delta = 0;
}
@@ -55,8 +76,8 @@ struct CFilterMode
#define PE_SIG 0x00004550
#define PE_OptHeader_Magic_32 0x10B
#define PE_OptHeader_Magic_64 0x20B
-#define PE_SectHeaderSize 40
-#define PE_SECT_EXECUTE 0x20000000
+// #define PE_SectHeaderSize 40
+// #define PE_SECT_EXECUTE 0x20000000
static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
{
@@ -78,6 +99,7 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
{
case 0x014C:
case 0x8664: filterId = k_X86; break;
+ case 0xAA64: filterId = k_ARM64; break;
/*
IMAGE_FILE_MACHINE_ARM 0x01C0 // ARM LE
@@ -94,6 +116,7 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
default: return 0;
}
+ // const UInt32 numSections = GetUi16(p + 2);
optHeaderSize = GetUi16(p + 16);
if (optHeaderSize > (1 << 10))
return 0;
@@ -109,6 +132,63 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
return 0;
}
+ /*
+ // Windows exe file sizes are not aligned for 4 KiB.
+ // So we can't use (CFilterMode::Offset != 0) in solid archives.
+ // So we just don't set Offset here.
+#define NUM_SCAN_SECTIONS_MAX (1 << 6)
+#define EXE_SECTION_OFFSET_MAX (1 << 27)
+#define EXE_SECTION_SIZE_MIN (1 << 8)
+#define EXE_SECTION_SIZE_MAX (1 << 27)
+#define PE_SectHeaderSize 40
+#define PE_SECT_EXECUTE 0x20000000
+
+ if (numSections > NUM_SCAN_SECTIONS_MAX)
+ return 0;
+
+ p += optHeaderSize;
+ // UInt32 numExeSections = 0;
+ // bool execute_finded = false;
+ // UInt32 sect_va = 0;
+ // UInt32 sect_size = 0;
+ // UInt32 sect_offset = 0;
+
+ for (UInt32 i = 0; i < numSections
+ // && numExeSections < numSectionsMax
+ ; i++, p += PE_SectHeaderSize)
+ {
+ UInt32 characts, rawSize, offset;
+ if ((UInt32)(p - buf) + PE_SectHeaderSize > size)
+ return 0;
+ rawSize = GetUi32(p + 16);
+ offset = GetUi32(p + 20);
+ characts = GetUi32(p + 36);
+ if (rawSize >= EXE_SECTION_SIZE_MIN &&
+ rawSize <= EXE_SECTION_SIZE_MAX &&
+ offset <= EXE_SECTION_OFFSET_MAX &&
+ // offset < limit &&
+ offset > 0)
+ {
+ if ((characts & PE_SECT_EXECUTE) != 0)
+ {
+ // execute_finded = true;
+ // sect_va = GetUi32(p + 12);
+ // sect_size = rawSize;
+ // sect_offset = offset;
+ break;
+ }
+ }
+ }
+
+ filterMode->Offset = 0;
+ if (filterId == k_ARM64)
+ {
+ // filterMode->AlignSizeOpt = (1 << 12);
+ // const UInt32 offs = (sect_va - sect_offset) & 0xFFF;
+ // if (offs != 0)
+ // filterMode->Offset = offs; // change it
+ }
+ */
filterMode->Id = filterId;
return 1;
}
@@ -124,13 +204,13 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
#define ELF_DATA_2LSB 1
#define ELF_DATA_2MSB 2
-static UInt16 Get16(const Byte *p, Bool be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); }
-static UInt32 Get32(const Byte *p, Bool be) { if (be) return GetBe32(p); return GetUi32(p); }
-// static UInt64 Get64(const Byte *p, Bool be) { if (be) return GetBe64(p); return GetUi64(p); }
+static UInt16 Get16(const Byte *p, BoolInt be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); }
+static UInt32 Get32(const Byte *p, BoolInt be) { if (be) return GetBe32(p); return GetUi32(p); }
+// static UInt64 Get64(const Byte *p, BoolInt be) { if (be) return GetBe64(p); return GetUi64(p); }
static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode)
{
- Bool /* is32, */ be;
+ BoolInt /* is32, */ be;
UInt32 filterId;
if (size < 512 || buf[6] != 1) /* ver */
@@ -164,8 +244,9 @@ static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode)
case 20:
case 21: if (!be) return 0; filterId = k_PPC; break;
case 40: if ( be) return 0; filterId = k_ARM; break;
-
- /* Some IA-64 ELF exacutable have size that is not aligned for 16 bytes.
+ case 183: if (be) return 0; filterId = k_ARM64; break;
+
+ /* Some IA-64 ELF executables have size that is not aligned for 16 bytes.
So we don't use IA-64 filter for IA-64 ELF */
// case 50: if ( be) return 0; filterId = k_IA64; break;
@@ -192,6 +273,7 @@ static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode)
#define MACH_MACHINE_PPC 18
#define MACH_MACHINE_PPC64 (MACH_ARCH_ABI64 | MACH_MACHINE_PPC)
#define MACH_MACHINE_AMD64 (MACH_ARCH_ABI64 | MACH_MACHINE_386)
+#define MACH_MACHINE_ARM64 (MACH_ARCH_ABI64 | MACH_MACHINE_ARM)
static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode)
{
@@ -200,7 +282,7 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode
if (size < 512)
return 0;
- Bool /* mode64, */ be;
+ BoolInt /* mode64, */ be;
switch (GetUi32(buf))
{
case MACH_SIG_BE_32: /* mode64 = False; */ be = True; break;
@@ -218,6 +300,7 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode
case MACH_MACHINE_SPARC: if (!be) return 0; filterId = k_SPARC; break;
case MACH_MACHINE_PPC:
case MACH_MACHINE_PPC64: if (!be) return 0; filterId = k_PPC; break;
+ case MACH_MACHINE_ARM64: if ( be) return 0; filterId = k_ARM64; break;
default: return 0;
}
@@ -239,7 +322,7 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode
#define RIFF_SIG 0x46464952
-static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
+static BoolInt Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
{
UInt32 subChunkSize, pos;
if (size < 0x2C)
@@ -254,10 +337,12 @@ static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
if (subChunkSize < 0x10 || subChunkSize > 0x12 || GetUi16(buf + 0x14) != 1)
return False;
- unsigned numChannels = GetUi16(buf + 0x16);
- unsigned bitsPerSample = GetUi16(buf + 0x22);
-
- if ((bitsPerSample & 0x7) != 0 || bitsPerSample >= 256 || numChannels >= 256)
+ const unsigned numChannels = GetUi16(buf + 0x16);
+ const unsigned bitsPerSample = GetUi16(buf + 0x22);
+ if ((bitsPerSample & 0x7) != 0)
+ return False;
+ const UInt32 delta = (UInt32)numChannels * (bitsPerSample >> 3);
+ if (delta == 0 || delta > 256)
return False;
pos = 0x14 + subChunkSize;
@@ -271,9 +356,6 @@ static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
subChunkSize = GetUi32(buf + pos + 4);
if (GetUi32(buf + pos) == WAV_SUBCHUNK_data)
{
- unsigned delta = numChannels * (bitsPerSample >> 3);
- if (delta >= 256)
- return False;
filterMode->Id = k_Delta;
filterMode->Delta = delta;
return True;
@@ -285,10 +367,15 @@ static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
return False;
}
-static Bool ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode)
+
+/*
+ filterMode->Delta will be set as:
+ = delta value : [1, 256] : for k_Delta
+ = 0 for another filters (branch filters)
+*/
+static BoolInt ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode)
{
- filterMode->Id = 0;
- filterMode->Delta = 0;
+ filterMode->ClearFilterMode();
if (Parse_EXE(buf, size, filterMode)) return True;
if (Parse_ELF(buf, size, filterMode)) return True;
@@ -316,18 +403,44 @@ struct CFilterMode2: public CFilterMode
else if (!m.Encrypted)
return 1;
- if (Id < m.Id) return -1;
- if (Id > m.Id) return 1;
+ const UInt32 id1 = Id;
+ const UInt32 id2 = m.Id;
+ /*
+ // we can change the order to place k_ARM64 files close to another exe files
+ if (id1 <= k_SPARC &&
+ id2 <= k_SPARC)
+ {
+ #define k_ARM64_FOR_SORT 0x3030901
+ if (id1 == k_ARM64) id1 = k_ARM64_FOR_SORT;
+ if (id2 == k_ARM64) id2 = k_ARM64_FOR_SORT;
+ }
+ */
+ if (id1 < id2) return -1;
+ if (id1 > id2) return 1;
if (Delta < m.Delta) return -1;
if (Delta > m.Delta) return 1;
+ if (Offset < m.Offset) return -1;
+ if (Offset > m.Offset) return 1;
+
+ /* we don't go here, because GetGroup()
+ and operator ==(const CFilterMode2 &m)
+ add only unique CFilterMode2:: { Id, Delta, Offset, Encrypted } items.
+ */
+ /*
+ if (GroupIndex < m.GroupIndex) return -1;
+ if (GroupIndex > m.GroupIndex) return 1;
+ */
return 0;
}
bool operator ==(const CFilterMode2 &m) const
{
- return Id == m.Id && Delta == m.Delta && Encrypted == m.Encrypted;
+ return Id == m.Id
+ && Delta == m.Delta
+ && Offset == m.Offset
+ && Encrypted == m.Encrypted;
}
};
@@ -368,6 +481,7 @@ static inline bool IsExeFilter(CMethodId m)
{
switch (m)
{
+ case k_ARM64:
case k_BCJ:
case k_BCJ2:
case k_ARM:
@@ -384,8 +498,9 @@ static unsigned Get_FilterGroup_for_Folder(
CRecordVector<CFilterMode2> &filters, const CFolderEx &f, bool extractFilter)
{
CFilterMode2 m;
- m.Id = 0;
- m.Delta = 0;
+ // m.Id = 0;
+ // m.Delta = 0;
+ // m.Offset = 0;
m.Encrypted = f.IsEncrypted();
if (extractFilter)
@@ -406,6 +521,9 @@ static unsigned Get_FilterGroup_for_Folder(
if (m.Id == k_BCJ2)
m.Id = k_BCJ;
m.SetDelta();
+ if (m.Id == k_ARM64)
+ if (coder.Props.Size() == 4)
+ m.Offset = GetUi32(coder.Props);
}
}
@@ -418,15 +536,15 @@ static unsigned Get_FilterGroup_for_Folder(
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
UInt64 position, UInt64 size, ICompressProgressInfo *progress)
{
- RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));
+ RINOK(InStream_SeekSet(inStream, position))
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
- CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
+ CMyComPtr<ISequentialInStream> inStreamLimited(streamSpec);
streamSpec->SetStream(inStream);
streamSpec->Init(size);
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
- RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
+ RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress))
return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL);
}
@@ -446,7 +564,7 @@ UString CUpdateItem::GetExtension() const
}
*/
-#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
+#define RINOZ(x) { const int _t_ = (x); if (_t_ != 0) return _t_; }
#define RINOZ_COMP(a, b) RINOZ(MyCompare(a, b))
@@ -631,7 +749,7 @@ struct CRefItem
unsigned NamePos;
unsigned ExtensionIndex;
- CRefItem() {};
+ CRefItem() {}
CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType):
UpdateItem(&ui),
Index(index),
@@ -642,13 +760,13 @@ struct CRefItem
if (sortByType)
{
int slashPos = ui.Name.ReverseFind_PathSepar();
- NamePos = slashPos + 1;
+ NamePos = (unsigned)(slashPos + 1);
int dotPos = ui.Name.ReverseFind_Dot();
if (dotPos <= slashPos)
ExtensionPos = ui.Name.Len();
else
{
- ExtensionPos = dotPos + 1;
+ ExtensionPos = (unsigned)(dotPos + 1);
if (ExtensionPos != ui.Name.Len())
{
AString s;
@@ -711,16 +829,16 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para
// bool sortByType = *(bool *)param;
const CSortParam *sortParam = (const CSortParam *)param;
- bool sortByType = sortParam->SortByType;
+ const bool sortByType = sortParam->SortByType;
if (sortByType)
{
- RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex);
- RINOZ(CompareFileNames(u1.Name.Ptr(a1.ExtensionPos), u2.Name.Ptr(a2.ExtensionPos)));
- RINOZ(CompareFileNames(u1.Name.Ptr(a1.NamePos), u2.Name.Ptr(a2.NamePos)));
+ RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex)
+ RINOZ(CompareFileNames(u1.Name.Ptr(a1.ExtensionPos), u2.Name.Ptr(a2.ExtensionPos)))
+ RINOZ(CompareFileNames(u1.Name.Ptr(a1.NamePos), u2.Name.Ptr(a2.NamePos)))
if (!u1.MTimeDefined && u2.MTimeDefined) return 1;
if (u1.MTimeDefined && !u2.MTimeDefined) return -1;
- if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime);
- RINOZ_COMP(u1.Size, u2.Size);
+ if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime)
+ RINOZ_COMP(u1.Size, u2.Size)
}
/*
int par1 = a1.UpdateItem->ParentFolderIndex;
@@ -766,9 +884,9 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para
}
*/
// RINOZ_COMP(a1.UpdateItem->ParentSortIndex, a2.UpdateItem->ParentSortIndex);
- RINOK(CompareFileNames(u1.Name, u2.Name));
- RINOZ_COMP(a1.UpdateItem->IndexInClient, a2.UpdateItem->IndexInClient);
- RINOZ_COMP(a1.UpdateItem->IndexInArchive, a2.UpdateItem->IndexInArchive);
+ RINOK(CompareFileNames(u1.Name, u2.Name))
+ RINOZ_COMP(a1.UpdateItem->IndexInClient, a2.UpdateItem->IndexInClient)
+ RINOZ_COMP(a1.UpdateItem->IndexInArchive, a2.UpdateItem->IndexInArchive)
return 0;
}
@@ -779,7 +897,7 @@ struct CSolidGroup
CRecordVector<CFolderRepack> folderRefs;
};
-static const char * const g_ExeExts[] =
+static const char * const g_Exe_Exts[] =
{
"dll"
, "exe"
@@ -788,13 +906,64 @@ static const char * const g_ExeExts[] =
, "sys"
};
-static bool IsExeExt(const wchar_t *ext)
+static const char * const g_ExeUnix_Exts[] =
+{
+ "so"
+ , "dylib"
+};
+
+static bool IsExt_Exe(const wchar_t *ext)
+{
+ for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Exe_Exts); i++)
+ if (StringsAreEqualNoCase_Ascii(ext, g_Exe_Exts[i]))
+ return true;
+ return false;
+}
+
+/*
+static bool IsExt_ExeUnix(const wchar_t *ext)
{
- for (unsigned i = 0; i < ARRAY_SIZE(g_ExeExts); i++)
- if (StringsAreEqualNoCase_Ascii(ext, g_ExeExts[i]))
+ for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExeUnix_Exts); i++)
+ if (StringsAreEqualNoCase_Ascii(ext, g_ExeUnix_Exts[i]))
return true;
return false;
}
+*/
+
+// we try to find "so" extension in such name: libstdc++.so.6.0.29
+static bool IsExt_ExeUnix_NumericAllowed(const UString &path)
+{
+ unsigned pos = path.Len();
+ unsigned dotPos = pos;
+ for (;;)
+ {
+ if (pos == 0)
+ return false;
+ const wchar_t c = path[--pos];
+ if (IS_PATH_SEPAR(c))
+ return false;
+ if (c == '.')
+ {
+ const unsigned num = (dotPos - pos) - 1;
+ if (num < 1)
+ return false;
+ const wchar_t *cur = path.Ptr(pos + 1);
+ for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExeUnix_Exts); i++)
+ {
+ const char *ext = g_ExeUnix_Exts[i];
+ if (num == MyStringLen(ext))
+ if (IsString1PrefixedByString2_NoCase_Ascii(cur, ext))
+ return true;
+ }
+ const wchar_t *end;
+ ConvertStringToUInt32(cur, &end);
+ if ((size_t)(end - cur) != num)
+ return false;
+ dotPos = pos;
+ }
+ }
+}
+
struct CAnalysis
{
@@ -803,12 +972,26 @@ struct CAnalysis
bool ParseWav;
bool ParseExe;
+ bool ParseExeUnix;
+ bool ParseNoExt;
bool ParseAll;
+ /*
+ bool Need_ATime;
+ bool ATime_Defined;
+ FILETIME ATime;
+ */
+
CAnalysis():
- ParseWav(true),
+ ParseWav(false),
ParseExe(false),
+ ParseExeUnix(false),
+ ParseNoExt(false),
ParseAll(false)
+ /*
+ , Need_ATime(false)
+ , ATime_Defined(false)
+ */
{}
HRESULT GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMode &filterMode);
@@ -820,32 +1003,46 @@ HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMo
{
filterMode.Id = 0;
filterMode.Delta = 0;
+ filterMode.Offset = 0;
CFilterMode filterModeTemp = filterMode;
- int slashPos = ui.Name.ReverseFind_PathSepar();
- int dotPos = ui.Name.ReverseFind_Dot();
+ const int slashPos = ui.Name.ReverseFind_PathSepar();
+ const int dotPos = ui.Name.ReverseFind_Dot();
// if (dotPos > slashPos)
{
bool needReadFile = ParseAll;
-
+ /* if (Callback) is not supported by client,
+ we still try to use file name extension to detect executable file */
bool probablyIsSameIsa = false;
if (!needReadFile || !Callback)
{
- const wchar_t *ext;
+ const wchar_t *ext = NULL;
if (dotPos > slashPos)
- ext = ui.Name.Ptr(dotPos + 1);
- else
- ext = ui.Name.RightPtr(0);
-
- // p7zip uses the trick to store posix attributes in high 16 bits
+ ext = ui.Name.Ptr((unsigned)(dotPos + 1));
+ // 7-zip stores posix attributes in high 16 bits and sets (0x8000) flag
if (ui.Attrib & 0x8000)
{
- unsigned st_mode = ui.Attrib >> 16;
- // st_mode = 00111;
- if ((st_mode & 00111) && (ui.Size >= 2048))
+ const unsigned st_mode = ui.Attrib >> 16;
+ /* note: executable ".so" can be without execute permission,
+ and symbolic link to such ".so" file is possible */
+ // st_mode = 00111; // for debug
+ /* in Linux we expect such permissions:
+ 0755 : for most executables
+ 0644 : for some ".so" files
+ 0777 : in WSL for all files.
+ We can try to exclude some such 0777 cases from analysis,
+ if there is non-executable extension.
+ */
+
+ if ((st_mode & (
+ MY_LIN_S_IXUSR |
+ MY_LIN_S_IXGRP |
+ MY_LIN_S_IXOTH)) != 0
+ && MY_LIN_S_ISREG(st_mode)
+ && (ui.Size >= (1u << 11)))
{
#ifndef _WIN32
probablyIsSameIsa = true;
@@ -854,73 +1051,114 @@ HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMo
}
}
- if (IsExeExt(ext))
+ if (!needReadFile)
{
- needReadFile = true;
- #ifdef _WIN32
- probablyIsSameIsa = true;
- needReadFile = ParseExe;
- #endif
- }
- else if (StringsAreEqualNoCase_Ascii(ext, "wav"))
- {
- needReadFile = ParseWav;
- }
- /*
- else if (!needReadFile && ParseUnixExt)
- {
- if (StringsAreEqualNoCase_Ascii(ext, "so")
- || StringsAreEqualNoCase_Ascii(ext, ""))
-
- needReadFile = true;
+ if (!ext)
+ needReadFile = ParseNoExt;
+ else
+ {
+ bool isUnixExt = false;
+ if (ParseExeUnix)
+ isUnixExt = IsExt_ExeUnix_NumericAllowed(ui.Name);
+ if (isUnixExt)
+ {
+ needReadFile = true;
+ #ifndef _WIN32
+ probablyIsSameIsa = true;
+ #endif
+ }
+ else if (IsExt_Exe(ext))
+ {
+ needReadFile = ParseExe;
+ #ifdef _WIN32
+ probablyIsSameIsa = true;
+ #endif
+ }
+ else if (StringsAreEqualNoCase_Ascii(ext, "wav"))
+ {
+ if (!needReadFile)
+ needReadFile = ParseWav;
+ }
+ }
}
- */
}
- if (needReadFile && Callback)
+ if (needReadFile)
{
- if (Buffer.Size() != kAnalysisBufSize)
- {
- Buffer.Alloc(kAnalysisBufSize);
- }
+ BoolInt parseRes = false;
+ if (Callback)
{
+ if (Buffer.Size() != kAnalysisBufSize)
+ Buffer.Alloc(kAnalysisBufSize);
CMyComPtr<ISequentialInStream> stream;
HRESULT result = Callback->GetStream2(index, &stream, NUpdateNotifyOp::kAnalyze);
if (result == S_OK && stream)
{
+ /*
+ if (Need_ATime)
+ {
+ // access time could be changed in analysis pass
+ CMyComPtr<IStreamGetProps> getProps;
+ stream.QueryInterface(IID_IStreamGetProps, (void **)&getProps);
+ if (getProps)
+ if (getProps->GetProps(NULL, NULL, &ATime, NULL, NULL) == S_OK)
+ ATime_Defined = true;
+ }
+ */
size_t size = kAnalysisBufSize;
result = ReadStream(stream, Buffer, &size);
stream.Release();
// RINOK(Callback->SetOperationResult2(index, NUpdate::NOperationResult::kOK));
if (result == S_OK)
{
- Bool parseRes = ParseFile(Buffer, size, &filterModeTemp);
- if (parseRes && filterModeTemp.Delta == 0)
- {
- filterModeTemp.SetDelta();
- if (filterModeTemp.Delta != 0 && filterModeTemp.Id != k_Delta)
- {
- if (ui.Size % filterModeTemp.Delta != 0)
- {
- parseRes = false;
- }
- }
- }
- if (!parseRes)
+ parseRes = ParseFile(Buffer, size, &filterModeTemp);
+ }
+ }
+ } // Callback
+ else if (probablyIsSameIsa)
+ {
+ #ifdef MY_CPU_X86_OR_AMD64
+ filterModeTemp.Id = k_X86;
+ #endif
+ #ifdef MY_CPU_ARM64
+ filterModeTemp.Id = k_ARM64;
+ #endif
+ parseRes = true;
+ }
+
+ if (parseRes
+ && filterModeTemp.Id != k_Delta
+ && filterModeTemp.Delta == 0)
+ {
+ /* ParseFile() sets (filterModeTemp.Delta == 0) for all
+ methods except of k_Delta. */
+ // it's not k_Delta
+ // So we call SetDelta() to set Delta
+ filterModeTemp.SetDelta();
+ if (filterModeTemp.Delta > 1)
+ {
+ /* If file Size is not aligned, then branch filter
+ will not work for next file in solid block.
+ Maybe we should allow filter for non-aligned-size file in non-solid archives ?
+ */
+ if (ui.Size % filterModeTemp.Delta != 0)
+ parseRes = false;
+ // windows exe files are not aligned for 4 KiB.
+ /*
+ else if (filterModeTemp.Id == k_ARM64 && filterModeTemp.Offset != 0)
+ {
+ if (ui.Size % (1 << 12) != 0)
{
- filterModeTemp.Id = 0;
- filterModeTemp.Delta = 0;
+ // If Size is not aligned for 4 KiB, then Offset will not work for next file in solid block.
+ // so we place such file in group with (Offset==0).
+ filterModeTemp.Offset = 0;
}
}
+ */
}
}
- }
- else if ((needReadFile && !Callback) || probablyIsSameIsa)
- {
- #ifdef MY_CPU_X86_OR_AMD64
- if (probablyIsSameIsa)
- filterModeTemp.Id = k_X86;
- #endif
+ if (!parseRes)
+ filterModeTemp.ClearFilterMode();
}
}
@@ -989,7 +1227,7 @@ static HRESULT AddBcj2Methods(CCompressionMethodMode &mode)
mode.Methods.Add(m);
mode.Methods.Add(m);
- RINOK(AddBondForFilter(mode));
+ RINOK(AddBondForFilter(mode))
CBond2 bond;
bond.OutCoder = 0;
bond.InCoder = methodIndex; bond.OutStream = 1; mode.Bonds.Add(bond);
@@ -1003,7 +1241,7 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode,
if (mode.Filter_was_Inserted)
{
const CMethodFull &m = mode.Methods[0];
- CMethodId id = m.Id;
+ const CMethodId id = m.Id;
if (id == k_BCJ2)
return AddBcj2Methods(mode);
if (!m.IsSimpleCoder())
@@ -1018,7 +1256,7 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode,
CMethodFull &m = mode.Methods.InsertNew(0);
{
- FOR_VECTOR(k, mode.Bonds)
+ FOR_VECTOR (k, mode.Bonds)
{
CBond2 &bond = mode.Bonds[k];
bond.InCoder++;
@@ -1038,23 +1276,32 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode,
GetMethodFull(filterMode.Id, 1, m);
if (filterMode.Id == k_Delta)
m.AddProp32(NCoderPropID::kDefaultProp, filterMode.Delta);
+ else if (filterMode.Id == k_ARM64)
+ {
+ // if (filterMode.Offset != 0)
+ m.AddProp32(
+ NCoderPropID::kDefaultProp,
+ // NCoderPropID::kBranchOffset,
+ filterMode.Offset);
+ }
res = AddFilterBond(mode);
int alignBits = -1;
- if (filterMode.Id == k_Delta || filterMode.Delta != 0)
- {
- if (filterMode.Delta == 1) alignBits = 0;
- else if (filterMode.Delta == 2) alignBits = 1;
- else if (filterMode.Delta == 4) alignBits = 2;
- else if (filterMode.Delta == 8) alignBits = 3;
- else if (filterMode.Delta == 16) alignBits = 4;
- }
- else
{
- // alignBits = GetAlignForFilterMethod(filterMode.Id);
+ const UInt32 delta = filterMode.Delta;
+ if (delta == 0 || delta > 16)
+ {
+ // if (delta == 0) alignBits = GetAlignForFilterMethod(filterMode.Id);
+ }
+ else if ((delta & ((1 << 4) - 1)) == 0) alignBits = 4;
+ else if ((delta & ((1 << 3) - 1)) == 0) alignBits = 3;
+ else if ((delta & ((1 << 2) - 1)) == 0) alignBits = 2;
+ else if ((delta & ((1 << 1) - 1)) == 0) alignBits = 1;
+ // else alignBits = 0;
+ /* alignBits=0 is default mode for lzma/lzma2.
+ So we don't set alignBits=0 here. */
}
-
- if (res == S_OK && alignBits >= 0)
+ if (res == S_OK && alignBits > 0)
{
unsigned nextCoder = 1;
if (!mode.Bonds.IsEmpty())
@@ -1071,12 +1318,12 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode,
if (alignBits != 0)
{
if (alignBits > 2 || filterMode.Id == k_Delta)
- nextMethod.AddProp32(NCoderPropID::kPosStateBits, alignBits);
+ nextMethod.AddProp32(NCoderPropID::kPosStateBits, (unsigned)alignBits);
unsigned lc = 0;
if (alignBits < 3)
- lc = 3 - alignBits;
+ lc = (unsigned)(3 - alignBits);
nextMethod.AddProp32(NCoderPropID::kLitContextBits, lc);
- nextMethod.AddProp32(NCoderPropID::kLitPosBits, alignBits);
+ nextMethod.AddProp32(NCoderPropID::kLitPosBits, (unsigned)alignBits);
}
}
}
@@ -1088,18 +1335,23 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode,
}
-static void FromUpdateItemToFileItem(const CUpdateItem &ui,
- CFileItem &file, CFileItem2 &file2)
+static void UpdateItem_To_FileItem2(const CUpdateItem &ui, CFileItem2 &file2)
{
- if (ui.AttribDefined)
- file.SetAttrib(ui.Attrib);
-
+ file2.Attrib = ui.Attrib; file2.AttribDefined = ui.AttribDefined;
file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined;
file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined;
file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined;
file2.IsAnti = ui.IsAnti;
// file2.IsAux = false;
file2.StartPosDefined = false;
+ // file2.StartPos = 0;
+}
+
+
+static void UpdateItem_To_FileItem(const CUpdateItem &ui,
+ CFileItem &file, CFileItem2 &file2)
+{
+ UpdateItem_To_FileItem2(ui, file2);
file.Size = ui.Size;
file.IsDir = ui.IsDir;
@@ -1107,13 +1359,15 @@ static void FromUpdateItemToFileItem(const CUpdateItem &ui,
// file.IsAltStream = ui.IsAltStream;
}
-class CRepackInStreamWithSizes:
- public ISequentialInStream,
- public ICompressGetSubStreamSize,
- public CMyUnknownImp
-{
+
+
+Z7_CLASS_IMP_COM_2(
+ CRepackInStreamWithSizes
+ , ISequentialInStream
+ , ICompressGetSubStreamSize
+)
CMyComPtr<ISequentialInStream> _stream;
- // UInt64 _size;
+ UInt64 _size;
const CBoolVector *_extractStatuses;
UInt32 _startIndex;
public:
@@ -1123,37 +1377,28 @@ public:
{
_startIndex = startIndex;
_extractStatuses = extractStatuses;
- // _size = 0;
+ _size = 0;
_stream = stream;
}
- // UInt64 GetSize() const { return _size; }
-
- MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
-
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
-
- STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
+ UInt64 GetSize() const { return _size; }
};
-STDMETHODIMP CRepackInStreamWithSizes::Read(void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CRepackInStreamWithSizes::Read(void *data, UInt32 size, UInt32 *processedSize))
{
- return _stream->Read(data, size, processedSize);
- /*
UInt32 realProcessedSize;
- HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ const HRESULT result = _stream->Read(data, size, &realProcessedSize);
_size += realProcessedSize;
if (processedSize)
*processedSize = realProcessedSize;
return result;
- */
}
-STDMETHODIMP CRepackInStreamWithSizes::GetSubStreamSize(UInt64 subStream, UInt64 *value)
+Z7_COM7F_IMF(CRepackInStreamWithSizes::GetSubStreamSize(UInt64 subStream, UInt64 *value))
{
*value = 0;
if (subStream >= _extractStatuses->Size())
return S_FALSE; // E_FAIL;
- unsigned index = (unsigned)subStream;
+ const unsigned index = (unsigned)subStream;
if ((*_extractStatuses)[index])
{
const CFileItem &fi = _db->Files[_startIndex + index];
@@ -1184,7 +1429,7 @@ protected:
public:
const CDbEx *_db;
CMyComPtr<IArchiveUpdateCallbackFile> _opCallback;
- CMyComPtr<IArchiveExtractCallbackMessage> _extractCallback;
+ CMyComPtr<IArchiveExtractCallbackMessage2> _extractCallback;
HRESULT Init(UInt32 startIndex, const CBoolVector *extractStatuses);
HRESULT CheckFinishedState() const { return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; }
@@ -1213,7 +1458,7 @@ HRESULT CRepackStreamBase::OpenFile()
NEventIndexType::kInArcIndex, arcIndex,
_needWrite ?
NUpdateNotifyOp::kRepack :
- NUpdateNotifyOp::kSkip));
+ NUpdateNotifyOp::kSkip))
}
_crc = CRC_INIT_VAL;
@@ -1239,7 +1484,7 @@ HRESULT CRepackStreamBase::CloseFile()
{
RINOK(_extractCallback->ReportExtractResult(
NEventIndexType::kInArcIndex, arcIndex,
- NExtract::NOperationResult::kCRCError));
+ NExtract::NOperationResult::kCRCError))
}
// return S_FALSE;
return k_My_HRESULT_CRC_ERROR;
@@ -1249,30 +1494,28 @@ HRESULT CRepackStreamBase::ProcessEmptyFiles()
{
while (_currentIndex < _extractStatuses->Size() && _db->Files[_startIndex + _currentIndex].Size == 0)
{
- RINOK(OpenFile());
- RINOK(CloseFile());
+ RINOK(OpenFile())
+ RINOK(CloseFile())
}
return S_OK;
}
-#ifndef _7ZIP_ST
+#ifndef Z7_ST
-class CFolderOutStream2:
+class CFolderOutStream2 Z7_final:
public CRepackStreamBase,
public ISequentialOutStream,
public CMyUnknownImp
{
+ Z7_COM_UNKNOWN_IMP_0
+ Z7_IFACE_COM7_IMP(ISequentialOutStream)
public:
CMyComPtr<ISequentialOutStream> _stream;
-
- MY_UNKNOWN_IMP
-
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
-STDMETHODIMP CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *processedSize))
{
if (processedSize)
*processedSize = 0;
@@ -1294,22 +1537,22 @@ STDMETHODIMP CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *pro
_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 (_currentIndex == _extractStatuses->Size())
{
// we don't support write cut here
return E_FAIL;
}
- RINOK(OpenFile());
+ RINOK(OpenFile())
}
return S_OK;
@@ -1321,18 +1564,19 @@ STDMETHODIMP CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *pro
static const UInt32 kTempBufSize = 1 << 16;
-class CFolderInStream2:
+class CFolderInStream2 Z7_final:
public CRepackStreamBase,
public ISequentialInStream,
public CMyUnknownImp
{
+ Z7_COM_UNKNOWN_IMP_0
+ Z7_IFACE_COM7_IMP(ISequentialInStream)
+
Byte *_buf;
public:
CMyComPtr<ISequentialInStream> _inStream;
HRESULT Result;
- MY_UNKNOWN_IMP
-
CFolderInStream2():
Result(S_OK)
{
@@ -1345,10 +1589,9 @@ public:
}
void Init() { Result = S_OK; }
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
-STDMETHODIMP CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSize))
{
if (processedSize)
*processedSize = 0;
@@ -1369,7 +1612,7 @@ STDMETHODIMP CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSi
cur = kTempBufSize;
}
- HRESULT result = _inStream->Read(buf, cur, &cur);
+ const HRESULT result = _inStream->Read(buf, cur, &cur);
_crc = CrcUpdate(_crc, buf, cur);
_rem -= cur;
@@ -1386,11 +1629,11 @@ STDMETHODIMP CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSi
if (_rem == 0)
{
- RINOK(CloseFile());
- RINOK(ProcessEmptyFiles());
+ RINOK(CloseFile())
+ RINOK(ProcessEmptyFiles())
}
- RINOK(result);
+ RINOK(result)
if (cur == 0)
return E_FAIL;
@@ -1398,20 +1641,20 @@ STDMETHODIMP CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSi
continue;
}
- RINOK(ProcessEmptyFiles());
+ RINOK(ProcessEmptyFiles())
if (_currentIndex == _extractStatuses->Size())
{
return S_OK;
}
- RINOK(OpenFile());
+ RINOK(OpenFile())
}
return S_OK;
}
-class CThreadDecoder
- #ifndef _7ZIP_ST
+class CThreadDecoder Z7_final
+ #ifndef Z7_ST
: public CVirtThread
#endif
{
@@ -1421,7 +1664,7 @@ public:
CThreadDecoder(bool multiThreadMixer):
Decoder(multiThreadMixer)
{
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
if (multiThreadMixer)
{
MtMode = false;
@@ -1435,8 +1678,9 @@ public:
// send_UnpackSize = false;
}
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
+ bool dataAfterEnd_Error;
HRESULT Result;
CMyComPtr<IInStream> InStream;
@@ -1445,41 +1689,51 @@ public:
UInt64 StartPos;
const CFolders *Folders;
- int FolderIndex;
+ unsigned FolderIndex;
// bool send_UnpackSize;
// UInt64 UnpackSize;
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
#endif
- DECL_EXTERNAL_CODECS_LOC_VARS2;
+ DECL_EXTERNAL_CODECS_LOC_VARS_DECL
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
bool MtMode;
UInt32 NumThreads;
#endif
- ~CThreadDecoder() { CVirtThread::WaitThreadFinish(); }
- virtual void Execute();
+ ~CThreadDecoder() Z7_DESTRUCTOR_override
+ {
+ /* WaitThreadFinish() will be called in ~CVirtThread().
+ But we need WaitThreadFinish() call before
+ destructors of this class members.
+ */
+ CVirtThread::WaitThreadFinish();
+ }
+private:
+ virtual void Execute() Z7_override;
#endif
};
-#ifndef _7ZIP_ST
+#ifndef Z7_ST
void CThreadDecoder::Execute()
{
try
{
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
bool isEncrypted = false;
bool passwordIsDefined = false;
UString password;
#endif
-
+
+ dataAfterEnd_Error = false;
+
Result = Decoder.Decode(
EXTERNAL_CODECS_LOC_VARS
InStream,
@@ -1491,12 +1745,16 @@ void CThreadDecoder::Execute()
Fos,
NULL, // compressProgress
+
NULL // *inStreamMainRes
+ , dataAfterEnd_Error
- _7Z_DECODER_CRYPRO_VARS
- #ifndef _7ZIP_ST
- , MtMode, NumThreads
+ Z7_7Z_DECODER_CRYPRO_VARS
+ #ifndef Z7_ST
+ , MtMode, NumThreads,
+ 0 // MemUsage
#endif
+
);
}
catch(...)
@@ -1513,20 +1771,17 @@ void CThreadDecoder::Execute()
#endif
-#ifndef _NO_CRYPTO
+#ifndef Z7_NO_CRYPTO
-class CCryptoGetTextPassword:
- public ICryptoGetTextPassword,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_NOQIB_1(
+ CCryptoGetTextPassword
+ , ICryptoGetTextPassword
+)
public:
UString Password;
-
- MY_UNKNOWN_IMP
- STDMETHOD(CryptoGetTextPassword)(BSTR *password);
};
-STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password)
+Z7_COM7F_IMF(CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password))
{
return StringToBstr(Password, password);
}
@@ -1541,6 +1796,7 @@ static void GetFile(const CDatabase &inDb, unsigned index, CFileItem &file, CFil
file2.ATimeDefined = inDb.ATime.GetItem(index, file2.ATime);
file2.MTimeDefined = inDb.MTime.GetItem(index, file2.MTime);
file2.StartPosDefined = inDb.StartPos.GetItem(index, file2.StartPos);
+ file2.AttribDefined = inDb.Attrib.GetItem(index, file2.Attrib);
file2.IsAnti = inDb.IsItemAnti(index);
// file2.IsAux = inDb.IsItemAux(index);
}
@@ -1549,52 +1805,72 @@ HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
const CDbEx *db,
- const CObjectVector<CUpdateItem> &updateItems,
+ CObjectVector<CUpdateItem> &updateItems,
// const CObjectVector<CTreeFolder> &treeFolders,
// const CUniqBlocks &secureBlocks,
- COutArchive &archive,
- CArchiveDatabaseOut &newDatabase,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
- const CUpdateOptions &options
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getDecoderPassword
- #endif
- )
+ const CUpdateOptions &options)
{
UInt64 numSolidFiles = options.NumSolidFiles;
if (numSolidFiles == 0)
numSolidFiles = 1;
- CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
- updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
+ Z7_DECL_CMyComPtr_QI_FROM(
+ IArchiveUpdateCallbackFile,
+ opCallback, updateCallback)
- CMyComPtr<IArchiveExtractCallbackMessage> extractCallback;
- updateCallback->QueryInterface(IID_IArchiveExtractCallbackMessage, (void **)&extractCallback);
-
- // size_t totalSecureDataSize = (size_t)secureBlocks.GetTotalSizeInBytes();
+ Z7_DECL_CMyComPtr_QI_FROM(
+ IArchiveExtractCallbackMessage2,
+ extractCallback, updateCallback)
/*
- CMyComPtr<IOutStream> outStream;
- RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream));
- if (!outStream)
- return E_NOTIMPL;
+ Z7_DECL_CMyComPtr_QI_FROM(
+ IArchiveUpdateCallbackArcProp,
+ reportArcProp, updateCallback)
*/
- UInt64 startBlockSize = db ? db->ArcInfo.StartPosition: 0;
- if (startBlockSize > 0 && !options.RemoveSfxBlock)
+ // size_t totalSecureDataSize = (size_t)secureBlocks.GetTotalSizeInBytes();
+
+ CMyComPtr<IStreamSetRestriction> v_StreamSetRestriction;
{
- RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
+ Z7_DECL_CMyComPtr_QI_FROM(
+ IOutStream,
+ outStream, seqOutStream)
+ if (!outStream)
+ return E_NOTIMPL;
+ const UInt64 sfxBlockSize = (db && !options.RemoveSfxBlock) ?
+ db->ArcInfo.StartPosition: 0;
+ seqOutStream->QueryInterface(IID_IStreamSetRestriction, (void **)&v_StreamSetRestriction);
+ if (v_StreamSetRestriction)
+ {
+ UInt64 offset = 0;
+ RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &offset))
+ RINOK(v_StreamSetRestriction->SetRestriction(
+ outStream ? offset + sfxBlockSize : 0,
+ outStream ? offset + sfxBlockSize + k_StartHeadersRewriteSize : 0))
+ }
+ outStream.Release();
+ if (sfxBlockSize != 0)
+ {
+ RINOK(WriteRange(inStream, seqOutStream, 0, sfxBlockSize, NULL))
+ }
}
CIntArr fileIndexToUpdateIndexMap;
UInt64 complexity = 0;
UInt64 inSizeForReduce2 = 0;
+
+ #ifndef Z7_NO_CRYPTO
bool needEncryptedRepack = false;
+ #endif
CRecordVector<CFilterMode2> filters;
CObjectVector<CSolidGroup> groups;
+
+ #ifndef Z7_ST
bool thereAreRepacks = false;
+ #endif
bool useFilters = options.UseFilters;
if (useFilters)
@@ -1602,11 +1878,15 @@ HRESULT Update(
const CCompressionMethodMode &method = *options.Method;
FOR_VECTOR (i, method.Methods)
+ {
+ /* IsFilterMethod() knows only built-in codecs
+ FIXME: we should check IsFilter status for external filters too */
if (IsFilterMethod(method.Methods[i].Id))
{
useFilters = false;
break;
}
+ }
}
if (db)
@@ -1621,24 +1901,27 @@ HRESULT Update(
{
int index = updateItems[i].IndexInArchive;
if (index != -1)
- fileIndexToUpdateIndexMap[(unsigned)index] = i;
+ fileIndexToUpdateIndexMap[(unsigned)index] = (int)i;
}
for (i = 0; i < db->NumFolders; i++)
{
CNum indexInFolder = 0;
CNum numCopyItems = 0;
- CNum numUnpackStreams = db->NumUnpackStreamsVector[i];
+ const CNum numUnpackStreams = db->NumUnpackStreamsVector[i];
UInt64 repackSize = 0;
for (CNum fi = db->FolderStartFileIndex[i]; indexInFolder < numUnpackStreams; fi++)
{
+ if (fi >= db->Files.Size())
+ return E_FAIL;
+
const CFileItem &file = db->Files[fi];
if (file.HasStream)
{
indexInFolder++;
- int updateIndex = fileIndexToUpdateIndexMap[fi];
- if (updateIndex >= 0 && !updateItems[updateIndex].NewData)
+ const int updateIndex = fileIndexToUpdateIndexMap[fi];
+ if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData)
{
numCopyItems++;
repackSize += file.Size;
@@ -1655,11 +1938,13 @@ HRESULT Update(
CFolderEx f;
db->ParseFolderEx(i, f);
+ #ifndef Z7_NO_CRYPTO
const bool isEncrypted = f.IsEncrypted();
+ #endif
const bool needCopy = (numCopyItems == numUnpackStreams);
const bool extractFilter = (useFilters || needCopy);
- unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter);
+ const unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter);
while (groupIndex >= groups.Size())
groups.AddNew();
@@ -1670,25 +1955,30 @@ HRESULT Update(
complexity += db->GetFolderFullPackSize(i);
else
{
+ #ifndef Z7_ST
thereAreRepacks = true;
+ #endif
complexity += repackSize;
if (inSizeForReduce2 < repackSize)
inSizeForReduce2 = repackSize;
+ #ifndef Z7_NO_CRYPTO
if (isEncrypted)
needEncryptedRepack = true;
+ #endif
}
}
}
UInt64 inSizeForReduce = 0;
{
+ bool isSolid = (numSolidFiles > 1 && options.NumSolidBytes != 0);
FOR_VECTOR (i, updateItems)
{
const CUpdateItem &ui = updateItems[i];
if (ui.NewData)
{
complexity += ui.Size;
- if (numSolidFiles != 1)
+ if (isSolid)
inSizeForReduce += ui.Size;
else if (inSizeForReduce < ui.Size)
inSizeForReduce = ui.Size;
@@ -1699,52 +1989,58 @@ HRESULT Update(
if (inSizeForReduce < inSizeForReduce2)
inSizeForReduce = inSizeForReduce2;
- RINOK(updateCallback->SetTotal(complexity));
+ RINOK(updateCallback->SetTotal(complexity))
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
CStreamBinder sb;
+ /*
if (options.MultiThreadMixer)
{
RINOK(sb.CreateEvents());
}
+ */
#endif
CThreadDecoder threadDecoder(options.MultiThreadMixer);
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
if (options.MultiThreadMixer && thereAreRepacks)
{
- #ifdef EXTERNAL_CODECS
- threadDecoder.__externalCodecs = __externalCodecs;
+ #ifdef Z7_EXTERNAL_CODECS
+ threadDecoder._externalCodecs = _externalCodecs;
#endif
- RINOK(threadDecoder.Create());
+ const WRes wres = threadDecoder.Create();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
}
#endif
{
CAnalysis analysis;
- if (options.AnalysisLevel == 0)
- {
- analysis.ParseWav = false;
- analysis.ParseExe = false;
- analysis.ParseAll = false;
- }
- else
+ // analysis.Need_ATime = options.Need_ATime;
+ int analysisLevel = options.AnalysisLevel;
+ // (analysisLevel < 0) means default level (5)
+ if (analysisLevel < 0)
+ analysisLevel = 5;
+ if (analysisLevel != 0)
{
analysis.Callback = opCallback;
- if (options.AnalysisLevel > 0)
+ analysis.ParseWav = true;
+ if (analysisLevel >= 5)
{
- analysis.ParseWav = true;
- if (options.AnalysisLevel >= 7)
+ analysis.ParseExe = true;
+ analysis.ParseExeUnix = true;
+ // analysis.ParseNoExt = true;
+ if (analysisLevel >= 7)
{
- analysis.ParseExe = true;
- if (options.AnalysisLevel >= 9)
+ analysis.ParseNoExt = true;
+ if (analysisLevel >= 9)
analysis.ParseAll = true;
}
}
@@ -1763,11 +2059,19 @@ HRESULT Update(
CFilterMode2 fm;
if (useFilters)
{
- RINOK(analysis.GetFilterGroup(i, ui, fm));
+ // analysis.ATime_Defined = false;
+ RINOK(analysis.GetFilterGroup(i, ui, fm))
+ /*
+ if (analysis.ATime_Defined)
+ {
+ ui.ATime = FILETIME_To_UInt64(analysis.ATime);
+ ui.ATime_WasReadByAnalysis = true;
+ }
+ */
}
fm.Encrypted = method.PasswordIsDefined;
- unsigned groupIndex = GetGroup(filters, fm);
+ const unsigned groupIndex = GetGroup(filters, fm);
while (groupIndex >= groups.Size())
groups.AddNew();
groups[groupIndex].Indices.Add(i);
@@ -1775,7 +2079,7 @@ HRESULT Update(
}
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
CCryptoGetTextPassword *getPasswordSpec = NULL;
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
@@ -1784,7 +2088,7 @@ HRESULT Update(
getPasswordSpec = new CCryptoGetTextPassword;
getTextPassword = getPasswordSpec;
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
threadDecoder.getTextPassword = getPasswordSpec;
#endif
@@ -1792,10 +2096,13 @@ HRESULT Update(
getPasswordSpec->Password = options.Method->Password;
else
{
+ Z7_DECL_CMyComPtr_QI_FROM(
+ ICryptoGetTextPassword,
+ getDecoderPassword, updateCallback)
if (!getDecoderPassword)
return E_NOTIMPL;
CMyComBSTR password;
- RINOK(getDecoderPassword->CryptoGetTextPassword(&password));
+ RINOK(getDecoderPassword->CryptoGetTextPassword(&password))
if (password)
getPasswordSpec->Password = password;
}
@@ -1803,11 +2110,12 @@ HRESULT Update(
#endif
-
// ---------- Compress ----------
- RINOK(archive.Create(seqOutStream, false));
- RINOK(archive.SkipPrefixArchiveHeader());
+ COutArchive archive;
+ CArchiveDatabaseOut newDatabase;
+
+ RINOK(archive.Create_and_WriteStartPrefix(seqOutStream))
/*
CIntVector treeFolderToArcIndex;
@@ -1837,7 +2145,7 @@ HRESULT Update(
continue;
secureID = ui.SecureIndex;
if (ui.NewProps)
- FromUpdateItemToFileItem(ui, file, file2);
+ UpdateItem_To_FileItem(ui, file, file2);
else
GetFile(*db, ui.IndexInArchive, file, file2);
}
@@ -1868,7 +2176,7 @@ HRESULT Update(
if (ui.HasStream())
continue;
}
- else if (ui.IndexInArchive != -1 && db->Files[ui.IndexInArchive].HasStream)
+ else if (ui.IndexInArchive != -1 && db->Files[(unsigned)ui.IndexInArchive].HasStream)
continue;
/*
if (ui.TreeFolderIndex >= 0)
@@ -1887,13 +2195,14 @@ HRESULT Update(
UString name;
if (ui.NewProps)
{
- FromUpdateItemToFileItem(ui, file, file2);
+ UpdateItem_To_FileItem(ui, file, file2);
+ file.CrcDefined = false;
name = ui.Name;
}
else
{
- GetFile(*db, ui.IndexInArchive, file, file2);
- db->GetPath(ui.IndexInArchive, name);
+ GetFile(*db, (unsigned)ui.IndexInArchive, file, file2);
+ db->GetPath((unsigned)ui.IndexInArchive, name);
}
/*
@@ -1909,7 +2218,6 @@ HRESULT Update(
{
// ---------- Sort Filters ----------
-
FOR_VECTOR (i, filters)
{
filters[i].GroupIndex = i;
@@ -1923,22 +2231,22 @@ HRESULT Update(
CCompressionMethodMode method = *options.Method;
{
- HRESULT res = MakeExeMethod(method, filterMode,
- #ifdef _7ZIP_ST
+ const HRESULT res = MakeExeMethod(method, filterMode,
+ #ifdef Z7_ST
false
#else
options.MaxFilter && options.MultiThreadMixer
#endif
);
- RINOK(res);
+ RINOK(res)
}
if (filterMode.Encrypted)
{
if (!method.PasswordIsDefined)
{
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
if (getPasswordSpec)
method.Password = getPasswordSpec->Password;
#endif
@@ -1957,13 +2265,13 @@ HRESULT Update(
const CSolidGroup &group = groups[filterMode.GroupIndex];
- FOR_VECTOR(folderRefIndex, group.folderRefs)
+ FOR_VECTOR (folderRefIndex, group.folderRefs)
{
const CFolderRepack &rep = group.folderRefs[folderRefIndex];
- unsigned folderIndex = rep.FolderIndex;
+ const unsigned folderIndex = rep.FolderIndex;
- CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
+ const CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
if (rep.NumCopyFiles == numUnpackStreams)
{
@@ -1971,7 +2279,7 @@ HRESULT Update(
{
RINOK(opCallback->ReportOperation(
NEventIndexType::kBlockIndex, (UInt32)folderIndex,
- NUpdateNotifyOp::kReplicate));
+ NUpdateNotifyOp::kReplicate))
// ---------- Copy old solid block ----------
{
@@ -1983,21 +2291,27 @@ HRESULT Update(
indexInFolder++;
RINOK(opCallback->ReportOperation(
NEventIndexType::kInArcIndex, (UInt32)fi,
- NUpdateNotifyOp::kReplicate));
+ NUpdateNotifyOp::kReplicate))
}
}
}
}
- UInt64 packSize = db->GetFolderFullPackSize(folderIndex);
+ const UInt64 packSize = db->GetFolderFullPackSize(folderIndex);
RINOK(WriteRange(inStream, archive.SeqStream,
- db->GetFolderStreamPos(folderIndex, 0), packSize, progress));
+ db->GetFolderStreamPos(folderIndex, 0), packSize, progress))
lps->ProgressOffset += packSize;
-
+
+ const unsigned folderIndex_New = newDatabase.Folders.Size();
CFolder &folder = newDatabase.Folders.AddNew();
+ // v23.01: we copy FolderCrc, if FolderCrc was used
+ if (db->FolderCRCs.ValidAndDefined(folderIndex))
+ newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New,
+ true, db->FolderCRCs.Vals[folderIndex]);
+
db->ParseFolderInfo(folderIndex, folder);
- CNum startIndex = db->FoStartPackStreamIndex[folderIndex];
- FOR_VECTOR(j, folder.PackStreams)
+ const CNum startIndex = db->FoStartPackStreamIndex[folderIndex];
+ FOR_VECTOR (j, folder.PackStreams)
{
newDatabase.PackSizes.Add(db->GetStreamPackSize(startIndex + j));
// newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]);
@@ -2005,7 +2319,7 @@ HRESULT Update(
}
size_t indexStart = db->FoToCoderUnpackSizes[folderIndex];
- size_t indexEnd = db->FoToCoderUnpackSizes[folderIndex + 1];
+ const size_t indexEnd = db->FoToCoderUnpackSizes[folderIndex + 1];
for (; indexStart < indexEnd; indexStart++)
newDatabase.CoderUnpackSizes.Add(db->CoderUnpackSizes[indexStart]);
}
@@ -2044,8 +2358,8 @@ HRESULT Update(
if (file.HasStream)
{
indexInFolder++;
- int updateIndex = fileIndexToUpdateIndexMap[fi];
- if (updateIndex >= 0 && !updateItems[updateIndex].NewData)
+ const int updateIndex = fileIndexToUpdateIndexMap[fi];
+ if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData)
needExtract = true;
// decodeSize += file.Size;
}
@@ -2066,7 +2380,6 @@ HRESULT Update(
unsigned startPackIndex = newDatabase.PackSizes.Size();
UInt64 curUnpackSize;
{
-
CMyComPtr<ISequentialInStream> sbInStream;
CRepackStreamBase *repackBase;
CFolderInStream2 *FosSpec2 = NULL;
@@ -2074,13 +2387,13 @@ HRESULT Update(
CRepackInStreamWithSizes *inStreamSizeCountSpec = new CRepackInStreamWithSizes;
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
{
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
if (options.MultiThreadMixer)
{
repackBase = threadDecoder.FosSpec;
CMyComPtr<ISequentialOutStream> sbOutStream;
- sb.CreateStreams(&sbInStream, &sbOutStream);
- sb.ReInit();
+ sb.CreateStreams2(sbInStream, sbOutStream);
+ RINOK(sb.Create_ReInit())
threadDecoder.FosSpec->_stream = sbOutStream;
@@ -2100,14 +2413,16 @@ HRESULT Update(
sbInStream = FosSpec2;
repackBase = FosSpec2;
- #ifndef _NO_CRYPTO
+ #ifndef Z7_NO_CRYPTO
bool isEncrypted = false;
bool passwordIsDefined = false;
UString password;
#endif
CMyComPtr<ISequentialInStream> decodedStream;
- HRESULT res = threadDecoder.Decoder.Decode(
+ bool dataAfterEnd_Error = false;
+
+ const HRESULT res = threadDecoder.Decoder.Decode(
EXTERNAL_CODECS_LOC_VARS
inStream,
db->ArcInfo.DataStartPosition, // db->GetFolderStreamPos(folderIndex, 0);,
@@ -2117,16 +2432,19 @@ HRESULT Update(
NULL, // *outStream
NULL, // *compressProgress
+
&decodedStream
+ , dataAfterEnd_Error
- _7Z_DECODER_CRYPRO_VARS
- #ifndef _7ZIP_ST
+ Z7_7Z_DECODER_CRYPRO_VARS
+ #ifndef Z7_ST
, false // mtMode
, 1 // numThreads
+ , 0 // memUsage
#endif
);
- RINOK(res);
+ RINOK(res)
if (!decodedStream)
return E_FAIL;
@@ -2138,32 +2456,44 @@ HRESULT Update(
repackBase->_extractCallback = extractCallback;
UInt32 startIndex = db->FolderStartFileIndex[folderIndex];
- RINOK(repackBase->Init(startIndex, &extractStatuses));
+ RINOK(repackBase->Init(startIndex, &extractStatuses))
inStreamSizeCountSpec->_db = db;
inStreamSizeCountSpec->Init(sbInStream, startIndex, &extractStatuses);
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
if (options.MultiThreadMixer)
{
- threadDecoder.Start();
+ WRes wres = threadDecoder.Start();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
}
#endif
}
+ // curUnpackSize = sizeToEncode;
- HRESULT encodeRes = encoder.Encode(
+ HRESULT encodeRes = encoder.Encode1(
EXTERNAL_CODECS_LOC_VARS
inStreamSizeCount,
// NULL,
&inSizeForReduce,
- newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curUnpackSize,
+ sizeToEncode, // expectedDataSize
+ newDatabase.Folders.AddNew(),
+ // newDatabase.CoderUnpackSizes, curUnpackSize,
archive.SeqStream, newDatabase.PackSizes, progress);
if (encodeRes == k_My_HRESULT_CRC_ERROR)
return E_FAIL;
- #ifndef _7ZIP_ST
+ curUnpackSize = inStreamSizeCountSpec->GetSize();
+
+ if (encodeRes == S_OK)
+ {
+ encoder.Encode_Post(curUnpackSize, newDatabase.CoderUnpackSizes);
+ }
+
+ #ifndef Z7_ST
if (options.MultiThreadMixer)
{
// 16.00: hang was fixed : for case if decoding was not finished.
@@ -2171,22 +2501,29 @@ HRESULT Update(
inStreamSizeCount.Release();
sbInStream.Release();
- threadDecoder.WaitExecuteFinish();
+ {
+ const WRes wres = threadDecoder.WaitExecuteFinish();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+ }
- HRESULT decodeRes = threadDecoder.Result;
+ const HRESULT decodeRes = threadDecoder.Result;
// if (res == k_My_HRESULT_CRC_ERROR)
- if (decodeRes == S_FALSE)
+ if (decodeRes == S_FALSE || threadDecoder.dataAfterEnd_Error)
{
if (extractCallback)
{
RINOK(extractCallback->ReportExtractResult(
NEventIndexType::kInArcIndex, db->FolderStartFileIndex[folderIndex],
// NEventIndexType::kBlockIndex, (UInt32)folderIndex,
- NExtract::NOperationResult::kDataError));
+ (decodeRes != S_OK ?
+ NExtract::NOperationResult::kDataError :
+ NExtract::NOperationResult::kDataAfterEnd)))
}
- return E_FAIL;
+ if (decodeRes != S_OK)
+ return E_FAIL;
}
- RINOK(decodeRes);
+ RINOK(decodeRes)
if (encodeRes == S_OK)
if (sb.ProcessedSize != sizeToEncode)
encodeRes = E_FAIL;
@@ -2200,15 +2537,15 @@ HRESULT Update(
{
RINOK(extractCallback->ReportExtractResult(
NEventIndexType::kBlockIndex, (UInt32)folderIndex,
- NExtract::NOperationResult::kDataError));
+ NExtract::NOperationResult::kDataError))
}
return E_FAIL;
}
- RINOK(FosSpec2->Result);
+ RINOK(FosSpec2->Result)
}
- RINOK(encodeRes);
- RINOK(repackBase->CheckFinishedState());
+ RINOK(encodeRes)
+ RINOK(repackBase->CheckFinishedState())
if (curUnpackSize != sizeToEncode)
return E_FAIL;
@@ -2224,31 +2561,30 @@ HRESULT Update(
CNum indexInFolder = 0;
for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
{
- CFileItem file;
- CFileItem2 file2;
- GetFile(*db, fi, file, file2);
- UString name;
- db->GetPath(fi, name);
- if (file.HasStream)
+ if (db->Files[fi].HasStream)
{
indexInFolder++;
- int updateIndex = fileIndexToUpdateIndexMap[fi];
+ const int updateIndex = fileIndexToUpdateIndexMap[fi];
if (updateIndex >= 0)
{
- const CUpdateItem &ui = updateItems[updateIndex];
+ const CUpdateItem &ui = updateItems[(unsigned)updateIndex];
if (ui.NewData)
continue;
+
+ UString name;
+ CFileItem file;
+ CFileItem2 file2;
+ GetFile(*db, fi, file, file2);
+
if (ui.NewProps)
{
- CFileItem uf;
- FromUpdateItemToFileItem(ui, uf, file2);
- uf.Size = file.Size;
- uf.Crc = file.Crc;
- uf.CrcDefined = file.CrcDefined;
- uf.HasStream = file.HasStream;
- file = uf;
+ UpdateItem_To_FileItem2(ui, file2);
+ file.IsDir = ui.IsDir;
name = ui.Name;
}
+ else
+ db->GetPath(fi, name);
+
/*
file.Parent = ui.ParentFolderIndex;
if (ui.TreeFolderIndex >= 0)
@@ -2265,12 +2601,13 @@ HRESULT Update(
// ---------- Compress files to new solid blocks ----------
- unsigned numFiles = group.Indices.Size();
+ const unsigned numFiles = group.Indices.Size();
if (numFiles == 0)
continue;
CRecordVector<CRefItem> refItems;
refItems.ClearAndSetSize(numFiles);
- bool sortByType = (options.UseTypeSorting && numSolidFiles > 1);
+ // bool sortByType = (options.UseTypeSorting && isSoid); // numSolidFiles > 1
+ const bool sortByType = options.UseTypeSorting;
unsigned i;
@@ -2286,13 +2623,13 @@ HRESULT Update(
for (i = 0; i < numFiles; i++)
{
- UInt32 index = refItems[i].Index;
+ const UInt32 index = refItems[i].Index;
indices[i] = index;
/*
const CUpdateItem &ui = updateItems[index];
CFileItem file;
if (ui.NewProps)
- FromUpdateItemToFileItem(ui, file);
+ UpdateItem_To_FileItem(ui, file);
else
file = db.Files[ui.IndexInArchive];
if (file.IsAnti || file.IsDir)
@@ -2316,9 +2653,9 @@ HRESULT Update(
break;
if (options.SolidExtension)
{
- int slashPos = ui.Name.ReverseFind_PathSepar();
- int dotPos = ui.Name.ReverseFind_Dot();
- const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : dotPos + 1);
+ const int slashPos = ui.Name.ReverseFind_PathSepar();
+ const int dotPos = ui.Name.ReverseFind_Dot();
+ const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : (unsigned)(dotPos + 1));
if (numSubFiles == 0)
prevExtension = ext;
else if (!StringsAreEqualNoCase(ext, prevExtension))
@@ -2329,36 +2666,77 @@ HRESULT Update(
if (numSubFiles < 1)
numSubFiles = 1;
- RINOK(lps->SetCur());
+ RINOK(lps->SetCur())
+
+ /*
+ const unsigned folderIndex = newDatabase.NumUnpackStreamsVector.Size();
+
+ if (opCallback)
+ {
+ RINOK(opCallback->ReportOperation(
+ NEventIndexType::kBlockIndex, (UInt32)folderIndex,
+ NUpdateNotifyOp::kAdd));
+ }
+ */
+
CFolderInStream *inStreamSpec = new CFolderInStream;
CMyComPtr<ISequentialInStream> solidInStream(inStreamSpec);
+
+ // inStreamSpec->_reportArcProp = reportArcProp;
+
+ inStreamSpec->Need_CTime = options.Need_CTime;
+ inStreamSpec->Need_ATime = options.Need_ATime;
+ inStreamSpec->Need_MTime = options.Need_MTime;
+ inStreamSpec->Need_Attrib = options.Need_Attrib;
+ // inStreamSpec->Need_Crc = options.Need_Crc;
+
inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
unsigned startPackIndex = newDatabase.PackSizes.Size();
- UInt64 curFolderUnpackSize;
- RINOK(encoder.Encode(
+ // UInt64 curFolderUnpackSize = totalSize;
+ // curFolderUnpackSize = (UInt64)(Int64)-1; // for debug
+ const UInt64 expectedDataSize = totalSize;
+
+ // const unsigned folderIndex_New = newDatabase.Folders.Size();
+
+ RINOK(encoder.Encode1(
EXTERNAL_CODECS_LOC_VARS
solidInStream,
// NULL,
&inSizeForReduce,
- newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curFolderUnpackSize,
- archive.SeqStream, newDatabase.PackSizes, progress));
+ expectedDataSize, // expected size
+ newDatabase.Folders.AddNew(),
+ // newDatabase.CoderUnpackSizes, curFolderUnpackSize,
+ archive.SeqStream, newDatabase.PackSizes, progress))
if (!inStreamSpec->WasFinished())
return E_FAIL;
+ /*
+ if (inStreamSpec->Need_FolderCrc)
+ newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New,
+ true, inStreamSpec->GetFolderCrc());
+ */
+
+ const UInt64 curFolderUnpackSize = inStreamSpec->Get_TotalSize_for_Coder();
+ encoder.Encode_Post(curFolderUnpackSize, newDatabase.CoderUnpackSizes);
+
+ UInt64 packSize = 0;
+ // const UInt32 numStreams = newDatabase.PackSizes.Size() - startPackIndex;
for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
- lps->OutSize += newDatabase.PackSizes[startPackIndex];
+ packSize += newDatabase.PackSizes[startPackIndex];
+ lps->OutSize += packSize;
- lps->InSize += curFolderUnpackSize;
// for ()
// newDatabase.PackCRCsDefined.Add(false);
// newDatabase.PackCRCs.Add(0);
CNum numUnpackStreams = 0;
UInt64 skippedSize = 0;
-
+ UInt64 procSize = 0;
+ // unsigned numProcessedFiles = 0;
+
for (unsigned subIndex = 0; subIndex < numSubFiles; subIndex++)
{
const CUpdateItem &ui = updateItems[indices[i + subIndex]];
@@ -2367,13 +2745,13 @@ HRESULT Update(
UString name;
if (ui.NewProps)
{
- FromUpdateItemToFileItem(ui, file, file2);
+ UpdateItem_To_FileItem(ui, file, file2);
name = ui.Name;
}
else
{
- GetFile(*db, ui.IndexInArchive, file, file2);
- db->GetPath(ui.IndexInArchive, name);
+ GetFile(*db, (unsigned)ui.IndexInArchive, file, file2);
+ db->GetPath((unsigned)ui.IndexInArchive, name);
}
if (file2.IsAnti || file.IsDir)
return E_FAIL;
@@ -2384,18 +2762,21 @@ HRESULT Update(
*/
if (!inStreamSpec->Processed[subIndex])
{
+ // we don't add file here
skippedSize += ui.Size;
- continue;
- // file.Name.AddAscii(".locked");
+ continue; // comment it for debug
+ // name += ".locked"; // for debug
}
+ // if (inStreamSpec->Need_Crc)
file.Crc = inStreamSpec->CRCs[subIndex];
file.Size = inStreamSpec->Sizes[subIndex];
- // if (file.Size >= 0) // test purposes
+ procSize += file.Size;
+ // if (file.Size >= 0) // for debug: test purposes
if (file.Size != 0)
{
- file.CrcDefined = true;
+ file.CrcDefined = true; // inStreamSpec->Need_Crc;
file.HasStream = true;
numUnpackStreams++;
}
@@ -2405,6 +2786,23 @@ HRESULT Update(
file.HasStream = false;
}
+ if (inStreamSpec->TimesDefined[subIndex])
+ {
+ if (inStreamSpec->Need_CTime)
+ { file2.CTimeDefined = true; file2.CTime = inStreamSpec->CTimes[subIndex]; }
+ if (inStreamSpec->Need_ATime
+ // && !ui.ATime_WasReadByAnalysis
+ )
+ { file2.ATimeDefined = true; file2.ATime = inStreamSpec->ATimes[subIndex]; }
+ if (inStreamSpec->Need_MTime)
+ { file2.MTimeDefined = true; file2.MTime = inStreamSpec->MTimes[subIndex]; }
+ if (inStreamSpec->Need_Attrib)
+ {
+ file2.AttribDefined = true;
+ file2.Attrib = inStreamSpec->Attribs[subIndex];
+ }
+ }
+
/*
file.Parent = ui.ParentFolderIndex;
if (ui.TreeFolderIndex >= 0)
@@ -2412,9 +2810,79 @@ HRESULT Update(
if (totalSecureDataSize != 0)
newDatabase.SecureIDs.Add(ui.SecureIndex);
*/
+ /*
+ if (reportArcProp)
+ {
+ RINOK(ReportItemProps(reportArcProp, ui.IndexInClient, file.Size,
+ file.CrcDefined ? &file.Crc : NULL))
+ }
+ */
+
+ // numProcessedFiles++;
newDatabase.AddFile(file, file2, name);
}
+ /*
+ // for debug:
+ // we can write crc to folders area, if folder contains only one file
+ if (numUnpackStreams == 1 && numSubFiles == 1)
+ {
+ const CFileItem &file = newDatabase.Files.Back();
+ if (file.CrcDefined)
+ newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New, true, file.Crc);
+ }
+ */
+
+ /*
+ // it's optional check to ensure that sizes are correct
+ if (inStreamSpec->TotalSize_for_Coder != curFolderUnpackSize)
+ return E_FAIL;
+ */
+ // if (inStreamSpec->AlignLog == 0)
+ {
+ if (procSize != curFolderUnpackSize)
+ return E_FAIL;
+ }
+ // else
+ {
+ /*
+ {
+ const CFolder &old = newDatabase.Folders.Back();
+ CFolder &folder = newDatabase.Folders.AddNew();
+ {
+ const unsigned numBonds = old.Bonds.Size();
+ folder.Bonds.SetSize(numBonds + 1);
+ for (unsigned k = 0; k < numBonds; k++)
+ folder.Bonds[k] = old.Bonds[k];
+ CBond &bond = folder.Bonds[numBonds];
+ bond.PackIndex = 0;
+ bond.UnpackIndex = 0;
+ }
+ {
+ const unsigned numCoders = old.Coders.Size();
+ folder.Coders.SetSize(numCoders + 1);
+ for (unsigned k = 0; k < numCoders; k++)
+ folder.Coders[k] = old.Coders[k];
+ CCoderInfo &cod = folder.Coders[numCoders];
+ cod.Props.Alloc(1);
+ cod.Props[0] = (Byte)inStreamSpec->AlignLog;
+ cod.NumStreams = 1;
+ }
+ {
+ const unsigned numPackStreams = old.Coders.Size();
+ folder.Coders.SetSize(numPackStreams);
+ for (unsigned k = 0; k < numPackStreams; k++)
+ folder.PackStreams[k] = old.PackStreams[k];
+ }
+ }
+ newDatabase.Folders.Delete(newDatabase.Folders.Size() - 2);
+ */
+ }
+
+
+ lps->InSize += procSize;
+ // lps->InSize += curFolderUnpackSize;
+
// numUnpackStreams = 0 is very bad case for locked files
// v3.13 doesn't understand it.
newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);
@@ -2423,12 +2891,50 @@ HRESULT Update(
if (skippedSize != 0 && complexity >= skippedSize)
{
complexity -= skippedSize;
- RINOK(updateCallback->SetTotal(complexity));
+ RINOK(updateCallback->SetTotal(complexity))
}
+
+ /*
+ if (reportArcProp)
+ {
+ PROPVARIANT prop;
+ prop.vt = VT_EMPTY;
+ prop.wReserved1 = 0;
+ {
+ NWindows::NCOM::PropVarEm_Set_UInt32(&prop, numProcessedFiles);
+ RINOK(reportArcProp->ReportProp(
+ NEventIndexType::kBlockIndex, (UInt32)folderIndex, kpidNumSubFiles, &prop));
+ }
+ {
+ NWindows::NCOM::PropVarEm_Set_UInt64(&prop, curFolderUnpackSize);
+ RINOK(reportArcProp->ReportProp(
+ NEventIndexType::kBlockIndex, (UInt32)folderIndex, kpidSize, &prop));
+ }
+ {
+ NWindows::NCOM::PropVarEm_Set_UInt64(&prop, packSize);
+ RINOK(reportArcProp->ReportProp(
+ NEventIndexType::kBlockIndex, (UInt32)folderIndex, kpidPackSize, &prop));
+ }
+ {
+ NWindows::NCOM::PropVarEm_Set_UInt32(&prop, numStreams);
+ RINOK(reportArcProp->ReportProp(
+ NEventIndexType::kBlockIndex, (UInt32)folderIndex, kpidNumStreams, &prop));
+ }
+ RINOK(reportArcProp->ReportFinished(NEventIndexType::kBlockIndex, (UInt32)folderIndex, NUpdate::NOperationResult::kOK));
+ }
+ */
+ /*
+ if (opCallback)
+ {
+ RINOK(opCallback->ReportOperation(
+ NEventIndexType::kBlockIndex, (UInt32)folderIndex,
+ NUpdateNotifyOp::kOpFinished));
+ }
+ */
}
}
- RINOK(lps->SetCur());
+ RINOK(lps->SetCur())
/*
fileIndexToUpdateIndexMap.ClearAndFree();
@@ -2458,10 +2964,26 @@ HRESULT Update(
}
}
*/
+
+ {
+ const unsigned numFolders = newDatabase.Folders.Size();
+ if (newDatabase.NumUnpackStreamsVector.Size() != numFolders
+ || newDatabase.FolderUnpackCRCs.Defs.Size() > numFolders)
+ return E_FAIL;
+ newDatabase.FolderUnpackCRCs.if_NonEmpty_FillResedue_with_false(numFolders);
+ }
+
+ updateItems.ClearAndFree();
newDatabase.ReserveDown();
if (opCallback)
- RINOK(opCallback->ReportOperation(NEventIndexType::kNoIndex, (UInt32)(Int32)-1, NUpdateNotifyOp::kHeader));
+ RINOK(opCallback->ReportOperation(NEventIndexType::kNoIndex, (UInt32)(Int32)-1, NUpdateNotifyOp::kHeader))
+
+ RINOK(archive.WriteDatabase(EXTERNAL_CODECS_LOC_VARS
+ newDatabase, options.HeaderMethod, options.HeaderOptions))
+
+ if (v_StreamSetRestriction)
+ RINOK(v_StreamSetRestriction->SetRestriction(0, 0))
return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h
index a7abf779a61..de4117af266 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h
@@ -1,7 +1,7 @@
// 7zUpdate.h
-#ifndef __7Z_UPDATE_H
-#define __7Z_UPDATE_H
+#ifndef ZIP7_INC_7Z_UPDATE_H
+#define ZIP7_INC_7Z_UPDATE_H
#include "../IArchive.h"
@@ -9,7 +9,6 @@
#include "7zCompressionMode.h"
#include "7zIn.h"
-#include "7zOut.h"
namespace NArchive {
namespace N7z {
@@ -31,7 +30,7 @@ struct CTreeFolder
struct CUpdateItem
{
int IndexInArchive;
- int IndexInClient;
+ unsigned IndexInClient;
UInt64 CTime;
UInt64 ATime;
@@ -62,6 +61,8 @@ struct CUpdateItem
bool ATimeDefined;
bool MTimeDefined;
+ // bool ATime_WasReadByAnalysis;
+
// int SecureIndex; // 0 means (no_security)
bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }
@@ -76,6 +77,7 @@ struct CUpdateItem
CTimeDefined(false),
ATimeDefined(false),
MTimeDefined(false)
+ // , ATime_WasReadByAnalysis(false)
// SecureIndex(0)
{}
void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); }
@@ -92,8 +94,6 @@ struct CUpdateOptions
bool MaxFilter; // use BCJ2 filter instead of BCJ
int AnalysisLevel;
- CHeaderOptions HeaderOptions;
-
UInt64 NumSolidFiles;
UInt64 NumSolidBytes;
bool SolidExtension;
@@ -103,6 +103,14 @@ struct CUpdateOptions
bool RemoveSfxBlock;
bool MultiThreadMixer;
+ bool Need_CTime;
+ bool Need_ATime;
+ bool Need_MTime;
+ bool Need_Attrib;
+ // bool Need_Crc;
+
+ CHeaderOptions HeaderOptions;
+
CUpdateOptions():
Method(NULL),
HeaderMethod(NULL),
@@ -114,7 +122,12 @@ struct CUpdateOptions
SolidExtension(false),
UseTypeSorting(true),
RemoveSfxBlock(false),
- MultiThreadMixer(true)
+ MultiThreadMixer(true),
+ Need_CTime(false),
+ Need_ATime(false),
+ Need_MTime(false),
+ Need_Attrib(false)
+ // , Need_Crc(true)
{}
};
@@ -122,18 +135,12 @@ HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
const CDbEx *db,
- const CObjectVector<CUpdateItem> &updateItems,
+ CObjectVector<CUpdateItem> &updateItems,
// const CObjectVector<CTreeFolder> &treeFolders, // treeFolders[0] is root
// const CUniqBlocks &secureBlocks,
- COutArchive &archive,
- CArchiveDatabaseOut &newDatabase,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
- const CUpdateOptions &options
- #ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getDecoderPassword
- #endif
- );
+ const CUpdateOptions &options);
}}
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h b/3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h
index 2854ff3e935..035267ccd02 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h
@@ -1,8 +1,11 @@
// StdAfx.h
-#ifndef __STDAFX_H
-#define __STDAFX_H
+#ifndef ZIP7_INC_STDAFX_H
+#define ZIP7_INC_STDAFX_H
+#if defined(_MSC_VER) && _MSC_VER >= 1800
+#pragma warning(disable : 4464) // relative include path contains '..'
+#endif
#include "../../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Archive.def b/3rdparty/lzma/CPP/7zip/Archive/Archive.def
index 145516d7970..2ed624623b8 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Archive.def
+++ b/3rdparty/lzma/CPP/7zip/Archive/Archive.def
@@ -10,3 +10,5 @@ EXPORTS
SetLargePageMode PRIVATE
SetCaseSensitive PRIVATE
+
+ GetModuleProp PRIVATE
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Archive2.def b/3rdparty/lzma/CPP/7zip/Archive/Archive2.def
index c7582742198..f891ad3b877 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Archive2.def
+++ b/3rdparty/lzma/CPP/7zip/Archive/Archive2.def
@@ -17,3 +17,5 @@ EXPORTS
SetLargePageMode PRIVATE
SetCaseSensitive PRIVATE
+
+ GetModuleProp PRIVATE
diff --git a/3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp b/3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp
index 28e9946d5f6..4735fcfff04 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp
@@ -10,7 +10,7 @@
#include "../Common/RegisterArc.h"
-static const unsigned kNumArcsMax = 64;
+static const unsigned kNumArcsMax = 72;
static unsigned g_NumArcs = 0;
static unsigned g_DefaultArcIndex = 0;
static const CArcInfo *g_Arcs[kNumArcsMax];
@@ -24,9 +24,10 @@ void RegisterArc(const CArcInfo *arcInfo) throw()
g_DefaultArcIndex = g_NumArcs;
g_Arcs[g_NumArcs++] = arcInfo;
}
+ // else throw 1;
}
-DEFINE_GUID(CLSID_CArchiveHandler,
+Z7_DEFINE_GUID(CLSID_CArchiveHandler,
k_7zip_GUID_Data1,
k_7zip_GUID_Data2,
k_7zip_GUID_Data3_Common,
@@ -36,7 +37,7 @@ DEFINE_GUID(CLSID_CArchiveHandler,
static inline HRESULT SetPropStrFromBin(const char *s, unsigned size, PROPVARIANT *value)
{
- if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
+ if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != NULL)
value->vt = VT_BSTR;
return S_OK;
}
@@ -46,28 +47,29 @@ static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
return SetPropStrFromBin((const char *)&guid, sizeof(guid), value);
}
-int FindFormatCalssId(const GUID *clsid)
+static int FindFormatCalssId(const GUID *clsid)
{
GUID cls = *clsid;
CLS_ARC_ID_ITEM(cls) = 0;
if (cls != CLSID_CArchiveHandler)
return -1;
- Byte id = CLS_ARC_ID_ITEM(*clsid);
+ const Byte id = CLS_ARC_ID_ITEM(*clsid);
for (unsigned i = 0; i < g_NumArcs; i++)
if (g_Arcs[i]->Id == id)
return (int)i;
return -1;
}
+STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject);
STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
{
COM_TRY_BEGIN
{
- int needIn = (*iid == IID_IInArchive);
- int needOut = (*iid == IID_IOutArchive);
+ const int needIn = (*iid == IID_IInArchive);
+ const int needOut = (*iid == IID_IOutArchive);
if (!needIn && !needOut)
return E_NOINTERFACE;
- int formatIndex = FindFormatCalssId(clsid);
+ const int formatIndex = FindFormatCalssId(clsid);
if (formatIndex < 0)
return CLASS_E_CLASSNOTAVAILABLE;
@@ -89,6 +91,7 @@ STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
return S_OK;
}
+STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value);
STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -113,6 +116,7 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
case NArchive::NHandlerPropID::kAltStreams: prop = ((arc.Flags & NArcInfoFlags::kAltStreams) != 0); break;
case NArchive::NHandlerPropID::kNtSecure: prop = ((arc.Flags & NArcInfoFlags::kNtSecure) != 0); break;
case NArchive::NHandlerPropID::kFlags: prop = (UInt32)arc.Flags; break;
+ case NArchive::NHandlerPropID::kTimeFlags: prop = (UInt32)arc.TimeFlags; break;
case NArchive::NHandlerPropID::kSignatureOffset: prop = (UInt32)arc.SignatureOffset; break;
// case NArchive::NHandlerPropID::kVersion: prop = (UInt32)MY_VER_MIX; break;
@@ -130,17 +134,20 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
COM_TRY_END
}
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value);
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
{
return GetHandlerProperty2(g_DefaultArcIndex, propID, value);
}
+STDAPI GetNumberOfFormats(UINT32 *numFormats);
STDAPI GetNumberOfFormats(UINT32 *numFormats)
{
*numFormats = g_NumArcs;
return S_OK;
}
+STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc);
STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc)
{
*isArc = NULL;
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp
index 41b5805c115..b6ddeb839c9 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp
@@ -6,7 +6,7 @@
#ifdef USE_MIXER_ST
-STDMETHODIMP CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 *processedSize))
{
UInt32 realProcessed = 0;
HRESULT result = S_OK;
@@ -21,7 +21,7 @@ STDMETHODIMP CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 *
}
-STDMETHODIMP COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *processedSize))
{
HRESULT result = S_OK;
if (_stream)
@@ -32,7 +32,7 @@ STDMETHODIMP COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *pr
return result;
}
-STDMETHODIMP COutStreamCalcSize::OutStreamFinish()
+Z7_COM7F_IMF(COutStreamCalcSize::OutStreamFinish())
{
HRESULT result = S_OK;
if (_stream)
@@ -60,6 +60,63 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
p[i] = false;
}
+
+HRESULT CCoder::CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const
+{
+ if (Coder)
+ {
+ if (PackSizePointers.IsEmpty() || !PackSizePointers[0])
+ return S_OK;
+ CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
+ Coder.QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize);
+ // if (!getInStreamProcessedSize) return E_FAIL;
+ if (getInStreamProcessedSize)
+ {
+ UInt64 processed;
+ RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed))
+ if (processed != (UInt64)(Int64)-1)
+ {
+ const UInt64 size = PackSizes[0];
+ if (processed < size && Finish)
+ dataAfterEnd_Error = true;
+ if (processed > size)
+ {
+ // InternalPackSizeError = true;
+ // return S_FALSE;
+ }
+ }
+ }
+ }
+ else if (Coder2)
+ {
+ CMyComPtr<ICompressGetInStreamProcessedSize2> getInStreamProcessedSize2;
+ Coder2.QueryInterface(IID_ICompressGetInStreamProcessedSize2, (void **)&getInStreamProcessedSize2);
+ if (getInStreamProcessedSize2)
+ FOR_VECTOR (i, PackSizePointers)
+ {
+ if (!PackSizePointers[i])
+ continue;
+ UInt64 processed;
+ RINOK(getInStreamProcessedSize2->GetInStreamProcessedSize2(i, &processed))
+ if (processed != (UInt64)(Int64)-1)
+ {
+ const UInt64 size = PackSizes[i];
+ if (processed < size && Finish)
+ dataAfterEnd_Error = true;
+ else if (processed > size)
+ {
+ // InternalPackSizeError = true;
+ // return S_FALSE;
+ }
+ }
+ }
+ }
+
+ return S_OK;
+}
+
+
+
class CBondsChecks
{
CBoolVector _coderUsed;
@@ -80,7 +137,7 @@ bool CBondsChecks::CheckCoder(unsigned coderIndex)
return false;
_coderUsed[coderIndex] = true;
- UInt32 start = BindInfo->Coder_to_Stream[coderIndex];
+ const UInt32 start = BindInfo->Coder_to_Stream[coderIndex];
for (unsigned i = 0; i < coder.NumStreams; i++)
{
@@ -89,10 +146,10 @@ bool CBondsChecks::CheckCoder(unsigned coderIndex)
if (BindInfo->IsStream_in_PackStreams(ind))
continue;
- int bond = BindInfo->FindBond_for_PackStream(ind);
+ const int bond = BindInfo->FindBond_for_PackStream(ind);
if (bond < 0)
return false;
- if (!CheckCoder(BindInfo->Bonds[bond].UnpackIndex))
+ if (!CheckCoder(BindInfo->Bonds[(unsigned)bond].UnpackIndex))
return false;
}
@@ -151,8 +208,10 @@ bool CBindInfo::CalcMapsAndCheck()
}
-void CCoder::SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes)
+void CCoder::SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
{
+ Finish = finish;
+
if (unpackSize)
{
UnpackSize = *unpackSize;
@@ -187,15 +246,15 @@ bool CMixer::Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex)
if (coderIndex == _bi.UnpackCoder)
return true;
- int bond = _bi.FindBond_for_UnpackStream(coderIndex);
+ const int bond = _bi.FindBond_for_UnpackStream(coderIndex);
if (bond < 0)
throw 20150213;
/*
UInt32 coderIndex, coderStreamIndex;
- _bi.GetCoder_for_Stream(_bi.Bonds[bond].PackIndex, coderIndex, coderStreamIndex);
+ _bi.GetCoder_for_Stream(_bi.Bonds[(unsigned)bond].PackIndex, coderIndex, coderStreamIndex);
*/
- UInt32 nextCoder = _bi.Stream_to_Coder[_bi.Bonds[bond].PackIndex];
+ const UInt32 nextCoder = _bi.Stream_to_Coder[_bi.Bonds[(unsigned)bond].PackIndex];
if (!IsFilter_Vector[nextCoder])
return false;
@@ -208,11 +267,11 @@ bool CMixer::Is_PackSize_Correct_for_Stream(UInt32 streamIndex)
if (_bi.IsStream_in_PackStreams(streamIndex))
return true;
- int bond = _bi.FindBond_for_PackStream(streamIndex);
+ const int bond = _bi.FindBond_for_PackStream(streamIndex);
if (bond < 0)
throw 20150213;
- UInt32 nextCoder = _bi.Bonds[bond].UnpackIndex;
+ const UInt32 nextCoder = _bi.Bonds[(unsigned)bond].UnpackIndex;
if (!IsFilter_Vector[nextCoder])
return false;
@@ -222,8 +281,8 @@ bool CMixer::Is_PackSize_Correct_for_Stream(UInt32 streamIndex)
bool CMixer::Is_PackSize_Correct_for_Coder(UInt32 coderIndex)
{
- UInt32 startIndex = _bi.Coder_to_Stream[coderIndex];
- UInt32 numStreams = _bi.Coders[coderIndex].NumStreams;
+ const UInt32 startIndex = _bi.Coder_to_Stream[coderIndex];
+ const UInt32 numStreams = _bi.Coders[coderIndex].NumStreams;
for (UInt32 i = 0; i < numStreams; i++)
if (!Is_PackSize_Correct_for_Stream(startIndex + i))
return false;
@@ -234,19 +293,19 @@ bool CMixer::IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex)
{
if (IsExternal_Vector[coderIndex])
return true;
- UInt32 startIndex = _bi.Coder_to_Stream[coderIndex];
- UInt32 numStreams = _bi.Coders[coderIndex].NumStreams;
+ const UInt32 startIndex = _bi.Coder_to_Stream[coderIndex];
+ const UInt32 numStreams = _bi.Coders[coderIndex].NumStreams;
for (UInt32 i = 0; i < numStreams; i++)
{
- UInt32 si = startIndex + i;
+ const UInt32 si = startIndex + i;
if (_bi.IsStream_in_PackStreams(si))
continue;
- int bond = _bi.FindBond_for_PackStream(si);
+ const int bond = _bi.FindBond_for_PackStream(si);
if (bond < 0)
throw 20150213;
- if (IsThere_ExternalCoder_in_PackTree(_bi.Bonds[bond].UnpackIndex))
+ if (IsThere_ExternalCoder_in_PackTree(_bi.Bonds[(unsigned)bond].UnpackIndex))
return true;
}
return false;
@@ -284,13 +343,11 @@ void CMixerST::AddCoder(const CCreatedCoder &cod)
{
IUnknown *unk = (cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2);
{
- CMyComPtr<ISequentialInStream> s;
- unk->QueryInterface(IID_ISequentialInStream, (void**)&s);
+ Z7_DECL_CMyComPtr_QI_FROM(ISequentialInStream, s, unk)
c2.CanRead = (s != NULL);
}
{
- CMyComPtr<ISequentialOutStream> s;
- unk->QueryInterface(IID_ISequentialOutStream, (void**)&s);
+ Z7_DECL_CMyComPtr_QI_FROM(ISequentialOutStream, s, unk)
c2.CanWrite = (s != NULL);
}
}
@@ -301,7 +358,7 @@ CCoder &CMixerST::GetCoder(unsigned index)
return _coders[index];
}
-void CMixerST::ReInit() {}
+HRESULT CMixerST::ReInit2() { return S_OK; }
HRESULT CMixerST::GetInStream2(
ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
@@ -323,8 +380,8 @@ HRESULT CMixerST::GetInStream2(
if (!seqInStream)
return E_NOTIMPL;
- UInt32 numInStreams = EncodeMode ? 1 : coder.NumStreams;
- UInt32 startIndex = EncodeMode ? coderIndex : _bi.Coder_to_Stream[coderIndex];
+ const UInt32 numInStreams = EncodeMode ? 1 : coder.NumStreams;
+ const UInt32 startIndex = EncodeMode ? coderIndex : _bi.Coder_to_Stream[coderIndex];
bool isSet = false;
@@ -335,8 +392,8 @@ HRESULT CMixerST::GetInStream2(
if (setStream)
{
CMyComPtr<ISequentialInStream> seqInStream2;
- RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + 0, &seqInStream2));
- RINOK(setStream->SetInStream(seqInStream2));
+ RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + 0, &seqInStream2))
+ RINOK(setStream->SetInStream(seqInStream2))
isSet = true;
}
}
@@ -351,8 +408,8 @@ HRESULT CMixerST::GetInStream2(
for (UInt32 i = 0; i < numInStreams; i++)
{
CMyComPtr<ISequentialInStream> seqInStream2;
- RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + i, &seqInStream2));
- RINOK(setStream2->SetInStream2(i, seqInStream2));
+ RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + i, &seqInStream2))
+ RINOK(setStream2->SetInStream2(i, seqInStream2))
}
}
@@ -385,18 +442,18 @@ HRESULT CMixerST::GetInStream(
}
}
- int bond = FindBond_for_Stream(
+ const int bond = FindBond_for_Stream(
true, // forInputStream
inStreamIndex);
if (bond < 0)
return E_INVALIDARG;
RINOK(GetInStream2(inStreams, /* inSizes, */
- _bi.Bonds[bond].Get_OutIndex(EncodeMode), &seqInStream));
+ _bi.Bonds[(unsigned)bond].Get_OutIndex(EncodeMode), &seqInStream))
while (_binderStreams.Size() <= (unsigned)bond)
_binderStreams.AddNew();
- CStBinderStream &bs = _binderStreams[bond];
+ CStBinderStream &bs = _binderStreams[(unsigned)bond];
if (bs.StreamRef || bs.InStreamSpec)
return E_NOTIMPL;
@@ -439,13 +496,13 @@ HRESULT CMixerST::GetOutStream(
}
}
- int bond = FindBond_for_Stream(
+ const int bond = FindBond_for_Stream(
false, // forInputStream
outStreamIndex);
if (bond < 0)
return E_INVALIDARG;
- UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode);
+ const UInt32 inStreamIndex = _bi.Bonds[(unsigned)bond].Get_InIndex(EncodeMode);
UInt32 coderIndex = inStreamIndex;
UInt32 coderStreamIndex = 0;
@@ -464,8 +521,8 @@ HRESULT CMixerST::GetOutStream(
if (!seqOutStream)
return E_NOTIMPL;
- UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1;
- UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex;
+ const UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1;
+ const UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex;
bool isSet = false;
@@ -476,8 +533,8 @@ HRESULT CMixerST::GetOutStream(
if (setOutStream)
{
CMyComPtr<ISequentialOutStream> seqOutStream2;
- RINOK(GetOutStream(outStreams, /* outSizes, */ startIndex + 0, &seqOutStream2));
- RINOK(setOutStream->SetOutStream(seqOutStream2));
+ RINOK(GetOutStream(outStreams, /* outSizes, */ startIndex + 0, &seqOutStream2))
+ RINOK(setOutStream->SetOutStream(seqOutStream2))
isSet = true;
}
}
@@ -493,15 +550,15 @@ HRESULT CMixerST::GetOutStream(
for (UInt32 i = 0; i < numOutStreams; i++)
{
CMyComPtr<ISequentialOutStream> seqOutStream2;
- RINOK(GetOutStream(outStreams, startIndex + i, &seqOutStream2));
- RINOK(setStream2->SetOutStream2(i, seqOutStream2));
+ RINOK(GetOutStream(outStreams, startIndex + i, &seqOutStream2))
+ RINOK(setStream2->SetOutStream2(i, seqOutStream2))
}
*/
}
while (_binderStreams.Size() <= (unsigned)bond)
_binderStreams.AddNew();
- CStBinderStream &bs = _binderStreams[bond];
+ CStBinderStream &bs = _binderStreams[(unsigned)bond];
if (bs.StreamRef || bs.OutStreamSpec)
return E_NOTIMPL;
@@ -551,13 +608,13 @@ HRESULT CMixerST::FinishStream(UInt32 streamIndex)
return S_OK;
}
- int bond = FindBond_for_Stream(
+ const int bond = FindBond_for_Stream(
false, // forInputStream
streamIndex);
if (bond < 0)
return E_INVALIDARG;
- UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode);
+ const UInt32 inStreamIndex = _bi.Bonds[(unsigned)bond].Get_InIndex(EncodeMode);
UInt32 coderIndex = inStreamIndex;
UInt32 coderStreamIndex = 0;
@@ -580,8 +637,8 @@ HRESULT CMixerST::FinishCoder(UInt32 coderIndex)
{
CCoder &coder = _coders[coderIndex];
- UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1;
- UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex;
+ const UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1;
+ const UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex;
HRESULT res = S_OK;
for (unsigned i = 0; i < numOutStreams; i++)
@@ -595,7 +652,7 @@ void CMixerST::SelectMainCoder(bool useFirst)
unsigned ci = _bi.UnpackCoder;
int firstNonFilter = -1;
- int firstAllowed = ci;
+ unsigned firstAllowed = ci;
for (;;)
{
@@ -612,10 +669,10 @@ void CMixerST::SelectMainCoder(bool useFirst)
if (coder.NumStreams != 1)
break;
- UInt32 st = _bi.Coder_to_Stream[ci];
+ const UInt32 st = _bi.Coder_to_Stream[ci];
if (_bi.IsStream_in_PackStreams(st))
break;
- int bond = _bi.FindBond_for_PackStream(st);
+ const int bond = _bi.FindBond_for_PackStream(st);
if (bond < 0)
throw 20150213;
@@ -623,15 +680,15 @@ void CMixerST::SelectMainCoder(bool useFirst)
break;
if (firstNonFilter == -1 && !IsFilter_Vector[ci])
- firstNonFilter = ci;
+ firstNonFilter = (int)ci;
- ci = _bi.Bonds[bond].UnpackIndex;
+ ci = _bi.Bonds[(unsigned)bond].UnpackIndex;
}
if (useFirst)
ci = firstAllowed;
else if (firstNonFilter >= 0)
- ci = firstNonFilter;
+ ci = (unsigned)firstNonFilter;
MainCoderIndex = ci;
}
@@ -640,35 +697,39 @@ void CMixerST::SelectMainCoder(bool useFirst)
HRESULT CMixerST::Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
- ICompressProgressInfo *progress)
+ ICompressProgressInfo *progress,
+ bool &dataAfterEnd_Error)
{
+ // InternalPackSizeError = false;
+ dataAfterEnd_Error = false;
+
_binderStreams.Clear();
- unsigned ci = MainCoderIndex;
+ const unsigned ci = MainCoderIndex;
const CCoder &mainCoder = _coders[MainCoderIndex];
CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
- UInt32 numInStreams = EncodeMode ? 1 : mainCoder.NumStreams;
- UInt32 numOutStreams = !EncodeMode ? 1 : mainCoder.NumStreams;
+ const UInt32 numInStreams = EncodeMode ? 1 : mainCoder.NumStreams;
+ const UInt32 numOutStreams = !EncodeMode ? 1 : mainCoder.NumStreams;
- UInt32 startInIndex = EncodeMode ? ci : _bi.Coder_to_Stream[ci];
- UInt32 startOutIndex = !EncodeMode ? ci : _bi.Coder_to_Stream[ci];
+ const UInt32 startInIndex = EncodeMode ? ci : _bi.Coder_to_Stream[ci];
+ const UInt32 startOutIndex = !EncodeMode ? ci : _bi.Coder_to_Stream[ci];
UInt32 i;
for (i = 0; i < numInStreams; i++)
{
CMyComPtr<ISequentialInStream> seqInStream;
- RINOK(GetInStream(inStreams, /* inSizes, */ startInIndex + i, &seqInStream));
+ RINOK(GetInStream(inStreams, /* inSizes, */ startInIndex + i, &seqInStream))
seqInStreams.Add(seqInStream);
}
for (i = 0; i < numOutStreams; i++)
{
CMyComPtr<ISequentialOutStream> seqOutStream;
- RINOK(GetOutStream(outStreams, /* outSizes, */ startOutIndex + i, &seqOutStream));
+ RINOK(GetOutStream(outStreams, /* outSizes, */ startOutIndex + i, &seqOutStream))
seqOutStreams.Add(seqOutStream);
}
@@ -692,15 +753,19 @@ HRESULT CMixerST::Code(
CMyComPtr<ICompressInitEncoder> initEncoder;
coder.QueryInterface(IID_ICompressInitEncoder, (void **)&initEncoder);
if (initEncoder)
- RINOK(initEncoder->InitEncoder());
+ {
+ RINOK(initEncoder->InitEncoder())
+ }
}
else
{
CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize);
if (setOutStreamSize)
+ {
RINOK(setOutStreamSize->SetOutStreamSize(
- EncodeMode ? coder.PackSizePointers[0] : coder.UnpackSizePointer));
+ EncodeMode ? coder.PackSizePointers[0] : coder.UnpackSizePointer))
+ }
}
}
@@ -742,7 +807,16 @@ HRESULT CMixerST::Code(
if (res == k_My_HRESULT_WritingWasCut)
res = S_OK;
- return res;
+
+ if (res != S_OK)
+ return res;
+
+ for (i = 0; i < _coders.Size(); i++)
+ {
+ RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /*, InternalPackSizeError */))
+ }
+
+ return S_OK;
}
@@ -762,7 +836,7 @@ HRESULT CMixerST::GetMainUnpackStream(
coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize);
if (setOutStreamSize)
{
- RINOK(setOutStreamSize->SetOutStreamSize(coder.UnpackSizePointer));
+ RINOK(setOutStreamSize->SetOutStreamSize(coder.UnpackSizePointer))
}
}
@@ -847,7 +921,8 @@ HRESULT CMixerMT::SetBindInfo(const CBindInfo &bindInfo)
_streamBinders.Clear();
FOR_VECTOR (i, _bi.Bonds)
{
- RINOK(_streamBinders.AddNew().CreateEvents());
+ // RINOK(_streamBinders.AddNew().CreateEvents())
+ _streamBinders.AddNew();
}
return S_OK;
}
@@ -869,10 +944,13 @@ CCoder &CMixerMT::GetCoder(unsigned index)
return _coders[index];
}
-void CMixerMT::ReInit()
+HRESULT CMixerMT::ReInit2()
{
FOR_VECTOR (i, _streamBinders)
- _streamBinders[i].ReInit();
+ {
+ RINOK(_streamBinders[i].Create_ReInit())
+ }
+ return S_OK;
}
void CMixerMT::SelectMainCoder(bool useFirst)
@@ -890,10 +968,10 @@ void CMixerMT::SelectMainCoder(bool useFirst)
UInt32 st = _bi.Coder_to_Stream[ci];
if (_bi.IsStream_in_PackStreams(st))
break;
- int bond = _bi.FindBond_for_PackStream(st);
+ const int bond = _bi.FindBond_for_PackStream(st);
if (bond < 0)
throw 20150213;
- ci = _bi.Bonds[bond].UnpackIndex;
+ ci = _bi.Bonds[(unsigned)bond].UnpackIndex;
}
MainCoderIndex = ci;
@@ -910,8 +988,8 @@ HRESULT CMixerMT::Init(ISequentialInStream * const *inStreams, ISequentialOutStr
UInt32 j;
- unsigned numInStreams = EncodeMode ? 1 : csi.NumStreams;
- unsigned numOutStreams = EncodeMode ? csi.NumStreams : 1;
+ const unsigned numInStreams = EncodeMode ? 1 : csi.NumStreams;
+ const unsigned numOutStreams = EncodeMode ? csi.NumStreams : 1;
coderInfo.InStreams.Clear();
for (j = 0; j < numInStreams; j++)
@@ -940,9 +1018,9 @@ HRESULT CMixerMT::Init(ISequentialInStream * const *inStreams, ISequentialOutStr
outCoderStreamIndex = EncodeMode ? coderStreamIndex : 0;
}
- _streamBinders[i].CreateStreams(
- &_coders[inCoderIndex].InStreams[inCoderStreamIndex],
- &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
+ _streamBinders[i].CreateStreams2(
+ _coders[inCoderIndex].InStreams[inCoderStreamIndex],
+ _coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
CMyComPtr<ICompressSetBufSize> inSetSize, outSetSize;
_coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize);
@@ -988,29 +1066,46 @@ HRESULT CMixerMT::ReturnIfError(HRESULT code)
HRESULT CMixerMT::Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
- ICompressProgressInfo *progress)
+ ICompressProgressInfo *progress,
+ bool &dataAfterEnd_Error)
{
+ // InternalPackSizeError = false;
+ dataAfterEnd_Error = false;
+
Init(inStreams, outStreams);
unsigned i;
for (i = 0; i < _coders.Size(); i++)
if (i != MainCoderIndex)
{
- RINOK(_coders[i].Create());
+ const WRes wres = _coders[i].Create();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
}
for (i = 0; i < _coders.Size(); i++)
if (i != MainCoderIndex)
- _coders[i].Start();
+ {
+ const WRes wres = _coders[i].Start();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+ }
_coders[MainCoderIndex].Code(progress);
+ WRes wres = 0;
for (i = 0; i < _coders.Size(); i++)
if (i != MainCoderIndex)
- _coders[i].WaitExecuteFinish();
+ {
+ WRes wres2 = _coders[i].WaitExecuteFinish();
+ if (wres == 0)
+ wres = wres2;
+ }
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
- RINOK(ReturnIfError(E_ABORT));
- RINOK(ReturnIfError(E_OUTOFMEMORY));
+ RINOK(ReturnIfError(E_ABORT))
+ RINOK(ReturnIfError(E_OUTOFMEMORY))
for (i = 0; i < _coders.Size(); i++)
{
@@ -1022,7 +1117,7 @@ HRESULT CMixerMT::Code(
return result;
}
- RINOK(ReturnIfError(S_FALSE));
+ RINOK(ReturnIfError(S_FALSE))
for (i = 0; i < _coders.Size(); i++)
{
@@ -1031,6 +1126,11 @@ HRESULT CMixerMT::Code(
return result;
}
+ for (i = 0; i < _coders.Size(); i++)
+ {
+ RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /* , InternalPackSizeError */))
+ }
+
return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h
index e63f2ff0efa..484a6089ad4 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h
@@ -1,7 +1,7 @@
// CoderMixer2.h
-#ifndef __CODER_MIXER2_H
-#define __CODER_MIXER2_H
+#ifndef ZIP7_INC_CODER_MIXER2_H
+#define ZIP7_INC_CODER_MIXER2_H
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
@@ -10,11 +10,11 @@
#include "../../Common/CreateCoder.h"
-#ifdef _7ZIP_ST
+#ifdef Z7_ST
#define USE_MIXER_ST
#else
#define USE_MIXER_MT
- #ifndef _SFX
+ #ifndef Z7_SFX
#define USE_MIXER_ST
#endif
#endif
@@ -28,18 +28,13 @@
#ifdef USE_MIXER_ST
-class CSequentialInStreamCalcSize:
- public ISequentialInStream,
- public CMyUnknownImp
-{
-public:
- MY_UNKNOWN_IMP1(ISequentialInStream)
-
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
-private:
+Z7_CLASS_IMP_COM_1(
+ CSequentialInStreamCalcSize
+ , ISequentialInStream
+)
+ bool _wasFinished;
CMyComPtr<ISequentialInStream> _stream;
UInt64 _size;
- bool _wasFinished;
public:
void SetStream(ISequentialInStream *stream) { _stream = stream; }
void Init()
@@ -53,19 +48,14 @@ public:
};
-class COutStreamCalcSize:
- public ISequentialOutStream,
- public IOutStreamFinish,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_COM_2(
+ COutStreamCalcSize
+ , ISequentialOutStream
+ , IOutStreamFinish
+)
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
public:
- MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStreamFinish)
-
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(OutStreamFinish)();
-
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
void Init() { _size = 0; }
@@ -107,7 +97,7 @@ struct CBindInfo
{
FOR_VECTOR (i, Bonds)
if (Bonds[i].PackIndex == packStream)
- return i;
+ return (int)i;
return -1;
}
@@ -115,14 +105,14 @@ struct CBindInfo
{
FOR_VECTOR (i, Bonds)
if (Bonds[i].UnpackIndex == unpackStream)
- return i;
+ return (int)i;
return -1;
}
bool SetUnpackCoder()
{
bool isOk = false;
- FOR_VECTOR(i, Coders)
+ FOR_VECTOR (i, Coders)
{
if (FindBond_for_UnpackStream(i) < 0)
{
@@ -142,9 +132,9 @@ struct CBindInfo
int FindStream_in_PackStreams(UInt32 streamIndex) const
{
- FOR_VECTOR(i, PackStreams)
+ FOR_VECTOR (i, PackStreams)
if (PackStreams[i] == streamIndex)
- return i;
+ return (int)i;
return -1;
}
@@ -189,11 +179,12 @@ struct CBindInfo
class CCoder
{
- CLASS_NO_COPY(CCoder);
+ Z7_CLASS_NO_COPY(CCoder)
public:
CMyComPtr<ICompressCoder> Coder;
CMyComPtr<ICompressCoder2> Coder2;
UInt32 NumStreams;
+ bool Finish;
UInt64 UnpackSize;
const UInt64 *UnpackSizePointer;
@@ -201,9 +192,11 @@ public:
CRecordVector<UInt64> PackSizes;
CRecordVector<const UInt64 *> PackSizePointers;
- CCoder() {}
+ CCoder(): Finish(false) {}
+
+ void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish);
- void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes);
+ HRESULT CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const;
IUnknown *GetUnknown() const
{
@@ -239,11 +232,15 @@ protected:
public:
unsigned MainCoderIndex;
+ // bool InternalPackSizeError;
+
CMixer(bool encodeMode):
EncodeMode(encodeMode),
MainCoderIndex(0)
+ // , InternalPackSizeError(false)
{}
+ virtual ~CMixer() {}
/*
Sequence of calling:
@@ -272,12 +269,13 @@ public:
virtual void AddCoder(const CCreatedCoder &cod) = 0;
virtual CCoder &GetCoder(unsigned index) = 0;
virtual void SelectMainCoder(bool useFirst) = 0;
- virtual void ReInit() = 0;
- virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes) = 0;
+ virtual HRESULT ReInit2() = 0;
+ virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) = 0;
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
- ICompressProgressInfo *progress) = 0;
+ ICompressProgressInfo *progress,
+ bool &dataAfterEnd_Error) = 0;
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const = 0;
bool Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex);
@@ -314,6 +312,9 @@ class CMixerST:
public CMixer,
public CMyUnknownImp
{
+ Z7_COM_UNKNOWN_IMP_0
+ Z7_CLASS_NO_COPY(CMixerST)
+
HRESULT GetInStream2(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
UInt32 outStreamIndex, ISequentialInStream **inStreamRes);
HRESULT GetInStream(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
@@ -329,22 +330,21 @@ public:
CObjectVector<CStBinderStream> _binderStreams;
- MY_UNKNOWN_IMP
-
CMixerST(bool encodeMode);
- ~CMixerST();
-
- virtual void AddCoder(const CCreatedCoder &cod);
- virtual CCoder &GetCoder(unsigned index);
- virtual void SelectMainCoder(bool useFirst);
- virtual void ReInit();
- virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes)
- { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); }
+ ~CMixerST() Z7_DESTRUCTOR_override;
+
+ virtual void AddCoder(const CCreatedCoder &cod) Z7_override;
+ virtual CCoder &GetCoder(unsigned index) Z7_override;
+ virtual void SelectMainCoder(bool useFirst) Z7_override;
+ virtual HRESULT ReInit2() Z7_override;
+ virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) Z7_override
+ { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
- ICompressProgressInfo *progress);
- virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
+ ICompressProgressInfo *progress,
+ bool &dataAfterEnd_Error) Z7_override;
+ virtual UInt64 GetBondStreamSize(unsigned bondIndex) const Z7_override;
HRESULT GetMainUnpackStream(
ISequentialInStream * const *inStreams,
@@ -360,12 +360,12 @@ public:
class CCoderMT: public CCoder, public CVirtThread
{
- CLASS_NO_COPY(CCoderMT)
+ Z7_CLASS_NO_COPY(CCoderMT)
CRecordVector<ISequentialInStream*> InStreamPointers;
CRecordVector<ISequentialOutStream*> OutStreamPointers;
private:
- void Execute();
+ virtual void Execute() Z7_override;
public:
bool EncodeMode;
HRESULT Result;
@@ -385,7 +385,7 @@ public:
class CReleaser
{
- CLASS_NO_COPY(CReleaser)
+ Z7_CLASS_NO_COPY(CReleaser)
CCoderMT &_c;
public:
CReleaser(CCoderMT &c): _c(c) {}
@@ -393,7 +393,14 @@ public:
};
CCoderMT(): EncodeMode(false) {}
- ~CCoderMT() { CVirtThread::WaitThreadFinish(); }
+ ~CCoderMT() Z7_DESTRUCTOR_override
+ {
+ /* WaitThreadFinish() will be called in ~CVirtThread().
+ But we need WaitThreadFinish() call before CCoder destructor,
+ and before destructors of this class members.
+ */
+ CVirtThread::WaitThreadFinish();
+ }
void Code(ICompressProgressInfo *progress);
};
@@ -404,28 +411,31 @@ class CMixerMT:
public CMixer,
public CMyUnknownImp
{
+ Z7_COM_UNKNOWN_IMP_0
+ Z7_CLASS_NO_COPY(CMixerMT)
+
CObjectVector<CStreamBinder> _streamBinders;
HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams);
HRESULT ReturnIfError(HRESULT code);
+ // virtual ~CMixerMT() {}
public:
CObjectVector<CCoderMT> _coders;
- MY_UNKNOWN_IMP
-
- virtual HRESULT SetBindInfo(const CBindInfo &bindInfo);
- virtual void AddCoder(const CCreatedCoder &cod);
- virtual CCoder &GetCoder(unsigned index);
- virtual void SelectMainCoder(bool useFirst);
- virtual void ReInit();
- virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes)
- { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); }
+ virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) Z7_override;
+ virtual void AddCoder(const CCreatedCoder &cod) Z7_override;
+ virtual CCoder &GetCoder(unsigned index) Z7_override;
+ virtual void SelectMainCoder(bool useFirst) Z7_override;
+ virtual HRESULT ReInit2() Z7_override;
+ virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) Z7_override
+ { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
- ICompressProgressInfo *progress);
- virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
+ ICompressProgressInfo *progress,
+ bool &dataAfterEnd_Error) Z7_override;
+ virtual UInt64 GetBondStreamSize(unsigned bondIndex) const Z7_override;
CMixerMT(bool encodeMode): CMixer(encodeMode) {}
};
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp
index 7c4f54879de..f48c32f2fd7 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp
@@ -4,7 +4,7 @@
#include "DummyOutStream.h"
-STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
{
UInt32 realProcessedSize = size;
HRESULT res = S_OK;
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h b/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h
index b5a51fc0755..f884e13c872 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h
@@ -1,24 +1,22 @@
// DummyOutStream.h
-#ifndef __DUMMY_OUT_STREAM_H
-#define __DUMMY_OUT_STREAM_H
+#ifndef ZIP7_INC_DUMMY_OUT_STREAM_H
+#define ZIP7_INC_DUMMY_OUT_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
-class CDummyOutStream:
- public ISequentialOutStream,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_NOQIB_1(
+ CDummyOutStream
+ , ISequentialOutStream
+)
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
public:
void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }
void ReleaseStream() { _stream.Release(); }
void Init() { _size = 0; }
- MY_UNKNOWN_IMP
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
UInt64 GetSize() const { return _size; }
};
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp
index 30ca73bd023..17fed675b5d 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp
@@ -2,54 +2,175 @@
#include "StdAfx.h"
-#ifndef _7ZIP_ST
-#include "../../../Windows/System.h"
-#endif
+#include "../../../Common/StringToInt.h"
#include "../Common/ParseProperties.h"
#include "HandlerOut.h"
-using namespace NWindows;
-
namespace NArchive {
-static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
+bool ParseSizeString(const wchar_t *s, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res)
+{
+ if (*s == 0)
+ {
+ switch (prop.vt)
+ {
+ case VT_UI4: res = prop.ulVal; return true;
+ case VT_UI8: res = prop.uhVal.QuadPart; return true;
+ case VT_BSTR:
+ s = prop.bstrVal;
+ break;
+ default: return false;
+ }
+ }
+ else if (prop.vt != VT_EMPTY)
+ return false;
+
+ bool percentMode = false;
+ {
+ const wchar_t c = *s;
+ if (MyCharLower_Ascii(c) == 'p')
+ {
+ percentMode = true;
+ s++;
+ }
+ }
+
+ const wchar_t *end;
+ const UInt64 v = ConvertStringToUInt64(s, &end);
+ if (s == end)
+ return false;
+ const wchar_t c = *end;
+
+ if (percentMode)
+ {
+ if (c != 0)
+ return false;
+ res = Calc_From_Val_Percents(percentsBase, v);
+ return true;
+ }
+
+ if (c == 0)
+ {
+ res = v;
+ return true;
+ }
+ if (end[1] != 0)
+ return false;
+
+ if (c == '%')
+ {
+ res = Calc_From_Val_Percents(percentsBase, v);
+ return true;
+ }
+
+ unsigned numBits;
+ switch (MyCharLower_Ascii(c))
+ {
+ case 'b': numBits = 0; break;
+ case 'k': numBits = 10; break;
+ case 'm': numBits = 20; break;
+ case 'g': numBits = 30; break;
+ case 't': numBits = 40; break;
+ default: return false;
+ }
+ const UInt64 val2 = v << numBits;
+ if ((val2 >> numBits) != v)
+ return false;
+ res = val2;
+ return true;
+}
+
+bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres)
+{
+ hres = S_OK;
+
+ if (name.IsPrefixedBy_Ascii_NoCase("mt"))
+ {
+ #ifndef Z7_ST
+ _numThreads = _numProcessors;
+ _numThreads_WasForced = false;
+ hres = ParseMtProp2(name.Ptr(2), value, _numThreads, _numThreads_WasForced);
+ // "mt" means "_numThreads_WasForced = false" here
+ #endif
+ return true;
+ }
+
+ if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
+ {
+ UInt64 v;
+ if (!ParseSizeString(name.Ptr(6), value, _memAvail, v))
+ hres = E_INVALIDARG;
+ _memUsage_Decompress = v;
+ _memUsage_Compress = v;
+ _memUsage_WasSet = true;
+ return true;
+ }
+
+ return false;
+}
+
+
+#ifndef Z7_EXTRACT_ONLY
+
+static void SetMethodProp32(CMethodProps &m, PROPID propID, UInt32 value)
{
if (m.FindProp(propID) < 0)
m.AddProp32(propID, value);
}
-void CMultiMethodProps::SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
- #ifndef _7ZIP_ST
- , UInt32 numThreads
- #endif
- )
+void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
{
UInt32 level = _level;
if (level != (UInt32)(Int32)-1)
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
-
- #ifndef _7ZIP_ST
+}
+
+#ifndef Z7_ST
+
+static void SetMethodProp32_Replace(CMethodProps &m, PROPID propID, UInt32 value)
+{
+ const int i = m.FindProp(propID);
+ if (i >= 0)
+ {
+ NWindows::NCOM::CPropVariant &val = m.Props[(unsigned)i].Value;
+ val = (UInt32)value;
+ return;
+ }
+ m.AddProp32(propID, value);
+}
+
+void CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(CMethodProps &oneMethodInfo, UInt32 numThreads)
+{
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
- #endif
}
-void CMultiMethodProps::Init()
+void CMultiMethodProps::SetMethodThreadsTo_Replace(CMethodProps &oneMethodInfo, UInt32 numThreads)
+{
+ SetMethodProp32_Replace(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
+}
+
+#endif // Z7_ST
+
+
+void CMultiMethodProps::InitMulti()
{
- #ifndef _7ZIP_ST
- _numProcessors = _numThreads = NSystem::GetNumberOfProcessors();
- #endif
-
_level = (UInt32)(Int32)-1;
_analysisLevel = -1;
-
- _autoFilter = true;
_crcSize = 4;
- _filterMethod.Clear();
+ _autoFilter = true;
+}
+
+void CMultiMethodProps::Init()
+{
+ InitCommon();
+ InitMulti();
_methods.Clear();
+ _filterMethod.Clear();
}
+
HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
UString name = nameSpec;
@@ -68,34 +189,32 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
{
name.Delete(0, 2);
UInt32 v = 9;
- RINOK(ParsePropToUInt32(name, value, v));
+ RINOK(ParsePropToUInt32(name, value, v))
_analysisLevel = (int)v;
return S_OK;
}
- if (name.IsEqualTo("crc"))
+ if (name.IsPrefixedBy_Ascii_NoCase("crc"))
{
name.Delete(0, 3);
_crcSize = 4;
return ParsePropToUInt32(name, value, _crcSize);
}
+
+ {
+ HRESULT hres;
+ if (SetCommonProperty(name, value, hres))
+ return hres;
+ }
UInt32 number;
- unsigned index = ParseStringToUInt32(name, number);
- UString realName = name.Ptr(index);
+ const unsigned index = ParseStringToUInt32(name, number);
+ const UString realName = name.Ptr(index);
if (index == 0)
{
- if (name.IsPrefixedBy_Ascii_NoCase("mt"))
- {
- #ifndef _7ZIP_ST
- RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads));
- #endif
-
- return S_OK;
- }
if (name.IsEqualTo("f"))
{
- HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
+ const HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
if (res == S_OK)
return res;
if (value.vt != VT_BSTR)
@@ -105,52 +224,87 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
number = 0;
}
if (number > 64)
- return E_FAIL;
- for (int j = _methods.Size(); j <= (int)number; j++)
- _methods.Add(COneMethodInfo());
+ return E_INVALIDARG;
+ for (unsigned j = _methods.Size(); j <= number; j++)
+ _methods.AddNew();
return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
}
+
+
void CSingleMethodProps::Init()
{
+ InitCommon();
+ InitSingle();
Clear();
- _level = (UInt32)(Int32)-1;
-
- #ifndef _7ZIP_ST
- _numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
- AddProp_NumThreads(_numThreads);
- #endif
}
+
+HRESULT CSingleMethodProps::SetProperty(const wchar_t *name2, const PROPVARIANT &value)
+{
+ // processed = false;
+ UString name = name2;
+ name.MakeLower_Ascii();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+ if (name.IsPrefixedBy_Ascii_NoCase("x"))
+ {
+ UInt32 a = 9;
+ RINOK(ParsePropToUInt32(name.Ptr(1), value, a))
+ _level = a;
+ AddProp_Level(a);
+ // processed = true;
+ return S_OK;
+ }
+ {
+ HRESULT hres;
+ if (SetCommonProperty(name, value, hres))
+ {
+ // processed = true;
+ return S_OK;
+ }
+ }
+ RINOK(ParseMethodFromPROPVARIANT(name, value))
+ return S_OK;
+}
+
+
HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
Init();
+
for (UInt32 i = 0; i < numProps; i++)
{
- UString name = names[i];
- name.MakeLower_Ascii();
- if (name.IsEmpty())
- return E_INVALIDARG;
- const PROPVARIANT &value = values[i];
- if (name[0] == L'x')
- {
- UInt32 a = 9;
- RINOK(ParsePropToUInt32(name.Ptr(1), value, a));
- _level = a;
- AddProp_Level(a);
- }
- else if (name.IsPrefixedBy_Ascii_NoCase("mt"))
- {
- #ifndef _7ZIP_ST
- RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads));
- AddProp_NumThreads(_numThreads);
- #endif
- }
- else
- {
- RINOK(ParseMethodFromPROPVARIANT(names[i], value));
- }
+ RINOK(SetProperty(names[i], values[i]))
+ }
+
+ return S_OK;
+}
+
+#endif
+
+
+static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest)
+{
+ RINOK(PROPVARIANT_to_bool(prop, dest.Val))
+ dest.Def = true;
+ return S_OK;
+}
+
+HRESULT CHandlerTimeOptions::Parse(const UString &name, const PROPVARIANT &prop, bool &processed)
+{
+ processed = true;
+ if (name.IsEqualTo_Ascii_NoCase("tm")) { return PROPVARIANT_to_BoolPair(prop, Write_MTime); }
+ if (name.IsEqualTo_Ascii_NoCase("ta")) { return PROPVARIANT_to_BoolPair(prop, Write_ATime); }
+ if (name.IsEqualTo_Ascii_NoCase("tc")) { return PROPVARIANT_to_BoolPair(prop, Write_CTime); }
+ if (name.IsPrefixedBy_Ascii_NoCase("tp"))
+ {
+ UInt32 v = 0;
+ RINOK(ParsePropToUInt32(name.Ptr(2), prop, v))
+ Prec = v;
+ return S_OK;
}
+ processed = false;
return S_OK;
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h b/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h
index 5a18d9802b3..cfba46e245b 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h
@@ -1,32 +1,90 @@
// HandlerOut.h
-#ifndef __HANDLER_OUT_H
-#define __HANDLER_OUT_H
+#ifndef ZIP7_INC_HANDLER_OUT_H
+#define ZIP7_INC_HANDLER_OUT_H
+
+#include "../../../Windows/System.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
-class CMultiMethodProps
+bool ParseSizeString(const wchar_t *name, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res);
+
+class CCommonMethodProps
{
- UInt32 _level;
- int _analysisLevel;
+protected:
+ void InitCommon()
+ {
+ // _Write_MTime = true;
+ #ifndef Z7_ST
+ _numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+ _numThreads_WasForced = false;
+ #endif
+
+ UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28;
+ _memAvail = memAvail;
+ _memUsage_Compress = memAvail;
+ _memUsage_Decompress = memAvail;
+ _memUsage_WasSet = NWindows::NSystem::GetRamSize(memAvail);
+ if (_memUsage_WasSet)
+ {
+ _memAvail = memAvail;
+ unsigned bits = sizeof(size_t) * 8;
+ if (bits == 32)
+ {
+ const UInt32 limit2 = (UInt32)7 << 28;
+ if (memAvail > limit2)
+ memAvail = limit2;
+ }
+ // 80% - is auto usage limit in handlers
+ // _memUsage_Compress = memAvail * 4 / 5;
+ // _memUsage_Compress = Calc_From_Val_Percents(memAvail, 80);
+ _memUsage_Compress = Calc_From_Val_Percents_Less100(memAvail, 80);
+ _memUsage_Decompress = memAvail / 32 * 17;
+ }
+ }
+
public:
- #ifndef _7ZIP_ST
+ #ifndef Z7_ST
UInt32 _numThreads;
UInt32 _numProcessors;
+ bool _numThreads_WasForced;
#endif
+ bool _memUsage_WasSet;
+ UInt64 _memUsage_Compress;
+ UInt64 _memUsage_Decompress;
+ UInt64 _memAvail;
+
+ bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres);
+
+ CCommonMethodProps() { InitCommon(); }
+};
+
+
+#ifndef Z7_EXTRACT_ONLY
+
+class CMultiMethodProps: public CCommonMethodProps
+{
+ UInt32 _level;
+ int _analysisLevel;
+
+ void InitMulti();
+public:
UInt32 _crcSize;
CObjectVector<COneMethodInfo> _methods;
COneMethodInfo _filterMethod;
bool _autoFilter;
- void SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
- #ifndef _7ZIP_ST
- , UInt32 numThreads
- #endif
- );
+
+ void SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const;
+
+ #ifndef Z7_ST
+ static void SetMethodThreadsTo_IfNotFinded(CMethodProps &props, UInt32 numThreads);
+ static void SetMethodThreadsTo_Replace(CMethodProps &props, UInt32 numThreads);
+ #endif
+
unsigned GetNumEmptyMethods() const
{
@@ -41,27 +99,56 @@ public:
int GetAnalysisLevel() const { return _analysisLevel; }
void Init();
+ CMultiMethodProps() { InitMulti(); }
- CMultiMethodProps() { Init(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
-class CSingleMethodProps: public COneMethodInfo
+
+class CSingleMethodProps: public COneMethodInfo, public CCommonMethodProps
{
UInt32 _level;
-
-public:
- #ifndef _7ZIP_ST
- UInt32 _numThreads;
- UInt32 _numProcessors;
- #endif
+ void InitSingle()
+ {
+ _level = (UInt32)(Int32)-1;
+ }
+
+public:
void Init();
- CSingleMethodProps() { Init(); }
+ CSingleMethodProps() { InitSingle(); }
+
int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; }
+ HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &values);
HRESULT SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
};
+#endif
+
+struct CHandlerTimeOptions
+{
+ CBoolPair Write_MTime;
+ CBoolPair Write_ATime;
+ CBoolPair Write_CTime;
+ UInt32 Prec;
+
+ void Init()
+ {
+ Write_MTime.Init();
+ Write_MTime.Val = true;
+ Write_ATime.Init();
+ Write_CTime.Init();
+ Prec = (UInt32)(Int32)-1;
+ }
+
+ CHandlerTimeOptions()
+ {
+ Init();
+ }
+
+ HRESULT Parse(const UString &name, const PROPVARIANT &prop, bool &processed);
+};
+
}
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
index a2d68832838..735d5d1eb0e 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
@@ -4,22 +4,33 @@
#include "InStreamWithCRC.h"
-STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize))
{
UInt32 realProcessed = 0;
HRESULT result = S_OK;
- if (_stream)
- result = _stream->Read(data, size, &realProcessed);
- _size += realProcessed;
- if (size != 0 && realProcessed == 0)
- _wasFinished = true;
- _crc = CrcUpdate(_crc, data, realProcessed);
+ if (size != 0)
+ {
+ if (_stream)
+ result = _stream->Read(data, size, &realProcessed);
+ _size += realProcessed;
+ if (realProcessed == 0)
+ _wasFinished = true;
+ else
+ _crc = CrcUpdate(_crc, data, realProcessed);
+ }
if (processedSize)
*processedSize = realProcessed;
return result;
}
-STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CSequentialInStreamWithCRC::GetSize(UInt64 *size))
+{
+ *size = _fullSize;
+ return S_OK;
+}
+
+
+Z7_COM7F_IMF(CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize))
{
UInt32 realProcessed = 0;
HRESULT result = S_OK;
@@ -36,7 +47,7 @@ STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSi
return result;
}
-STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+Z7_COM7F_IMF(CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
{
if (seekOrigin != STREAM_SEEK_SET || offset != 0)
return E_FAIL;
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h b/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h
index 31b761e4566..2a91d76742a 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h
@@ -1,7 +1,7 @@
// InStreamWithCRC.h
-#ifndef __IN_STREAM_WITH_CRC_H
-#define __IN_STREAM_WITH_CRC_H
+#ifndef ZIP7_INC_IN_STREAM_WITH_CRC_H
+#define ZIP7_INC_IN_STREAM_WITH_CRC_H
#include "../../../../C/7zCrc.h"
@@ -9,26 +9,29 @@
#include "../../IStream.h"
-class CSequentialInStreamWithCRC:
- public ISequentialInStream,
- public CMyUnknownImp
-{
-public:
- MY_UNKNOWN_IMP
-
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
-private:
+Z7_CLASS_IMP_NOQIB_2(
+ CSequentialInStreamWithCRC
+ , ISequentialInStream
+ , IStreamGetSize
+)
CMyComPtr<ISequentialInStream> _stream;
UInt64 _size;
UInt32 _crc;
bool _wasFinished;
+ UInt64 _fullSize;
public:
- void SetStream(ISequentialInStream *stream) { _stream = stream; }
+
+ CSequentialInStreamWithCRC():
+ _fullSize((UInt64)(Int64)-1)
+ {}
+
+ void SetStream(ISequentialInStream *stream) { _stream = stream; }
+ void SetFullSize(UInt64 fullSize) { _fullSize = fullSize; }
void Init()
{
_size = 0;
- _wasFinished = false;
_crc = CRC_INIT_VAL;
+ _wasFinished = false;
}
void ReleaseStream() { _stream.Release(); }
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
@@ -36,22 +39,19 @@ public:
bool WasFinished() const { return _wasFinished; }
};
-class CInStreamWithCRC:
- public IInStream,
- public CMyUnknownImp
-{
-public:
- MY_UNKNOWN_IMP1(IInStream)
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
-private:
+Z7_CLASS_IMP_COM_1(
+ CInStreamWithCRC,
+ IInStream
+)
+ Z7_IFACE_COM7_IMP(ISequentialInStream)
+
CMyComPtr<IInStream> _stream;
UInt64 _size;
UInt32 _crc;
// bool _wasFinished;
public:
- void SetStream(IInStream *stream) { _stream = stream; }
+ void SetStream(IInStream *stream) { _stream = stream; }
void Init()
{
_size = 0;
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp
index 7cd3037be50..8caf1d141b1 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp
@@ -7,58 +7,101 @@
namespace NArchive {
namespace NItemName {
-static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR;
-static const wchar_t kDirDelimiter = L'/';
+static const wchar_t kOsPathSepar = WCHAR_PATH_SEPARATOR;
-void ReplaceToOsPathSeparator(wchar_t *s)
-{
- #ifdef _WIN32
- for (;;)
+#if WCHAR_PATH_SEPARATOR != L'/'
+static const wchar_t kUnixPathSepar = L'/';
+#endif
+
+void ReplaceSlashes_OsToUnix
+#if WCHAR_PATH_SEPARATOR != L'/'
+ (UString &name)
{
- wchar_t c = *s;
- if (c == 0)
- break;
- if (c == kDirDelimiter)
- *s = kOSDirDelimiter;
- s++;
+ name.Replace(kOsPathSepar, kUnixPathSepar);
}
- #endif
-}
+#else
+ (UString &) {}
+#endif
-UString MakeLegalName(const UString &name)
-{
- UString zipName = name;
- zipName.Replace(kOSDirDelimiter, kDirDelimiter);
- return zipName;
-}
-UString GetOSName(const UString &name)
+UString GetOsPath(const UString &name)
{
- UString newName = name;
- newName.Replace(kDirDelimiter, kOSDirDelimiter);
- return newName;
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ UString newName = name;
+ newName.Replace(kUnixPathSepar, kOsPathSepar);
+ return newName;
+ #else
+ return name;
+ #endif
}
-UString GetOSName2(const UString &name)
+
+UString GetOsPath_Remove_TailSlash(const UString &name)
{
if (name.IsEmpty())
return UString();
- UString newName = GetOSName(name);
- if (newName.Back() == kOSDirDelimiter)
+ UString newName = GetOsPath(name);
+ if (newName.Back() == kOsPathSepar)
newName.DeleteBack();
return newName;
}
-void ConvertToOSName2(UString &name)
+
+void ReplaceToOsSlashes_Remove_TailSlash(UString &name, bool
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ useBackslashReplacement
+ #endif
+ )
{
- if (!name.IsEmpty())
+ if (name.IsEmpty())
+ return;
+
+ #if WCHAR_PATH_SEPARATOR != L'/'
{
- name.Replace(kDirDelimiter, kOSDirDelimiter);
- if (name.Back() == kOSDirDelimiter)
- name.DeleteBack();
+ // name.Replace(kUnixPathSepar, kOsPathSepar);
+ const unsigned len = name.Len();
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = name[i];
+ if (c == L'/')
+ c = WCHAR_PATH_SEPARATOR;
+ else if (useBackslashReplacement && c == L'\\')
+ c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme
+ else
+ continue;
+ name.ReplaceOneCharAtPos(i, c);
+ }
+ }
+ #endif
+
+ if (name.Back() == kOsPathSepar)
+ name.DeleteBack();
+}
+
+
+void NormalizeSlashes_in_FileName_for_OsPath(wchar_t *name, unsigned len)
+{
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = name[i];
+ if (c == L'/')
+ c = L'_';
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ else if (c == L'\\')
+ c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme
+ #endif
+ else
+ continue;
+ name[i] = c;
}
}
+void NormalizeSlashes_in_FileName_for_OsPath(UString &name)
+{
+ NormalizeSlashes_in_FileName_for_OsPath(name.GetBuf(), name.Len());
+}
+
+
bool HasTailSlash(const AString &name, UINT
#if defined(_WIN32) && !defined(UNDER_CE)
codePage
@@ -67,20 +110,24 @@ bool HasTailSlash(const AString &name, UINT
{
if (name.IsEmpty())
return false;
- LPCSTR prev =
- #if defined(_WIN32) && !defined(UNDER_CE)
- CharPrevExA((WORD)codePage, name, &name[name.Len()], 0);
- #else
- (LPCSTR)(name) + (name.Len() - 1);
- #endif
- return (*prev == '/');
+ char c;
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (codePage != CP_UTF8)
+ c = *CharPrevExA((WORD)codePage, name, name.Ptr(name.Len()), 0);
+ else
+ #endif
+ {
+ c = name.Back();
+ }
+ return (c == '/');
}
+
#ifndef _WIN32
-UString WinNameToOSName(const UString &name)
+UString WinPathToOsPath(const UString &name)
{
UString newName = name;
- newName.Replace(L'\\', kOSDirDelimiter);
+ newName.Replace(L'\\', WCHAR_PATH_SEPARATOR);
return newName;
}
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h b/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h
index d0dc76a4109..8ab9b610a0f 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h
@@ -1,26 +1,29 @@
// Archive/Common/ItemNameUtils.h
-#ifndef __ARCHIVE_ITEM_NAME_UTILS_H
-#define __ARCHIVE_ITEM_NAME_UTILS_H
+#ifndef ZIP7_INC_ARCHIVE_ITEM_NAME_UTILS_H
+#define ZIP7_INC_ARCHIVE_ITEM_NAME_UTILS_H
#include "../../../Common/MyString.h"
namespace NArchive {
namespace NItemName {
- void ReplaceToOsPathSeparator(wchar_t *s);
-
- UString MakeLegalName(const UString &name);
- UString GetOSName(const UString &name);
- UString GetOSName2(const UString &name);
- void ConvertToOSName2(UString &name);
- bool HasTailSlash(const AString &name, UINT codePage);
-
- #ifdef _WIN32
- inline UString WinNameToOSName(const UString &name) { return name; }
- #else
- UString WinNameToOSName(const UString &name);
- #endif
+void ReplaceSlashes_OsToUnix(UString &name);
+
+UString GetOsPath(const UString &name);
+UString GetOsPath_Remove_TailSlash(const UString &name);
+
+void ReplaceToOsSlashes_Remove_TailSlash(UString &name, bool useBackslashReplacement = false);
+void NormalizeSlashes_in_FileName_for_OsPath(wchar_t *s, unsigned len);
+void NormalizeSlashes_in_FileName_for_OsPath(UString &name);
+
+bool HasTailSlash(const AString &name, UINT codePage);
+
+#ifdef _WIN32
+ inline UString WinPathToOsPath(const UString &name) { return name; }
+#else
+ UString WinPathToOsPath(const UString &name);
+#endif
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp
index 1de74afe43e..5d357af7113 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp
@@ -4,7 +4,7 @@
#include "MultiStream.h"
-STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize))
{
if (processedSize)
*processedSize = 0;
@@ -23,10 +23,7 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
else if (_pos >= m.GlobalOffset + m.Size)
left = mid + 1;
else
- {
- _streamIndex = mid;
break;
- }
mid = (left + right) / 2;
}
_streamIndex = mid;
@@ -36,12 +33,14 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
UInt64 localPos = _pos - s.GlobalOffset;
if (localPos != s.LocalPos)
{
- RINOK(s.Stream->Seek(localPos, STREAM_SEEK_SET, &s.LocalPos));
+ RINOK(s.Stream->Seek((Int64)localPos, STREAM_SEEK_SET, &s.LocalPos))
}
- UInt64 rem = s.Size - localPos;
- if (size > rem)
- size = (UInt32)rem;
- HRESULT result = s.Stream->Read(data, size, &size);
+ {
+ const UInt64 rem = s.Size - localPos;
+ if (size > rem)
+ size = (UInt32)rem;
+ }
+ const HRESULT result = s.Stream->Read(data, size, &size);
_pos += size;
s.LocalPos += size;
if (processedSize)
@@ -49,7 +48,7 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
return result;
}
-STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+Z7_COM7F_IMF(CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
{
switch (seekOrigin)
{
@@ -60,9 +59,9 @@ STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosi
}
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
- _pos = offset;
+ _pos = (UInt64)offset;
if (newPosition)
- *newPosition = offset;
+ *newPosition = (UInt64)offset;
return S_OK;
}
@@ -72,6 +71,9 @@ class COutVolumeStream:
public ISequentialOutStream,
public CMyUnknownImp
{
+ Z7_COM_UNKNOWN_IMP_0
+ Z7_IFACE_COM7_IMP(ISequentialOutStream)
+
unsigned _volIndex;
UInt64 _volSize;
UInt64 _curPos;
@@ -80,8 +82,6 @@ class COutVolumeStream:
CCRC _crc;
public:
- MY_UNKNOWN_IMP
-
CFileItem _file;
CUpdateOptions _options;
CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
@@ -98,7 +98,6 @@ public:
}
HRESULT Flush();
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
HRESULT COutVolumeStream::Flush()
@@ -107,7 +106,7 @@ HRESULT COutVolumeStream::Flush()
{
_file.UnPackSize = _curPos;
_file.FileCRC = _crc.GetDigest();
- RINOK(WriteVolumeHeader(_archive, _file, _options));
+ RINOK(WriteVolumeHeader(_archive, _file, _options))
_archive.Close();
_volumeStream.Release();
_file.StartPos += _file.UnPackSize;
@@ -117,7 +116,10 @@ HRESULT COutVolumeStream::Flush()
*/
/*
-STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+
+#include "../../../Common/Defs.h"
+
+Z7_COM7F_IMF(COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
{
if (processedSize)
*processedSize = 0;
@@ -126,8 +128,8 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce
if (_streamIndex >= Streams.Size())
{
CSubStreamInfo subStream;
- RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size));
- RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream));
+ RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size))
+ RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream))
subStream.Pos = 0;
Streams.Add(subStream);
continue;
@@ -142,15 +144,15 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce
if (_offsetPos != subStream.Pos)
{
CMyComPtr<IOutStream> outStream;
- RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
- RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
+ RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream))
+ RINOK(outStream->Seek((Int64)_offsetPos, STREAM_SEEK_SET, NULL))
subStream.Pos = _offsetPos;
}
- UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos);
+ const UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos);
UInt32 realProcessed;
- RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
- data = (void *)((Byte *)data + realProcessed);
+ RINOK(subStream.Stream->Write(data, curSize, &realProcessed))
+ data = (const void *)((const Byte *)data + realProcessed);
size -= realProcessed;
subStream.Pos += realProcessed;
_offsetPos += realProcessed;
@@ -170,7 +172,7 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce
return S_OK;
}
-STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+Z7_COM7F_IMF(COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
{
switch (seekOrigin)
{
@@ -181,11 +183,11 @@ STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newP
}
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
- _absPos = offset;
+ _absPos = (UInt64)offset;
_offsetPos = _absPos;
_streamIndex = 0;
if (newPosition)
- *newPosition = offset;
+ *newPosition = (UInt64)offset;
return S_OK;
}
*/
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h b/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h
index c10cd455729..e3096f58d93 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h
@@ -1,20 +1,23 @@
// MultiStream.h
-#ifndef __MULTI_STREAM_H
-#define __MULTI_STREAM_H
+#ifndef ZIP7_INC_MULTI_STREAM_H
+#define ZIP7_INC_MULTI_STREAM_H
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
#include "../../IStream.h"
+#include "../../Archive/IArchive.h"
-class CMultiStream:
- public IInStream,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_COM_1(
+ CMultiStream
+ , IInStream
+)
+ Z7_IFACE_COM7_IMP(ISequentialInStream)
+
+ unsigned _streamIndex;
UInt64 _pos;
UInt64 _totalLength;
- unsigned _streamIndex;
public:
@@ -24,12 +27,12 @@ public:
UInt64 Size;
UInt64 GlobalOffset;
UInt64 LocalPos;
-
CSubStreamInfo(): Size(0), GlobalOffset(0), LocalPos(0) {}
};
-
+
+ CMyComPtr<IArchiveUpdateCallbackFile> updateCallbackFile;
CObjectVector<CSubStreamInfo> Streams;
-
+
HRESULT Init()
{
UInt64 total = 0;
@@ -37,26 +40,27 @@ public:
{
CSubStreamInfo &s = Streams[i];
s.GlobalOffset = total;
- total += Streams[i].Size;
- RINOK(s.Stream->Seek(0, STREAM_SEEK_CUR, &s.LocalPos));
+ total += s.Size;
+ s.LocalPos = 0;
+ {
+ // it was already set to start
+ // RINOK(InStream_GetPos(s.Stream, s.LocalPos));
+ }
}
_totalLength = total;
_pos = 0;
_streamIndex = 0;
return S_OK;
}
-
- MY_UNKNOWN_IMP1(IInStream)
-
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
/*
-class COutMultiStream:
- public IOutStream,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_COM_1(
+ COutMultiStream,
+ IOutStream
+)
+ Z7_IFACE_COM7_IMP(ISequentialOutStream)
+
unsigned _streamIndex; // required stream
UInt64 _offsetPos; // offset from start of _streamIndex index
UInt64 _absPos;
@@ -78,11 +82,6 @@ public:
_absPos = 0;
_length = 0;
}
-
- MY_UNKNOWN_IMP1(IOutStream)
-
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
*/
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
index f955c22547b..7dcd44ac13c 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
@@ -4,7 +4,7 @@
#include "OutStreamWithCRC.h"
-STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize))
{
HRESULT result = S_OK;
if (_stream)
@@ -12,7 +12,7 @@ STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *pro
if (_calculate)
_crc = CrcUpdate(_crc, data, size);
_size += size;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = size;
return result;
}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h b/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h
index 09b899bbd74..845146a1b9d 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h
@@ -1,7 +1,7 @@
// OutStreamWithCRC.h
-#ifndef __OUT_STREAM_WITH_CRC_H
-#define __OUT_STREAM_WITH_CRC_H
+#ifndef ZIP7_INC_OUT_STREAM_WITH_CRC_H
+#define ZIP7_INC_OUT_STREAM_WITH_CRC_H
#include "../../../../C/7zCrc.h"
@@ -9,17 +9,15 @@
#include "../../IStream.h"
-class COutStreamWithCRC:
- public ISequentialOutStream,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_NOQIB_1(
+ COutStreamWithCRC
+ , ISequentialOutStream
+)
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
UInt32 _crc;
bool _calculate;
public:
- MY_UNKNOWN_IMP
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
void Init(bool calculate = true)
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/ParseProperties.h b/3rdparty/lzma/CPP/7zip/Archive/Common/ParseProperties.h
index 1038a8c020c..4ec2e48ed9d 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/ParseProperties.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/ParseProperties.h
@@ -1,6 +1,6 @@
// ParseProperties.h
-#ifndef __PARSE_PROPERTIES_H
-#define __PARSE_PROPERTIES_H
+#ifndef ZIP7_INC_PARSE_PROPERTIES_H
+#define ZIP7_INC_PARSE_PROPERTIES_H
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h b/3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h
index 2854ff3e935..035267ccd02 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h
@@ -1,8 +1,11 @@
// StdAfx.h
-#ifndef __STDAFX_H
-#define __STDAFX_H
+#ifndef ZIP7_INC_STDAFX_H
+#define ZIP7_INC_STDAFX_H
+#if defined(_MSC_VER) && _MSC_VER >= 1800
+#pragma warning(disable : 4464) // relative include path contains '..'
+#endif
#include "../../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp b/3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp
index 10889e75521..ae8d8acc19c 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp
@@ -3,10 +3,9 @@
#include "StdAfx.h"
#include "../../Common/MyWindows.h"
-
#include "../../Common/MyInitGuid.h"
-#if defined(_7ZIP_LARGE_PAGES)
+#if defined(Z7_LARGE_PAGES)
#include "../../../C/Alloc.h"
#endif
@@ -22,11 +21,25 @@
#include "IArchive.h"
-HINSTANCE g_hInstance;
+#ifdef _WIN32
+
+#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
#define NT_CHECK_FAIL_ACTION return FALSE;
+#endif
+
+static
+HINSTANCE g_hInstance;
+
+extern "C"
+BOOL WINAPI DllMain(
+ #ifdef UNDER_CE
+ HANDLE
+ #else
+ HINSTANCE
+ #endif
+ hInstance, DWORD dwReason, LPVOID /*lpReserved*/);
-#ifdef _WIN32
extern "C"
BOOL WINAPI DllMain(
#ifdef UNDER_CE
@@ -40,7 +53,7 @@ BOOL WINAPI DllMain(
{
// OutputDebugStringA("7z.dll DLL_PROCESS_ATTACH");
g_hInstance = (HINSTANCE)hInstance;
- NT_CHECK;
+ NT_CHECK
}
/*
if (dwReason == DLL_PROCESS_DETACH)
@@ -50,9 +63,24 @@ BOOL WINAPI DllMain(
*/
return TRUE;
}
-#endif
-DEFINE_GUID(CLSID_CArchiveHandler,
+#else // _WIN32
+
+#include "../../Common/StringConvert.h"
+// #include <stdio.h>
+
+// STDAPI LibStartup();
+static __attribute__((constructor)) void Init_ForceToUTF8();
+static __attribute__((constructor)) void Init_ForceToUTF8()
+{
+ g_ForceToUTF8 = IsNativeUTF8();
+ // printf("\nDLLExports2.cpp::Init_ForceToUTF8 =%d\n", g_ForceToUTF8 ? 1 : 0);
+}
+
+#endif // _WIN32
+
+
+Z7_DEFINE_GUID(CLSID_CArchiveHandler,
k_7zip_GUID_Data1,
k_7zip_GUID_Data2,
k_7zip_GUID_Data3_Common,
@@ -62,10 +90,11 @@ STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject);
STDAPI CreateHasher(const GUID *clsid, IHasher **hasher);
STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject);
+STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject);
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
{
// COM_TRY_BEGIN
- *outObject = 0;
+ *outObject = NULL;
if (*iid == IID_ICompressCoder ||
*iid == IID_ICompressCoder2 ||
*iid == IID_ICompressFilter)
@@ -76,26 +105,49 @@ STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
// COM_TRY_END
}
+STDAPI SetLargePageMode();
STDAPI SetLargePageMode()
{
- #if defined(_7ZIP_LARGE_PAGES)
+ #if defined(Z7_LARGE_PAGES)
+ #ifdef _WIN32
SetLargePageSize();
#endif
+ #endif
return S_OK;
}
extern bool g_CaseSensitive;
+STDAPI SetCaseSensitive(Int32 caseSensitive);
STDAPI SetCaseSensitive(Int32 caseSensitive)
{
g_CaseSensitive = (caseSensitive != 0);
return S_OK;
}
-#ifdef EXTERNAL_CODECS
+/*
+UInt32 g_ClientVersion;
+STDAPI SetClientVersion(UInt32 version);
+STDAPI SetClientVersion(UInt32 version)
+{
+ g_ClientVersion = version;
+ return S_OK;
+}
+*/
+
+/*
+STDAPI SetProperty(Int32 id, const PROPVARIANT *value);
+STDAPI SetProperty(Int32 id, const PROPVARIANT *value)
+{
+ return S_OK;
+}
+*/
+
+#ifdef Z7_EXTERNAL_CODECS
CExternalCodecs g_ExternalCodecs;
+STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo);
STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo)
{
COM_TRY_BEGIN
@@ -114,6 +166,7 @@ STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo)
#else
+STDAPI SetCodecs(ICompressCodecsInfo *);
STDAPI SetCodecs(ICompressCodecsInfo *)
{
return S_OK;
diff --git a/3rdparty/lzma/CPP/7zip/Archive/IArchive.h b/3rdparty/lzma/CPP/7zip/Archive/IArchive.h
index 0028d76246b..3e68ac30099 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/IArchive.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/IArchive.h
@@ -1,22 +1,55 @@
// IArchive.h
-#ifndef __IARCHIVE_H
-#define __IARCHIVE_H
+#ifndef ZIP7_INC_IARCHIVE_H
+#define ZIP7_INC_IARCHIVE_H
#include "../IProgress.h"
#include "../IStream.h"
#include "../PropID.h"
-#define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x)
-#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x)
+Z7_PURE_INTERFACES_BEGIN
+
+
+#define Z7_IFACE_CONSTR_ARCHIVE_SUB(i, base, n) \
+ Z7_DECL_IFACE_7ZIP_SUB(i, base, 6, n) \
+ { Z7_IFACE_COM7_PURE(i) };
+
+#define Z7_IFACE_CONSTR_ARCHIVE(i, n) \
+ Z7_IFACE_CONSTR_ARCHIVE_SUB(i, IUnknown, n)
+
+/*
+How the function in 7-Zip returns object for output parameter via pointer
+
+1) The caller sets the value of variable before function call:
+ PROPVARIANT : vt = VT_EMPTY
+ BSTR : NULL
+ IUnknown* and derived interfaces : NULL
+ another scalar types : any non-initialized value is allowed
+
+2) The callee in current 7-Zip code now can free input object for output parameter:
+ PROPVARIANT : the callee calls VariantClear(propvaiant_ptr) for input
+ value stored in variable
+ another types : the callee ignores stored value.
+
+3) The callee writes new value to variable for output parameter and
+ returns execution to caller.
+
+4) The caller must free or release object returned by the callee:
+ PROPVARIANT : VariantClear(&propvaiant)
+ BSTR : SysFreeString(bstr)
+ IUnknown* and derived interfaces : if (ptr) ptr->Relase()
+*/
+
namespace NFileTimeType
{
enum EEnum
{
- kWindows,
+ kNotDefined = -1,
+ kWindows = 0,
kUnix,
- kDOS
+ kDOS,
+ k1ns
};
}
@@ -34,8 +67,33 @@ namespace NArcInfoFlags
const UInt32 kPreArc = 1 << 9; // such archive can be stored before real archive (like SFX stub)
const UInt32 kSymLinks = 1 << 10; // the handler supports symbolic links
const UInt32 kHardLinks = 1 << 11; // the handler supports hard links
+ const UInt32 kByExtOnlyOpen = 1 << 12; // call handler only if file extension matches
+ const UInt32 kHashHandler = 1 << 13; // the handler contains the hashes (checksums)
+ const UInt32 kCTime = 1 << 14;
+ const UInt32 kCTime_Default = 1 << 15;
+ const UInt32 kATime = 1 << 16;
+ const UInt32 kATime_Default = 1 << 17;
+ const UInt32 kMTime = 1 << 18;
+ const UInt32 kMTime_Default = 1 << 19;
+ // const UInt32 kTTime_Reserved = 1 << 20;
+ // const UInt32 kTTime_Reserved_Default = 1 << 21;
}
+namespace NArcInfoTimeFlags
+{
+ const unsigned kTime_Prec_Mask_bit_index = 0;
+ const unsigned kTime_Prec_Mask_num_bits = 26;
+
+ const unsigned kTime_Prec_Default_bit_index = 27;
+ const unsigned kTime_Prec_Default_num_bits = 5;
+}
+
+#define TIME_PREC_TO_ARC_FLAGS_MASK(v) \
+ ((UInt32)1 << (NArcInfoTimeFlags::kTime_Prec_Mask_bit_index + (v)))
+
+#define TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT(v) \
+ ((UInt32)(v) << NArcInfoTimeFlags::kTime_Prec_Default_bit_index)
+
namespace NArchive
{
namespace NHandlerPropID
@@ -53,8 +111,8 @@ namespace NArchive
kSignatureOffset, // VT_UI4
kAltStreams, // VT_BOOL
kNtSecure, // VT_BOOL
- kFlags // VT_UI4
- // kVersion // VT_UI4 ((VER_MAJOR << 8) | VER_MINOR)
+ kFlags, // VT_UI4
+ kTimeFlags // VT_UI4
};
}
@@ -66,7 +124,8 @@ namespace NArchive
{
kExtract = 0,
kTest,
- kSkip
+ kSkip,
+ kReadExternal
};
}
@@ -84,6 +143,7 @@ namespace NArchive
kIsNotArc,
kHeadersError,
kWrongPassword
+ // , kMemError
};
}
}
@@ -96,6 +156,7 @@ namespace NArchive
kInArcIndex,
kBlockIndex,
kOutArcIndex
+ // kArcProp
};
}
@@ -106,20 +167,18 @@ namespace NArchive
enum
{
kOK = 0
- , // kError
+ // kError = 1,
+ // kError_FileChanged
};
}
}
}
-#define INTERFACE_IArchiveOpenCallback(x) \
- STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \
- STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \
+#define Z7_IFACEM_IArchiveOpenCallback(x) \
+ x(SetTotal(const UInt64 *files, const UInt64 *bytes)) \
+ x(SetCompleted(const UInt64 *files, const UInt64 *bytes)) \
-ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)
-{
- INTERFACE_IArchiveOpenCallback(PURE);
-};
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenCallback, 0x10)
/*
IArchiveExtractCallback::
@@ -137,13 +196,13 @@ IArchiveExtractCallback::GetStream()
Int32 askExtractMode (Extract::NAskMode)
if (askMode != NExtract::NAskMode::kExtract)
{
- then the callee can not real stream: (*inStream == NULL)
+ then the callee doesn't write data to stream: (*outStream == NULL)
}
Out:
- (*inStream == NULL) - for directories
- (*inStream == NULL) - if link (hard link or symbolic link) was created
- if (*inStream == NULL && askMode == NExtract::NAskMode::kExtract)
+ (*outStream == NULL) - for directories
+ (*outStream == NULL) - if link (hard link or symbolic link) was created
+ if (*outStream == NULL && askMode == NExtract::NAskMode::kExtract)
{
then the caller must skip extracting of that file.
}
@@ -170,57 +229,49 @@ SetOperationResult()
Int32 opRes (NExtract::NOperationResult)
*/
-#define INTERFACE_IArchiveExtractCallback(x) \
- INTERFACE_IProgress(x) \
- STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \
- STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \
- STDMETHOD(SetOperationResult)(Int32 opRes) x; \
+// INTERFACE_IProgress(x)
-ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20)
-{
- INTERFACE_IArchiveExtractCallback(PURE)
-};
+#define Z7_IFACEM_IArchiveExtractCallback(x) \
+ x(GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)) \
+ x(PrepareOperation(Int32 askExtractMode)) \
+ x(SetOperationResult(Int32 opRes)) \
+
+Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallback, IProgress, 0x20)
/*
-IArchiveExtractCallbackMessage can be requested from IArchiveExtractCallback object
+v23:
+IArchiveExtractCallbackMessage2 can be requested from IArchiveExtractCallback object
by Extract() or UpdateItems() functions to report about extracting errors
ReportExtractResult()
UInt32 indexType (NEventIndexType)
UInt32 index
Int32 opRes (NExtract::NOperationResult)
*/
+/*
+before v23:
+#define Z7_IFACEM_IArchiveExtractCallbackMessage(x) \
+ x(ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes))
+Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallbackMessage, IProgress, 0x21)
+*/
+#define Z7_IFACEM_IArchiveExtractCallbackMessage2(x) \
+ x(ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes))
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveExtractCallbackMessage2, 0x22)
-#define INTERFACE_IArchiveExtractCallbackMessage(x) \
- STDMETHOD(ReportExtractResult)(UInt32 indexType, UInt32 index, Int32 opRes) x; \
-
-ARCHIVE_INTERFACE_SUB(IArchiveExtractCallbackMessage, IProgress, 0x21)
-{
- INTERFACE_IArchiveExtractCallbackMessage(PURE)
-};
-
-
-#define INTERFACE_IArchiveOpenVolumeCallback(x) \
- STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \
- STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \
-
-ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30)
-{
- INTERFACE_IArchiveOpenVolumeCallback(PURE);
-};
-
+#define Z7_IFACEM_IArchiveOpenVolumeCallback(x) \
+ x(GetProperty(PROPID propID, PROPVARIANT *value)) \
+ x(GetStream(const wchar_t *name, IInStream **inStream))
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenVolumeCallback, 0x30)
-ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40)
-{
- STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE;
-};
+#define Z7_IFACEM_IInArchiveGetStream(x) \
+ x(GetStream(UInt32 index, ISequentialInStream **stream))
+Z7_IFACE_CONSTR_ARCHIVE(IInArchiveGetStream, 0x40)
-ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50)
-{
- STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE;
-};
+#define Z7_IFACEM_IArchiveOpenSetSubArchiveName(x) \
+ x(SetSubArchiveName(const wchar_t *name))
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenSetSubArchiveName, 0x50)
/*
@@ -256,28 +307,25 @@ Notes:
Some IInArchive handlers will work incorrectly in that case.
*/
-#ifdef _MSC_VER
- #define MY_NO_THROW_DECL_ONLY throw()
+#if defined(_MSC_VER) && !defined(__clang__)
+ #define MY_NO_THROW_DECL_ONLY Z7_COM7F_E
#else
#define MY_NO_THROW_DECL_ONLY
#endif
-#define INTERFACE_IInArchive(x) \
- STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; \
- STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \
- STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; \
- STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
- STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; \
- STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
- STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
- STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
- STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
- STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
-
-ARCHIVE_INTERFACE(IInArchive, 0x60)
-{
- INTERFACE_IInArchive(PURE)
-};
+#define Z7_IFACEM_IInArchive(x) \
+ x(Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback)) \
+ x(Close()) \
+ x(GetNumberOfItems(UInt32 *numItems)) \
+ x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \
+ x(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) \
+ x(GetArchiveProperty(PROPID propID, PROPVARIANT *value)) \
+ x(GetNumberOfProperties(UInt32 *numProps)) \
+ x(GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \
+ x(GetNumberOfArchiveProperties(UInt32 *numProps)) \
+ x(GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \
+
+Z7_IFACE_CONSTR_ARCHIVE(IInArchive, 0x60)
namespace NParentType
{
@@ -286,7 +334,7 @@ namespace NParentType
kDir = 0,
kAltStream
};
-};
+}
namespace NPropDataType
{
@@ -302,41 +350,36 @@ namespace NPropDataType
const UInt32 kUtf8z = kMask_Utf8 | kMask_ZeroEnd;
const UInt32 kUtf16z = kMask_Utf16 | kMask_ZeroEnd;
-};
+}
// UTF string (pointer to wchar_t) with zero end and little-endian.
#define PROP_DATA_TYPE_wchar_t_PTR_Z_LE ((NPropDataType::kMask_Utf | NPropDataType::kMask_ZeroEnd) + (sizeof(wchar_t) >> 1))
+
/*
GetRawProp:
Result:
S_OK - even if property is not set
*/
-#define INTERFACE_IArchiveGetRawProps(x) \
- STDMETHOD(GetParent)(UInt32 index, UInt32 *parent, UInt32 *parentType) x; \
- STDMETHOD(GetRawProp)(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \
- STDMETHOD(GetNumRawProps)(UInt32 *numProps) x; \
- STDMETHOD(GetRawPropInfo)(UInt32 index, BSTR *name, PROPID *propID) x;
+#define Z7_IFACEM_IArchiveGetRawProps(x) \
+ x(GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) \
+ x(GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) \
+ x(GetNumRawProps(UInt32 *numProps)) \
+ x(GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID))
-ARCHIVE_INTERFACE(IArchiveGetRawProps, 0x70)
-{
- INTERFACE_IArchiveGetRawProps(PURE)
-};
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetRawProps, 0x70)
-#define INTERFACE_IArchiveGetRootProps(x) \
- STDMETHOD(GetRootProp)(PROPID propID, PROPVARIANT *value) x; \
- STDMETHOD(GetRootRawProp)(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \
+#define Z7_IFACEM_IArchiveGetRootProps(x) \
+ x(GetRootProp(PROPID propID, PROPVARIANT *value)) \
+ x(GetRootRawProp(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) \
-ARCHIVE_INTERFACE(IArchiveGetRootProps, 0x71)
-{
- INTERFACE_IArchiveGetRootProps(PURE)
-};
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetRootProps, 0x71)
-ARCHIVE_INTERFACE(IArchiveOpenSeq, 0x61)
-{
- STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE;
-};
+#define Z7_IFACEM_IArchiveOpenSeq(x) \
+ x(OpenSeq(ISequentialInStream *stream)) \
+
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenSeq, 0x61)
/*
OpenForSize
@@ -362,12 +405,10 @@ Flags:
the handler can return S_OK, but it doesn't check even Signature.
So next Extract can be called for that sequential stream.
*/
-
/*
-ARCHIVE_INTERFACE(IArchiveOpen2, 0x62)
-{
- STDMETHOD(ArcOpen2)(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback) PURE;
-};
+#define Z7_IFACEM_IArchiveOpen2(x) \
+ x(ArcOpen2(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback))
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpen2, 0x62)
*/
// ---------- UPDATE ----------
@@ -400,27 +441,21 @@ SetOperationResult()
Int32 opRes (NExtract::NOperationResult::kOK)
*/
-#define INTERFACE_IArchiveUpdateCallback(x) \
- INTERFACE_IProgress(x); \
- STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive) x; \
- STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
- STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \
- STDMETHOD(SetOperationResult)(Int32 operationResult) x; \
+// INTERFACE_IProgress(x)
+#define Z7_IFACEM_IArchiveUpdateCallback(x) \
+ x(GetUpdateItemInfo(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)) \
+ x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \
+ x(GetStream(UInt32 index, ISequentialInStream **inStream)) \
+ x(SetOperationResult(Int32 operationResult)) \
-ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80)
-{
- INTERFACE_IArchiveUpdateCallback(PURE);
-};
+Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveUpdateCallback, IProgress, 0x80)
-#define INTERFACE_IArchiveUpdateCallback2(x) \
- INTERFACE_IArchiveUpdateCallback(x) \
- STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \
- STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \
+// INTERFACE_IArchiveUpdateCallback(x)
+#define Z7_IFACEM_IArchiveUpdateCallback2(x) \
+ x(GetVolumeSize(UInt32 index, UInt64 *size)) \
+ x(GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)) \
-ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
-{
- INTERFACE_IArchiveUpdateCallback2(PURE);
-};
+Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
namespace NUpdateNotifyOp
{
@@ -433,11 +468,13 @@ namespace NUpdateNotifyOp
kRepack,
kSkip,
kDelete,
- kHeader
-
- // kNumDefined
+ kHeader,
+ kHashRead,
+ kInFileChanged
+ // , kOpFinished
+ // , kNumDefined
};
-};
+}
/*
IArchiveUpdateCallbackFile::ReportOperation
@@ -446,16 +483,28 @@ IArchiveUpdateCallbackFile::ReportOperation
UInt32 notifyOp (NUpdateNotifyOp)
*/
-#define INTERFACE_IArchiveUpdateCallbackFile(x) \
- STDMETHOD(GetStream2)(UInt32 index, ISequentialInStream **inStream, UInt32 notifyOp) x; \
- STDMETHOD(ReportOperation)(UInt32 indexType, UInt32 index, UInt32 notifyOp) x; \
+#define Z7_IFACEM_IArchiveUpdateCallbackFile(x) \
+ x(GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 notifyOp)) \
+ x(ReportOperation(UInt32 indexType, UInt32 index, UInt32 notifyOp)) \
-ARCHIVE_INTERFACE(IArchiveUpdateCallbackFile, 0x83)
-{
- INTERFACE_IArchiveUpdateCallbackFile(PURE);
-};
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveUpdateCallbackFile, 0x83)
+#define Z7_IFACEM_IArchiveGetDiskProperty(x) \
+ x(GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \
+
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetDiskProperty, 0x84)
+
+/*
+#define Z7_IFACEM_IArchiveUpdateCallbackArcProp(x) \
+ x(ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value)) \
+ x(ReportRawProp(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)) \
+ x(ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)) \
+ x(DoNeedArcProp(PROPID propID, Int32 *answer)) \
+
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveUpdateCallbackArcProp, 0x85)
+*/
+
/*
UpdateItems()
-------------
@@ -478,41 +527,43 @@ UpdateItems()
*/
-#define INTERFACE_IOutArchive(x) \
- STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \
- STDMETHOD(GetFileTimeType)(UInt32 *type) x;
+#define Z7_IFACEM_IOutArchive(x) \
+ x(UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback)) \
+ x(GetFileTimeType(UInt32 *type))
-ARCHIVE_INTERFACE(IOutArchive, 0xA0)
-{
- INTERFACE_IOutArchive(PURE)
-};
+Z7_IFACE_CONSTR_ARCHIVE(IOutArchive, 0xA0)
-ARCHIVE_INTERFACE(ISetProperties, 0x03)
-{
- STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) PURE;
-};
+/*
+ISetProperties::SetProperties()
+ PROPVARIANT values[i].vt:
+ VT_EMPTY
+ VT_BOOL
+ VT_UI4 - if 32-bit number
+ VT_UI8 - if 64-bit number
+ VT_BSTR
+*/
-ARCHIVE_INTERFACE(IArchiveKeepModeForNextOpen, 0x04)
-{
- STDMETHOD(KeepModeForNextOpen)() PURE;
-};
+#define Z7_IFACEM_ISetProperties(x) \
+ x(SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
+
+Z7_IFACE_CONSTR_ARCHIVE(ISetProperties, 0x03)
+
+#define Z7_IFACEM_IArchiveKeepModeForNextOpen(x) \
+ x(KeepModeForNextOpen()) \
+
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveKeepModeForNextOpen, 0x04)
/* Exe handler: the handler for executable format (PE, ELF, Mach-O).
SFX archive: executable stub + some tail data.
before 9.31: exe handler didn't parse SFX archives as executable format.
for 9.31+: exe handler parses SFX archives as executable format, only if AllowTail(1) was called */
-ARCHIVE_INTERFACE(IArchiveAllowTail, 0x05)
-{
- STDMETHOD(AllowTail)(Int32 allowTail) PURE;
-};
+#define Z7_IFACEM_IArchiveAllowTail(x) \
+ x(AllowTail(Int32 allowTail)) \
+Z7_IFACE_CONSTR_ARCHIVE(IArchiveAllowTail, 0x05)
-#define IMP_IInArchive_GetProp(k) \
- (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
- { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \
- *propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; *name = 0; return S_OK; } \
struct CStatProp
@@ -528,46 +579,69 @@ namespace NCOM {
BSTR AllocBstrFromAscii(const char *s) throw();
}}
-#define IMP_IInArchive_GetProp_WITH_NAME(k) \
- (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
- { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \
+
+#define IMP_IInArchive_GetProp_Base(fn, f, k) \
+ Z7_COM7F_IMF(CHandler::fn(UInt32 *numProps)) \
+ { *numProps = Z7_ARRAY_SIZE(k); return S_OK; } \
+ Z7_COM7F_IMF(CHandler::f(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \
+ { if (index >= Z7_ARRAY_SIZE(k)) return E_INVALIDARG; \
+
+#define IMP_IInArchive_GetProp_NO_NAME(fn, f, k) \
+ IMP_IInArchive_GetProp_Base(fn, f, k) \
+ *propID = k[index]; \
+ *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; \
+ *name = NULL; return S_OK; } \
+
+#define IMP_IInArchive_GetProp_WITH_NAME(fn, f, k) \
+ IMP_IInArchive_GetProp_Base(fn, f, k) \
const CStatProp &prop = k[index]; \
- *propID = (PROPID)prop.PropID; *varType = prop.vt; \
+ *propID = (PROPID)prop.PropID; \
+ *varType = prop.vt; \
*name = NWindows::NCOM::AllocBstrFromAscii(prop.Name); return S_OK; } \
+
#define IMP_IInArchive_Props \
- STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \
- { *numProps = ARRAY_SIZE(kProps); return S_OK; } \
- STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps)
+ IMP_IInArchive_GetProp_NO_NAME(GetNumberOfProperties, GetPropertyInfo, kProps)
#define IMP_IInArchive_Props_WITH_NAME \
- STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \
- { *numProps = ARRAY_SIZE(kProps); return S_OK; } \
- STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps)
-
+ IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfProperties, GetPropertyInfo, kProps)
#define IMP_IInArchive_ArcProps \
- STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
- { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \
- STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps)
+ IMP_IInArchive_GetProp_NO_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps)
#define IMP_IInArchive_ArcProps_WITH_NAME \
- STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
- { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \
- STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps)
+ IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps)
#define IMP_IInArchive_ArcProps_NO_Table \
- STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
+ Z7_COM7F_IMF(CHandler::GetNumberOfArchiveProperties(UInt32 *numProps)) \
{ *numProps = 0; return S_OK; } \
- STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \
+ Z7_COM7F_IMF(CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *)) \
{ return E_NOTIMPL; } \
#define IMP_IInArchive_ArcProps_NO \
IMP_IInArchive_ArcProps_NO_Table \
- STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \
+ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value)) \
{ value->vt = VT_EMPTY; return S_OK; }
+#define Z7_class_CHandler_final \
+ Z7_class_final(CHandler)
+
+
+#define Z7_CLASS_IMP_CHandler_IInArchive_0 \
+ Z7_CLASS_IMP_COM_1(CHandler, IInArchive)
+#define Z7_CLASS_IMP_CHandler_IInArchive_1(i1) \
+ Z7_CLASS_IMP_COM_2(CHandler, IInArchive, i1)
+#define Z7_CLASS_IMP_CHandler_IInArchive_2(i1, i2) \
+ Z7_CLASS_IMP_COM_3(CHandler, IInArchive, i1, i2)
+#define Z7_CLASS_IMP_CHandler_IInArchive_3(i1, i2, i3) \
+ Z7_CLASS_IMP_COM_4(CHandler, IInArchive, i1, i2, i3)
+#define Z7_CLASS_IMP_CHandler_IInArchive_4(i1, i2, i3, i4) \
+ Z7_CLASS_IMP_COM_5(CHandler, IInArchive, i1, i2, i3, i4)
+#define Z7_CLASS_IMP_CHandler_IInArchive_5(i1, i2, i3, i4, i5) \
+ Z7_CLASS_IMP_COM_6(CHandler, IInArchive, i1, i2, i3, i4, i5)
+
+
#define k_IsArc_Res_NO 0
#define k_IsArc_Res_YES 1
@@ -590,9 +664,41 @@ extern "C"
typedef HRESULT (WINAPI *Func_SetCaseSensitive)(Int32 caseSensitive);
typedef HRESULT (WINAPI *Func_SetLargePageMode)();
+ // typedef HRESULT (WINAPI *Func_SetClientVersion)(UInt32 version);
typedef IOutArchive * (*Func_CreateOutArchive)();
typedef IInArchive * (*Func_CreateInArchive)();
}
+
+/*
+ if there is no time in archive, external MTime of archive
+ will be used instead of _item.Time from archive.
+ For 7-zip before 22.00 we need to return some supported value.
+ But (kpidTimeType > kDOS) is not allowed in 7-Zip before 22.00.
+ So we return highest precision value supported by old 7-Zip.
+ new 7-Zip 22.00 doesn't use that value in usual cases.
+*/
+
+
+#define DECLARE_AND_SET_CLIENT_VERSION_VAR
+#define GET_FileTimeType_NotDefined_for_GetFileTimeType \
+ NFileTimeType::kWindows
+
+/*
+extern UInt32 g_ClientVersion;
+
+#define GET_CLIENT_VERSION(major, minor) \
+ ((UInt32)(((UInt32)(major) << 16) | (UInt32)(minor)))
+
+#define DECLARE_AND_SET_CLIENT_VERSION_VAR \
+ UInt32 g_ClientVersion = GET_CLIENT_VERSION(MY_VER_MAJOR, MY_VER_MINOR);
+
+#define GET_FileTimeType_NotDefined_for_GetFileTimeType \
+ ((UInt32)(g_ClientVersion >= GET_CLIENT_VERSION(22, 0) ? \
+ (UInt32)(Int32)NFileTimeType::kNotDefined : \
+ NFileTimeType::kWindows))
+*/
+
+Z7_PURE_INTERFACES_END
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp b/3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp
index 121cd67cee5..11cb76ed467 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp
@@ -44,7 +44,8 @@ static const Byte kProps[] =
static const Byte kArcProps[] =
{
- kpidNumStreams
+ kpidNumStreams,
+ kpidMethod
};
struct CHeader
@@ -53,6 +54,7 @@ struct CHeader
Byte FilterID;
Byte LzmaProps[5];
+ Byte GetProp() const { return LzmaProps[0]; }
UInt32 GetDicSize() const { return GetUi32(LzmaProps + 1); }
bool HasSize() const { return (Size != (UInt64)(Int64)-1); }
bool Parse(const Byte *buf, bool isThereFilter);
@@ -74,7 +76,7 @@ bool CHeader::Parse(const Byte *buf, bool isThereFilter)
&& CheckDicSize(LzmaProps + 1);
}
-class CDecoder
+class CDecoder Z7_final
{
CMyComPtr<ISequentialOutStream> _bcjStream;
CFilterCoder *_filterCoder;
@@ -110,7 +112,7 @@ HRESULT CDecoder::Create(bool filteredMode, ISequentialInStream *inStream)
{
_filterCoder = new CFilterCoder(false);
CMyComPtr<ICompressCoder> coder = _filterCoder;
- _filterCoder->Filter = new NCompress::NBcj::CCoder(false);
+ _filterCoder->Filter = new NCompress::NBcj::CCoder2(z7_BranchConvSt_X86_Dec);
_bcjStream = _filterCoder;
}
}
@@ -129,21 +131,15 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,
if (header.FilterID > 1)
return E_NOTIMPL;
- {
- CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
- _lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
- if (!setDecoderProperties)
- return E_NOTIMPL;
- RINOK(setDecoderProperties->SetDecoderProperties2(header.LzmaProps, 5));
- }
+ RINOK(_lzmaDecoderSpec->SetDecoderProperties2(header.LzmaProps, 5))
bool filteredMode = (header.FilterID == 1);
if (filteredMode)
{
- RINOK(_filterCoder->SetOutStream(outStream));
+ RINOK(_filterCoder->SetOutStream(outStream))
outStream = _bcjStream;
- RINOK(_filterCoder->SetOutStreamSize(NULL));
+ RINOK(_filterCoder->SetOutStreamSize(NULL))
}
const UInt64 *Size = header.HasSize() ? &header.Size : NULL;
@@ -161,7 +157,7 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,
res = res2;
}
- RINOK(res);
+ RINOK(res)
if (header.HasSize())
if (_lzmaDecoderSpec->GetOutputProcessedSize() != header.Size)
@@ -171,11 +167,9 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,
}
-class CHandler:
- public IInArchive,
- public IArchiveOpenSeq,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_CHandler_IInArchive_1(
+ IArchiveOpenSeq
+)
CHeader _header;
bool _lzma86;
CMyComPtr<IInStream> _stream;
@@ -185,34 +179,28 @@ class CHandler:
bool _needSeekToStart;
bool _dataAfterEnd;
bool _needMoreInput;
+ bool _unsupported;
+ bool _dataError;
bool _packSize_Defined;
bool _unpackSize_Defined;
bool _numStreams_Defined;
- bool _unsupported;
- bool _dataError;
-
UInt64 _packSize;
UInt64 _unpackSize;
UInt64 _numStreams;
-public:
- MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq)
-
- INTERFACE_IInArchive(;)
- STDMETHOD(OpenSeq)(ISequentialInStream *stream);
-
- CHandler(bool lzma86) { _lzma86 = lzma86; }
+ void GetMethod(NCOM::CPropVariant &prop);
unsigned GetHeaderSize() const { return 5 + 8 + (_lzma86 ? 1 : 0); }
-
+public:
+ CHandler(bool lzma86) { _lzma86 = lzma86; }
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
-STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
{
NCOM::CPropVariant prop;
switch (propID)
@@ -220,63 +208,86 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidPhySize: if (_packSize_Defined) prop = _packSize; break;
case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break;
case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break;
+ case kpidMethod: GetMethod(prop); break;
case kpidErrorFlags:
{
UInt32 v = 0;
- if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;;
+ if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd;
if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
if (_dataError) v |= kpv_ErrorFlags_DataError;
prop = v;
+ break;
}
}
prop.Detach(value);
return S_OK;
}
-STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
{
*numItems = 1;
return S_OK;
}
-static void DictSizeToString(UInt32 value, char *s)
+
+static char * DictSizeToString(UInt32 val, char *s)
{
- for (int i = 0; i <= 31; i++)
- if (((UInt32)1 << i) == value)
- {
- ::ConvertUInt32ToString(i, s);
- return;
- }
+ for (unsigned i = 0; i < 32; i++)
+ if (((UInt32)1 << i) == val)
+ return ::ConvertUInt32ToString(i, s);
char c = 'b';
- if ((value & ((1 << 20) - 1)) == 0) { value >>= 20; c = 'm'; }
- else if ((value & ((1 << 10) - 1)) == 0) { value >>= 10; c = 'k'; }
- ::ConvertUInt32ToString(value, s);
- s += MyStringLen(s);
+ if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
+ else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
+ s = ::ConvertUInt32ToString(val, s);
*s++ = c;
*s = 0;
+ return s;
+}
+
+static char *AddProp32(char *s, const char *name, UInt32 v)
+{
+ *s++ = ':';
+ s = MyStpCpy(s, name);
+ return ::ConvertUInt32ToString(v, s);
}
-STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
+void CHandler::GetMethod(NCOM::CPropVariant &prop)
+{
+ if (!_stream)
+ return;
+
+ char sz[64];
+ char *s = sz;
+ if (_header.FilterID != 0)
+ s = MyStpCpy(s, "BCJ ");
+ s = MyStpCpy(s, "LZMA:");
+ s = DictSizeToString(_header.GetDicSize(), s);
+
+ UInt32 d = _header.GetProp();
+ // if (d != 0x5D)
+ {
+ UInt32 lc = d % 9;
+ d /= 9;
+ UInt32 pb = d / 5;
+ UInt32 lp = d % 5;
+ if (lc != 3) s = AddProp32(s, "lc", lc);
+ if (lp != 0) s = AddProp32(s, "lp", lp);
+ if (pb != 2) s = AddProp32(s, "pb", pb);
+ }
+ prop = sz;
+}
+
+
+Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value))
{
NCOM::CPropVariant prop;
switch (propID)
{
case kpidSize: if (_stream && _header.HasSize()) prop = _header.Size; break;
case kpidPackSize: if (_packSize_Defined) prop = _packSize; break;
- case kpidMethod:
- if (_stream)
- {
- char sz[64];
- char *s = sz;
- if (_header.FilterID != 0)
- s = MyStpCpy(s, "BCJ ");
- s = MyStpCpy(s, "LZMA:");
- DictSizeToString(_header.GetDicSize(), s);
- prop = sz;
- }
- break;
+ case kpidMethod: GetMethod(prop); break;
}
prop.Detach(value);
return S_OK;
@@ -289,10 +300,10 @@ API_FUNC_static_IsArc IsArc_Lzma(const Byte *p, size_t size)
return k_IsArc_Res_NEED_MORE;
if (p[0] >= 5 * 5 * 9)
return k_IsArc_Res_NO;
- UInt64 unpackSize = GetUi64(p + 1 + 4);
+ const UInt64 unpackSize = GetUi64(p + 1 + 4);
if (unpackSize != (UInt64)(Int64)-1)
{
- if (size >= ((UInt64)1 << 56))
+ if (unpackSize >= ((UInt64)1 << 56))
return k_IsArc_Res_NO;
}
if (unpackSize != 0)
@@ -325,24 +336,54 @@ API_FUNC_static_IsArc IsArc_Lzma86(const Byte *p, size_t size)
}
}
-STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)
+
+
+Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *))
{
Close();
- const UInt32 kBufSize = 1 + 5 + 8 + 2;
+ const unsigned headerSize = GetHeaderSize();
+ const UInt32 kBufSize = 1 << 7;
Byte buf[kBufSize];
-
- RINOK(ReadStream_FALSE(inStream, buf, kBufSize));
-
+ size_t processedSize = kBufSize;
+ RINOK(ReadStream(inStream, buf, &processedSize))
+ if (processedSize < headerSize + 2)
+ return S_FALSE;
if (!_header.Parse(buf, _lzma86))
return S_FALSE;
- const Byte *start = buf + GetHeaderSize();
+ const Byte *start = buf + headerSize;
if (start[0] != 0 /* || (start[1] & 0x80) != 0 */ ) // empty stream with EOS is not 0x80
return S_FALSE;
-
- RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize));
- if (_packSize >= 24 && _header.Size == 0 && _header.FilterID == 0 && _header.LzmaProps[0] == 0)
+
+ RINOK(InStream_GetSize_SeekToEnd(inStream, _packSize))
+
+ SizeT srcLen = (SizeT)processedSize - headerSize;
+
+ if (srcLen > 10
+ && _header.Size == 0
+ // && _header.FilterID == 0
+ && _header.LzmaProps[0] == 0
+ )
return S_FALSE;
+
+ CDecoder state;
+ const UInt32 outLimit = 1 << 11;
+ Byte outBuf[outLimit];
+
+ SizeT outSize = outLimit;
+ if (outSize > _header.Size)
+ outSize = (SizeT)_header.Size;
+ SizeT destLen = outSize;
+ ELzmaStatus status;
+
+ SRes res = LzmaDecode(outBuf, &destLen, start, &srcLen,
+ _header.LzmaProps, 5, LZMA_FINISH_ANY,
+ &status, &g_Alloc);
+
+ if (res != SZ_OK)
+ if (res != SZ_ERROR_INPUT_EOF)
+ return S_FALSE;
+
_isArc = true;
_stream = inStream;
_seqStream = inStream;
@@ -350,7 +391,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCal
return S_OK;
}
-STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
+Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream))
{
Close();
_isArc = true;
@@ -358,53 +399,50 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
return S_OK;
}
-STDMETHODIMP CHandler::Close()
+Z7_COM7F_IMF(CHandler::Close())
{
_isArc = false;
- _packSize_Defined = false;
- _unpackSize_Defined = false;
- _numStreams_Defined = false;
-
+ _needSeekToStart = false;
_dataAfterEnd = false;
_needMoreInput = false;
_unsupported = false;
_dataError = false;
- _packSize = 0;
+ _packSize_Defined = false;
+ _unpackSize_Defined = false;
+ _numStreams_Defined = false;
- _needSeekToStart = false;
+ _packSize = 0;
_stream.Release();
_seqStream.Release();
return S_OK;
}
-class CCompressProgressInfoImp:
- public ICompressProgressInfo,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_COM_1(
+ CCompressProgressInfoImp,
+ ICompressProgressInfo
+)
CMyComPtr<IArchiveOpenCallback> Callback;
public:
UInt64 Offset;
-
- MY_UNKNOWN_IMP1(ICompressProgressInfo)
- STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+
void Init(IArchiveOpenCallback *callback) { Callback = callback; }
};
-STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)
+Z7_COM7F_IMF(CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */))
{
if (Callback)
{
- UInt64 files = 0;
- UInt64 value = Offset + *inSize;
- return Callback->SetCompleted(&files, &value);
+ const UInt64 files = 0;
+ const UInt64 val = Offset + *inSize;
+ return Callback->SetCompleted(&files, &val);
}
return S_OK;
}
-STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
- Int32 testMode, IArchiveExtractCallback *extractCallback)
+Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback))
{
COM_TRY_BEGIN
@@ -418,10 +456,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ISequentialOutStream> realOutStream;
- Int32 askMode = testMode ?
+ const Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
- RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
+ RINOK(extractCallback->GetStream(0, &realOutStream, askMode))
if (!testMode && !realOutStream)
return S_OK;
@@ -441,14 +479,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
if (!_stream)
return E_FAIL;
- RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(InStream_SeekToBegin(_stream))
}
else
_needSeekToStart = true;
CDecoder decoder;
HRESULT result = decoder.Create(_lzma86, _seqStream);
- RINOK(result);
+ RINOK(result)
bool firstItem = true;
@@ -462,13 +500,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
lps->InSize = packSize;
lps->OutSize = unpackSize;
- RINOK(lps->SetCur());
+ RINOK(lps->SetCur())
const UInt32 kBufSize = 1 + 5 + 8;
Byte buf[kBufSize];
const UInt32 headerSize = GetHeaderSize();
UInt32 processed;
- RINOK(decoder.ReadInput(buf, headerSize, &processed));
+ RINOK(decoder.ReadInput(buf, headerSize, &processed))
if (processed != headerSize)
{
if (processed != 0)
@@ -498,7 +536,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
if (result == S_FALSE)
break;
- RINOK(result);
+ RINOK(result)
}
if (firstItem)
@@ -510,7 +548,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
if (dataAfterEnd)
_dataAfterEnd = true;
- else if (decoder._lzmaDecoderSpec->NeedMoreInput)
+ else if (decoder._lzmaDecoderSpec->NeedsMoreInput())
_needMoreInput = true;
_packSize = packSize;
@@ -551,7 +589,7 @@ namespace NLzmaAr {
REGISTER_ARC_I_CLS_NO_SIG(
CHandler(false),
- "lzma", "lzma", 0, 0xA,
+ "lzma", "lzma", NULL, 0xA,
0,
NArcInfoFlags::kStartOpen |
NArcInfoFlags::kKeepName,
@@ -563,7 +601,7 @@ namespace NLzma86Ar {
REGISTER_ARC_I_CLS_NO_SIG(
CHandler(true),
- "lzma86", "lzma86", 0, 0xB,
+ "lzma86", "lzma86", NULL, 0xB,
0,
NArcInfoFlags::kKeepName,
IsArc_Lzma86)
diff --git a/3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp b/3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp
index 72b52fe732d..ae7ca0369fb 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp
@@ -9,6 +9,7 @@
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
+#include "../Common/StreamUtils.h"
#include "../Compress/CopyCoder.h"
@@ -31,27 +32,22 @@ static const Byte kArcProps[] =
kpidTotalPhySize
};
-class CHandler:
- public IInArchive,
- public IInArchiveGetStream,
- public CMyUnknownImp
-{
+
+Z7_CLASS_IMP_CHandler_IInArchive_1(
+ IInArchiveGetStream
+)
CObjectVector<CMyComPtr<IInStream> > _streams;
CRecordVector<UInt64> _sizes;
UString _subName;
UInt64 _totalSize;
HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback);
-public:
- MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
- INTERFACE_IInArchive(;)
- STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
};
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
-STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
{
NCOM::CPropVariant prop;
switch (propID)
@@ -121,29 +117,31 @@ struct CSeqName
}
};
+
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{
Close();
if (!callback)
return S_FALSE;
- CMyComPtr<IArchiveOpenVolumeCallback> volumeCallback;
- callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback);
+ Z7_DECL_CMyComPtr_QI_FROM(
+ IArchiveOpenVolumeCallback,
+ volumeCallback, callback)
if (!volumeCallback)
return S_FALSE;
UString name;
{
NCOM::CPropVariant prop;
- RINOK(volumeCallback->GetProperty(kpidName, &prop));
+ RINOK(volumeCallback->GetProperty(kpidName, &prop))
if (prop.vt != VT_BSTR)
return S_FALSE;
name = prop.bstrVal;
}
- int dotPos = name.ReverseFind_Dot();
- const UString prefix = name.Left(dotPos + 1);
- const UString ext = name.Ptr(dotPos + 1);
+ const int dotPos = name.ReverseFind_Dot();
+ const UString prefix = name.Left((unsigned)(dotPos + 1));
+ const UString ext = name.Ptr((unsigned)(dotPos + 1));
UString ext2 = ext;
ext2.MakeLower_Ascii();
@@ -162,7 +160,10 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
numLetters++;
}
}
- else if (ext.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "01"))
+ else if (ext2.Len() >= 2 && (
+ StringsAreEqual_Ascii(ext2.RightPtr(2), "01")
+ || StringsAreEqual_Ascii(ext2.RightPtr(2), "00")
+ ))
{
while (numLetters < ext2.Len())
{
@@ -170,7 +171,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
break;
numLetters++;
}
- if (numLetters != ext.Len())
+ if (numLetters != ext2.Len())
return S_FALSE;
}
else
@@ -181,7 +182,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
seqName._splitStyle = splitStyle;
if (prefix.Len() < 1)
- _subName.SetFromAscii("file");
+ _subName = "file";
else
_subName.SetFrom(prefix, prefix.Len() - 1);
@@ -189,14 +190,13 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{
/*
NCOM::CPropVariant prop;
- RINOK(volumeCallback->GetProperty(kpidSize, &prop));
+ RINOK(volumeCallback->GetProperty(kpidSize, &prop))
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
*/
- RINOK(stream->Seek(0, STREAM_SEEK_END, &size));
- RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
}
+ RINOK(InStream_AtBegin_GetSize(stream, size))
_totalSize += size;
_sizes.Add(size);
@@ -204,7 +204,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{
const UInt64 numFiles = _streams.Size();
- RINOK(callback->SetCompleted(&numFiles, NULL));
+ RINOK(callback->SetCompleted(&numFiles, NULL))
}
for (;;)
@@ -213,30 +213,20 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
if (!seqName.GetNextName(fullName))
break;
CMyComPtr<IInStream> nextStream;
- HRESULT result = volumeCallback->GetStream(fullName, &nextStream);
+ const HRESULT result = volumeCallback->GetStream(fullName, &nextStream);
if (result == S_FALSE)
break;
if (result != S_OK)
return result;
if (!nextStream)
break;
- {
- /*
- NCOM::CPropVariant prop;
- RINOK(volumeCallback->GetProperty(kpidSize, &prop));
- if (prop.vt != VT_UI8)
- return E_INVALIDARG;
- size = prop.uhVal.QuadPart;
- */
- RINOK(nextStream->Seek(0, STREAM_SEEK_END, &size));
- RINOK(nextStream->Seek(0, STREAM_SEEK_SET, NULL));
- }
+ RINOK(InStream_AtBegin_GetSize(nextStream, size))
_totalSize += size;
_sizes.Add(size);
_streams.Add(nextStream);
{
const UInt64 numFiles = _streams.Size();
- RINOK(callback->SetCompleted(&numFiles, NULL));
+ RINOK(callback->SetCompleted(&numFiles, NULL))
}
}
@@ -248,17 +238,17 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
return S_OK;
}
-STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)
+Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback))
{
COM_TRY_BEGIN
- HRESULT res = Open2(stream, callback);
+ const HRESULT res = Open2(stream, callback);
if (res != S_OK)
Close();
return res;
COM_TRY_END
}
-STDMETHODIMP CHandler::Close()
+Z7_COM7F_IMF(CHandler::Close())
{
_totalSize = 0;
_subName.Empty();
@@ -267,13 +257,13 @@ STDMETHODIMP CHandler::Close()
return S_OK;
}
-STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
{
*numItems = _streams.IsEmpty() ? 0 : 1;
return S_OK;
}
-STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
+Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value))
{
NCOM::CPropVariant prop;
switch (propID)
@@ -288,8 +278,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
return S_OK;
}
-STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
- Int32 testMode, IArchiveExtractCallback *extractCallback)
+Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback))
{
COM_TRY_BEGIN
if (numItems == 0)
@@ -298,15 +288,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
return E_INVALIDARG;
UInt64 currentTotalSize = 0;
- RINOK(extractCallback->SetTotal(_totalSize));
+ RINOK(extractCallback->SetTotal(_totalSize))
CMyComPtr<ISequentialOutStream> outStream;
- Int32 askMode = testMode ?
+ const Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
- RINOK(extractCallback->GetStream(0, &outStream, askMode));
+ RINOK(extractCallback->GetStream(0, &outStream, askMode))
if (!testMode && !outStream)
return S_OK;
- RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->PrepareOperation(askMode))
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
@@ -315,13 +305,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
- FOR_VECTOR (i, _streams)
+ for (unsigned i = 0;; i++)
{
lps->InSize = lps->OutSize = currentTotalSize;
- RINOK(lps->SetCur());
+ RINOK(lps->SetCur())
+ if (i == _streams.Size())
+ break;
IInStream *inStream = _streams[i];
- RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
- RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
+ RINOK(InStream_SeekToBegin(inStream))
+ RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress))
currentTotalSize += copyCoderSpec->TotalSize;
}
outStream.Release();
@@ -329,12 +321,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
COM_TRY_END
}
-STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream))
{
COM_TRY_BEGIN
if (index != 0)
return E_INVALIDARG;
- *stream = 0;
+ *stream = NULL;
CMultiStream *streamSpec = new CMultiStream;
CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
FOR_VECTOR (i, _streams)
@@ -351,7 +343,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
}
REGISTER_ARC_I_NO_SIG(
- "Split", "001", 0, 0xEA,
+ "Split", "001", NULL, 0xEA,
0,
0,
NULL)
diff --git a/3rdparty/lzma/CPP/7zip/Archive/StdAfx.h b/3rdparty/lzma/CPP/7zip/Archive/StdAfx.h
index 1cbd7feaeec..80866550d1f 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/StdAfx.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/StdAfx.h
@@ -1,8 +1,11 @@
// StdAfx.h
-#ifndef __STDAFX_H
-#define __STDAFX_H
+#ifndef ZIP7_INC_STDAFX_H
+#define ZIP7_INC_STDAFX_H
+#if defined(_MSC_VER) && _MSC_VER >= 1800
+#pragma warning(disable : 4464) // relative include path contains '..'
+#endif
#include "../../Common/Common.h"
#endif
diff --git a/3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp b/3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp
index 318be190a79..976817c7437 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp
+++ b/3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp
@@ -3,16 +3,15 @@
#include "StdAfx.h"
#include "../../../C/Alloc.h"
-#include "../../../C/XzCrc64.h"
-#include "../../../C/XzEnc.h"
#include "../../Common/ComTry.h"
#include "../../Common/Defs.h"
#include "../../Common/IntToString.h"
+#include "../../Common/MyBuffer.h"
+#include "../../Common/StringToInt.h"
#include "../../Windows/PropVariant.h"
-
-#include "../ICoder.h"
+#include "../../Windows/System.h"
#include "../Common/CWrappers.h"
#include "../Common/ProgressUtils.h"
@@ -20,126 +19,174 @@
#include "../Common/StreamUtils.h"
#include "../Compress/CopyCoder.h"
+#include "../Compress/XzDecoder.h"
+#include "../Compress/XzEncoder.h"
#include "IArchive.h"
-#ifndef EXTRACT_ONLY
#include "Common/HandlerOut.h"
-#endif
-
-#include "XzHandler.h"
using namespace NWindows;
-namespace NCompress {
-namespace NLzma2 {
-
-HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props);
-
-}}
-
namespace NArchive {
namespace NXz {
-struct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit;
+#define k_LZMA2_Name "LZMA2"
-static const char *k_LZMA2_Name = "LZMA2";
-void CStatInfo::Clear()
+struct CBlockInfo
{
- InSize = 0;
- OutSize = 0;
- PhySize = 0;
-
- NumStreams = 0;
- NumBlocks = 0;
-
- UnpackSize_Defined = false;
-
- NumStreams_Defined = false;
- NumBlocks_Defined = false;
-
- IsArc = false;
- UnexpectedEnd = false;
- DataAfterEnd = false;
- Unsupported = false;
- HeadersError = false;
- DataError = false;
- CrcError = false;
-}
+ unsigned StreamFlags;
+ UInt64 PackPos;
+ UInt64 PackSize; // pure value from Index record, it doesn't include pad zeros
+ UInt64 UnpackPos;
+};
+
-class CHandler:
+Z7_class_CHandler_final:
public IInArchive,
public IArchiveOpenSeq,
- #ifndef EXTRACT_ONLY
- public IOutArchive,
+ public IInArchiveGetStream,
public ISetProperties,
- public CMultiMethodProps,
- #endif
- public CMyUnknownImp
+ #ifndef Z7_EXTRACT_ONLY
+ public IOutArchive,
+ #endif
+ public CMyUnknownImp,
+ #ifndef Z7_EXTRACT_ONLY
+ public CMultiMethodProps
+ #else
+ public CCommonMethodProps
+ #endif
{
- CStatInfo _stat;
+ Z7_COM_QI_BEGIN2(IInArchive)
+ Z7_COM_QI_ENTRY(IArchiveOpenSeq)
+ Z7_COM_QI_ENTRY(IInArchiveGetStream)
+ Z7_COM_QI_ENTRY(ISetProperties)
+ #ifndef Z7_EXTRACT_ONLY
+ Z7_COM_QI_ENTRY(IOutArchive)
+ #endif
+ Z7_COM_QI_END
+ Z7_COM_ADDREF_RELEASE
+
+ Z7_IFACE_COM7_IMP(IInArchive)
+ Z7_IFACE_COM7_IMP(IArchiveOpenSeq)
+ Z7_IFACE_COM7_IMP(IInArchiveGetStream)
+ Z7_IFACE_COM7_IMP(ISetProperties)
+ #ifndef Z7_EXTRACT_ONLY
+ Z7_IFACE_COM7_IMP(IOutArchive)
+ #endif
+
+ CXzStatInfo _stat; // it's stat from backward parsing
+ CXzStatInfo _stat2; // it's data from forward parsing, if the decoder was called
+ SRes _stat2_decode_SRes;
+ bool _stat_defined;
+ bool _stat2_defined;
+
+ const CXzStatInfo *GetStat() const
+ {
+ if (_stat_defined) return &_stat;
+ if (_stat2_defined) return &_stat2;
+ return NULL;
+ }
bool _isArc;
bool _needSeekToStart;
- bool _phySize_Defined;
-
- CMyComPtr<IInStream> _stream;
- CMyComPtr<ISequentialInStream> _seqStream;
+ bool _firstBlockWasRead;
AString _methodsString;
- #ifndef EXTRACT_ONLY
+
+ #ifndef Z7_EXTRACT_ONLY
UInt32 _filterId;
+ UInt64 _numSolidBytes;
- void Init()
+ void InitXz()
{
_filterId = 0;
- CMultiMethodProps::Init();
+ _numSolidBytes = XZ_PROPS_BLOCK_SIZE_AUTO;
}
-
+
#endif
+
+ void Init()
+ {
+ #ifndef Z7_EXTRACT_ONLY
+ InitXz();
+ CMultiMethodProps::Init();
+ #else
+ CCommonMethodProps::InitCommon();
+ #endif
+ }
+
+ HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
+
HRESULT Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback);
- HRESULT Decode2(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
- CDecoder &decoder, ICompressProgressInfo *progress)
+ HRESULT Decode(NCompress::NXz::CDecoder &decoder,
+ ISequentialInStream *seqInStream,
+ ISequentialOutStream *outStream,
+ ICompressProgressInfo *progress)
{
- RINOK(decoder.Decode(seqInStream, outStream, progress));
- _stat = decoder;
- _phySize_Defined = true;
- return S_OK;
+ #ifndef Z7_ST
+ decoder._numThreads = _numThreads;
+ #endif
+ decoder._memUsage = _memUsage_Decompress;
+
+ HRESULT hres = decoder.Decode(seqInStream, outStream,
+ NULL, // *outSizeLimit
+ true, // finishStream
+ progress);
+
+ if (decoder.MainDecodeSRes_wasUsed
+ && decoder.MainDecodeSRes != SZ_ERROR_MEM
+ && decoder.MainDecodeSRes != SZ_ERROR_UNSUPPORTED)
+ {
+ // if (!_stat2_defined)
+ {
+ _stat2_decode_SRes = decoder.MainDecodeSRes;
+ _stat2 = decoder.Stat;
+ _stat2_defined = true;
+ }
+ }
+
+ return hres;
}
public:
- MY_QUERYINTERFACE_BEGIN2(IInArchive)
- MY_QUERYINTERFACE_ENTRY(IArchiveOpenSeq)
- #ifndef EXTRACT_ONLY
- MY_QUERYINTERFACE_ENTRY(IOutArchive)
- MY_QUERYINTERFACE_ENTRY(ISetProperties)
- #endif
- MY_QUERYINTERFACE_END
- MY_ADDREF_RELEASE
-
- INTERFACE_IInArchive(;)
- STDMETHOD(OpenSeq)(ISequentialInStream *stream);
+ CBlockInfo *_blocks;
+ size_t _blocksArraySize;
+ UInt64 _maxBlocksSize;
+ CMyComPtr<IInStream> _stream;
+ CMyComPtr<ISequentialInStream> _seqStream;
- #ifndef EXTRACT_ONLY
- INTERFACE_IOutArchive(;)
- STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
- #endif
+ CXzBlock _firstBlock;
CHandler();
+ ~CHandler();
+
+ HRESULT SeekToPackPos(UInt64 pos)
+ {
+ return InStream_SeekSet(_stream, pos);
+ }
};
-CHandler::CHandler()
+
+CHandler::CHandler():
+ _blocks(NULL),
+ _blocksArraySize(0)
{
- #ifndef EXTRACT_ONLY
- Init();
+ #ifndef Z7_EXTRACT_ONLY
+ InitXz();
#endif
}
+CHandler::~CHandler()
+{
+ MyFree(_blocks);
+}
+
static const Byte kProps[] =
{
@@ -152,7 +199,9 @@ static const Byte kArcProps[] =
{
kpidMethod,
kpidNumStreams,
- kpidNumBlocks
+ kpidNumBlocks,
+ kpidClusterSize,
+ kpidCharacts
};
IMP_IInArchive_Props
@@ -169,13 +218,6 @@ static inline void AddHexToString(AString &s, Byte value)
s += GetHex(value & 0xF);
}
-static void AddUInt32ToString(AString &s, UInt32 value)
-{
- char temp[16];
- ConvertUInt32ToString(value, temp);
- s += temp;
-}
-
static void Lzma2PropToString(AString &s, unsigned prop)
{
char c = 0;
@@ -192,7 +234,7 @@ static void Lzma2PropToString(AString &s, unsigned prop)
c = 'm';
}
}
- AddUInt32ToString(s, size);
+ s.Add_UInt32(size);
if (c != 0)
s += c;
}
@@ -213,13 +255,14 @@ static const CMethodNamePair g_NamePairs[] =
{ XZ_ID_ARM, "ARM" },
{ XZ_ID_ARMT, "ARMT" },
{ XZ_ID_SPARC, "SPARC" },
+ { XZ_ID_ARM64, "ARM64" },
{ XZ_ID_LZMA2, "LZMA2" }
};
-static AString GetMethodString(const CXzFilter &f)
+static void AddMethodString(AString &s, const CXzFilter &f)
{
const char *p = NULL;
- for (unsigned i = 0; i < ARRAY_SIZE(g_NamePairs); i++)
+ for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NamePairs); i++)
if (g_NamePairs[i].Id == f.id)
{
p = g_NamePairs[i].Name;
@@ -232,7 +275,7 @@ static AString GetMethodString(const CXzFilter &f)
p = temp;
}
- AString s = p;
+ s += p;
if (f.propsSize > 0)
{
@@ -240,7 +283,9 @@ static AString GetMethodString(const CXzFilter &f)
if (f.id == XZ_ID_LZMA2 && f.propsSize == 1)
Lzma2PropToString(s, f.props[0]);
else if (f.id == XZ_ID_Delta && f.propsSize == 1)
- AddUInt32ToString(s, (UInt32)f.props[0] + 1);
+ s.Add_UInt32((UInt32)f.props[0] + 1);
+ else if (f.id == XZ_ID_ARM64 && f.propsSize == 1)
+ s.Add_UInt32((UInt32)f.props[0] + 16 + 2);
else
{
s += '[';
@@ -249,13 +294,6 @@ static AString GetMethodString(const CXzFilter &f)
s += ']';
}
}
- return s;
-}
-
-static void AddString(AString &dest, const AString &src)
-{
- dest.Add_Space_if_NotEmpty();
- dest += src;
}
static const char * const kChecks[] =
@@ -278,51 +316,76 @@ static const char * const kChecks[] =
, NULL
};
-static AString GetCheckString(const CXzs &xzs)
+static void AddCheckString(AString &s, const CXzs &xzs)
{
size_t i;
UInt32 mask = 0;
for (i = 0; i < xzs.num; i++)
mask |= ((UInt32)1 << XzFlags_GetCheckType(xzs.streams[i].flags));
- AString s;
for (i = 0; i <= XZ_CHECK_MASK; i++)
if (((mask >> i) & 1) != 0)
{
- AString s2;
+ s.Add_Space_if_NotEmpty();
if (kChecks[i])
- s2 = kChecks[i];
+ s += kChecks[i];
else
{
- s2 = "Check-";
- AddUInt32ToString(s2, (UInt32)i);
+ s += "Check-";
+ s.Add_UInt32((UInt32)i);
}
- AddString(s, s2);
}
- return s;
}
-STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
+
+ const CXzStatInfo *stat = GetStat();
+
switch (propID)
{
- case kpidPhySize: if (_phySize_Defined) prop = _stat.PhySize; break;
- case kpidNumStreams: if (_stat.NumStreams_Defined) prop = _stat.NumStreams; break;
- case kpidNumBlocks: if (_stat.NumBlocks_Defined) prop = _stat.NumBlocks; break;
- case kpidUnpackSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break;
+ case kpidPhySize: if (stat) prop = stat->InSize; break;
+ case kpidNumStreams: if (stat && stat->NumStreams_Defined) prop = stat->NumStreams; break;
+ case kpidNumBlocks: if (stat && stat->NumBlocks_Defined) prop = stat->NumBlocks; break;
+ case kpidUnpackSize: if (stat && stat->UnpackSize_Defined) prop = stat->OutSize; break;
+ case kpidClusterSize: if (_stat_defined && _stat.NumBlocks_Defined && stat->NumBlocks > 1) prop = _maxBlocksSize; break;
+ case kpidCharacts:
+ if (_firstBlockWasRead)
+ {
+ AString s;
+ if (XzBlock_HasPackSize(&_firstBlock))
+ s.Add_OptSpaced("BlockPackSize");
+ if (XzBlock_HasUnpackSize(&_firstBlock))
+ s.Add_OptSpaced("BlockUnpackSize");
+ if (!s.IsEmpty())
+ prop = s;
+ }
+ break;
+
+
case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;
case kpidErrorFlags:
{
UInt32 v = 0;
- if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;;
- if (_stat.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
- if (_stat.DataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
- if (_stat.HeadersError) v |= kpv_ErrorFlags_HeadersError;
- if (_stat.Unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
- if (_stat.DataError) v |= kpv_ErrorFlags_DataError;
- if (_stat.CrcError) v |= kpv_ErrorFlags_CrcError;
- prop = v;
+ SRes sres = _stat2_decode_SRes;
+ if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
+ if (sres == SZ_ERROR_INPUT_EOF) v |= kpv_ErrorFlags_UnexpectedEnd;
+ if (_stat2_defined && _stat2.DataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
+ if (sres == SZ_ERROR_ARCHIVE) v |= kpv_ErrorFlags_HeadersError;
+ if (sres == SZ_ERROR_UNSUPPORTED) v |= kpv_ErrorFlags_UnsupportedMethod;
+ if (sres == SZ_ERROR_DATA) v |= kpv_ErrorFlags_DataError;
+ if (sres == SZ_ERROR_CRC) v |= kpv_ErrorFlags_CrcError;
+ if (v != 0)
+ prop = v;
+ break;
+ }
+
+ case kpidMainSubfile:
+ {
+ // debug only, comment it:
+ // if (_blocks) prop = (UInt32)0;
+ break;
}
}
prop.Detach(value);
@@ -330,20 +393,21 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
COM_TRY_END
}
-STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
{
*numItems = 1;
return S_OK;
}
-STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)
+Z7_COM7F_IMF(CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value))
{
COM_TRY_BEGIN
+ const CXzStatInfo *stat = GetStat();
NCOM::CPropVariant prop;
switch (propID)
{
- case kpidSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break;
- case kpidPackSize: if (_phySize_Defined) prop = _stat.PhySize; break;
+ case kpidSize: if (stat && stat->UnpackSize_Defined) prop = stat->OutSize; break;
+ case kpidPackSize: if (stat) prop = stat->InSize; break;
case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;
}
prop.Detach(value);
@@ -354,27 +418,30 @@ STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)
struct COpenCallbackWrap
{
- ICompressProgress p;
+ ICompressProgress vt;
IArchiveOpenCallback *OpenCallback;
HRESULT Res;
- COpenCallbackWrap(IArchiveOpenCallback *progress);
+
+ // new clang shows "non-POD" warning for offsetof(), if we use constructor instead of Init()
+ void Init(IArchiveOpenCallback *progress);
};
-static SRes OpenCallbackProgress(void *pp, UInt64 inSize, UInt64 /* outSize */)
+static SRes OpenCallbackProgress(ICompressProgressPtr pp, UInt64 inSize, UInt64 /* outSize */)
{
- COpenCallbackWrap *p = (COpenCallbackWrap *)pp;
+ Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(COpenCallbackWrap)
if (p->OpenCallback)
p->Res = p->OpenCallback->SetCompleted(NULL, &inSize);
- return (SRes)p->Res;
+ return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS);
}
-COpenCallbackWrap::COpenCallbackWrap(IArchiveOpenCallback *callback)
+void COpenCallbackWrap::Init(IArchiveOpenCallback *callback)
{
- p.Progress = OpenCallbackProgress;
+ vt.Progress = OpenCallbackProgress;
OpenCallback = callback;
Res = SZ_OK;
}
+
struct CXzsCPP
{
CXzs p;
@@ -382,6 +449,30 @@ struct CXzsCPP
~CXzsCPP() { Xzs_Free(&p, &g_Alloc); }
};
+#define kInputBufSize ((size_t)1 << 10)
+
+struct CLookToRead2_CPP: public CLookToRead2
+{
+ CLookToRead2_CPP()
+ {
+ buf = NULL;
+ LookToRead2_CreateVTable(this,
+ True // Lookahead ?
+ );
+ }
+ void Alloc(size_t allocSize)
+ {
+ buf = (Byte *)MyAlloc(allocSize);
+ if (buf)
+ this->bufSize = allocSize;
+ }
+ ~CLookToRead2_CPP()
+ {
+ MyFree(buf);
+ }
+};
+
+
static HRESULT SRes_to_Open_HRESULT(SRes res)
{
switch (res)
@@ -401,49 +492,90 @@ static HRESULT SRes_to_Open_HRESULT(SRes res)
return S_FALSE;
}
+
+
HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback)
{
_needSeekToStart = true;
{
CXzStreamFlags st;
- CSeqInStreamWrap inStreamWrap(inStream);
- SRes res = Xz_ReadHeader(&st, &inStreamWrap.p);
+ CSeqInStreamWrap inStreamWrap;
+
+ inStreamWrap.Init(inStream);
+
+ SRes res = Xz_ReadHeader(&st, &inStreamWrap.vt);
+
+ if (inStreamWrap.Res != S_OK)
+ return inStreamWrap.Res;
if (res != SZ_OK)
return SRes_to_Open_HRESULT(res);
{
CXzBlock block;
- Bool isIndex;
+ BoolInt isIndex;
UInt32 headerSizeRes;
- SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.p, &isIndex, &headerSizeRes);
- if (res2 == SZ_OK && !isIndex)
+
+ SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.vt, &isIndex, &headerSizeRes);
+
+ if (inStreamWrap.Res != S_OK)
+ return inStreamWrap.Res;
+
+ if (res2 != SZ_OK)
{
+ if (res2 == SZ_ERROR_INPUT_EOF)
+ {
+ _stat2_decode_SRes = res2;
+ _stream = inStream;
+ _seqStream = inStream;
+ _isArc = true;
+ return S_OK;
+ }
+
+ if (res2 == SZ_ERROR_ARCHIVE)
+ return S_FALSE;
+ }
+ else if (!isIndex)
+ {
+ _firstBlockWasRead = true;
+ _firstBlock = block;
+
unsigned numFilters = XzBlock_GetNumFilters(&block);
for (unsigned i = 0; i < numFilters; i++)
- AddString(_methodsString, GetMethodString(block.filters[i]));
+ {
+ _methodsString.Add_Space_if_NotEmpty();
+ AddMethodString(_methodsString, block.filters[i]);
+ }
}
}
}
- RINOK(inStream->Seek(0, STREAM_SEEK_END, &_stat.PhySize));
+ RINOK(InStream_GetSize_SeekToEnd(inStream, _stat.InSize))
if (callback)
{
- RINOK(callback->SetTotal(NULL, &_stat.PhySize));
+ RINOK(callback->SetTotal(NULL, &_stat.InSize))
}
- CSeekInStreamWrap inStreamImp(inStream);
+ CSeekInStreamWrap inStreamImp;
+
+ inStreamImp.Init(inStream);
+
+ CLookToRead2_CPP lookStream;
+
+ lookStream.Alloc(kInputBufSize);
+
+ if (!lookStream.buf)
+ return E_OUTOFMEMORY;
- CLookToRead lookStream;
- LookToRead_CreateVTable(&lookStream, True);
- lookStream.realStream = &inStreamImp.p;
- LookToRead_Init(&lookStream);
+ lookStream.realStream = &inStreamImp.vt;
+ LookToRead2_INIT(&lookStream)
- COpenCallbackWrap openWrap(callback);
+ COpenCallbackWrap openWrap;
+ openWrap.Init(callback);
CXzsCPP xzs;
Int64 startPosition;
- SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.s, &startPosition, &openWrap.p, &g_Alloc);
+ SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.vt, &startPosition, &openWrap.vt, &g_Alloc);
if (res == SZ_ERROR_PROGRESS)
return (openWrap.Res == S_OK) ? E_FAIL : openWrap.Res;
/*
@@ -452,7 +584,7 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
*/
if (res == SZ_OK && startPosition == 0)
{
- _phySize_Defined = true;
+ _stat_defined = true;
_stat.OutSize = Xzs_GetUnpackSize(&xzs.p);
_stat.UnpackSize_Defined = true;
@@ -463,21 +595,81 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
_stat.NumBlocks = Xzs_GetNumBlocks(&xzs.p);
_stat.NumBlocks_Defined = true;
- AddString(_methodsString, GetCheckString(xzs.p));
+ AddCheckString(_methodsString, xzs.p);
+
+ const size_t numBlocks = (size_t)_stat.NumBlocks + 1;
+ const size_t bytesAlloc = numBlocks * sizeof(CBlockInfo);
+
+ if (bytesAlloc / sizeof(CBlockInfo) == _stat.NumBlocks + 1)
+ {
+ _blocks = (CBlockInfo *)MyAlloc(bytesAlloc);
+ if (_blocks)
+ {
+ unsigned blockIndex = 0;
+ UInt64 unpackPos = 0;
+
+ for (size_t si = xzs.p.num; si != 0;)
+ {
+ si--;
+ const CXzStream &str = xzs.p.streams[si];
+ UInt64 packPos = str.startOffset + XZ_STREAM_HEADER_SIZE;
+
+ for (size_t bi = 0; bi < str.numBlocks; bi++)
+ {
+ const CXzBlockSizes &bs = str.blocks[bi];
+ const UInt64 packSizeAligned = bs.totalSize + ((0 - (unsigned)bs.totalSize) & 3);
+
+ if (bs.unpackSize != 0)
+ {
+ if (blockIndex >= _stat.NumBlocks)
+ return E_FAIL;
+
+ CBlockInfo &block = _blocks[blockIndex++];
+ block.StreamFlags = str.flags;
+ block.PackSize = bs.totalSize; // packSizeAligned;
+ block.PackPos = packPos;
+ block.UnpackPos = unpackPos;
+ }
+ packPos += packSizeAligned;
+ unpackPos += bs.unpackSize;
+ if (_maxBlocksSize < bs.unpackSize)
+ _maxBlocksSize = bs.unpackSize;
+ }
+ }
+
+ /*
+ if (blockIndex != _stat.NumBlocks)
+ {
+ // there are Empty blocks;
+ }
+ */
+ if (_stat.OutSize != unpackPos)
+ return E_FAIL;
+ CBlockInfo &block = _blocks[blockIndex++];
+ block.StreamFlags = 0;
+ block.PackSize = 0;
+ block.PackPos = 0;
+ block.UnpackPos = unpackPos;
+ _blocksArraySize = blockIndex;
+ }
+ }
}
else
{
res = SZ_OK;
}
- RINOK(SRes_to_Open_HRESULT(res));
+ RINOK(SRes_to_Open_HRESULT(res))
+
_stream = inStream;
_seqStream = inStream;
_isArc = true;
return S_OK;
}
-STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)
+
+
+Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback))
{
COM_TRY_BEGIN
{
@@ -487,7 +679,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCal
COM_TRY_END
}
-STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
+Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream))
{
Close();
_seqStream = stream;
@@ -496,206 +688,340 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
return S_OK;
}
-STDMETHODIMP CHandler::Close()
+Z7_COM7F_IMF(CHandler::Close())
{
- _stat.Clear();
+ XzStatInfo_Clear(&_stat);
+ XzStatInfo_Clear(&_stat2);
+ _stat_defined = false;
+ _stat2_defined = false;
+ _stat2_decode_SRes = SZ_OK;
_isArc = false;
_needSeekToStart = false;
+ _firstBlockWasRead = false;
- _phySize_Defined = false;
-
_methodsString.Empty();
_stream.Release();
_seqStream.Release();
+
+ MyFree(_blocks);
+ _blocks = NULL;
+ _blocksArraySize = 0;
+ _maxBlocksSize = 0;
+
return S_OK;
}
-class CSeekToSeqStream:
- public IInStream,
- public CMyUnknownImp
-{
-public:
- CMyComPtr<ISequentialInStream> Stream;
- MY_UNKNOWN_IMP1(IInStream)
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+struct CXzUnpackerCPP2
+{
+ Byte *InBuf;
+ // Byte *OutBuf;
+ CXzUnpacker p;
+
+ CXzUnpackerCPP2();
+ ~CXzUnpackerCPP2();
};
-STDMETHODIMP CSeekToSeqStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+CXzUnpackerCPP2::CXzUnpackerCPP2(): InBuf(NULL)
+ // , OutBuf(NULL)
{
- return Stream->Read(data, size, processedSize);
+ XzUnpacker_Construct(&p, &g_Alloc);
}
-STDMETHODIMP CSeekToSeqStream::Seek(Int64, UInt32, UInt64 *) { return E_NOTIMPL; }
-
-CXzUnpackerCPP::CXzUnpackerCPP(): InBuf(0), OutBuf(0)
+CXzUnpackerCPP2::~CXzUnpackerCPP2()
{
- XzUnpacker_Construct(&p, &g_Alloc);
+ XzUnpacker_Free(&p);
+ MidFree(InBuf);
+ // MidFree(OutBuf);
}
-CXzUnpackerCPP::~CXzUnpackerCPP()
+
+Z7_CLASS_IMP_COM_1(
+ CInStream
+ , IInStream
+)
+ Z7_IFACE_COM7_IMP(ISequentialInStream)
+
+ UInt64 _virtPos;
+public:
+ UInt64 Size;
+ UInt64 _cacheStartPos;
+ size_t _cacheSize;
+ CByteBuffer _cache;
+ // UInt64 _startPos;
+ CXzUnpackerCPP2 xz;
+
+ void InitAndSeek()
+ {
+ _virtPos = 0;
+ _cacheStartPos = 0;
+ _cacheSize = 0;
+ // _startPos = startPos;
+ }
+
+ CHandler *_handlerSpec;
+ CMyComPtr<IUnknown> _handler;
+
+ // ~CInStream();
+};
+
+/*
+CInStream::~CInStream()
{
- XzUnpacker_Free(&p);
- MyFree(InBuf);
- MyFree(OutBuf);
+ // _cache.Free();
}
+*/
-HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
+static size_t FindBlock(const CBlockInfo *blocks, size_t numBlocks, UInt64 pos)
{
- const size_t kInBufSize = 1 << 15;
- const size_t kOutBufSize = 1 << 21;
+ size_t left = 0, right = numBlocks;
+ for (;;)
+ {
+ size_t mid = (left + right) / 2;
+ if (mid == left)
+ return left;
+ if (pos < blocks[mid].UnpackPos)
+ right = mid;
+ else
+ left = mid;
+ }
+}
+
- Clear();
- DecodeRes = SZ_OK;
+
+static HRESULT DecodeBlock(CXzUnpackerCPP2 &xzu,
+ ISequentialInStream *seqInStream,
+ unsigned streamFlags,
+ UInt64 packSize, // pure size from Index record, it doesn't include pad zeros
+ size_t unpackSize, Byte *dest
+ // , ICompressProgressInfo *progress
+ )
+{
+ const size_t kInBufSize = (size_t)1 << 16;
XzUnpacker_Init(&xzu.p);
+
if (!xzu.InBuf)
- xzu.InBuf = (Byte *)MyAlloc(kInBufSize);
- if (!xzu.OutBuf)
- xzu.OutBuf = (Byte *)MyAlloc(kOutBufSize);
+ {
+ xzu.InBuf = (Byte *)MidAlloc(kInBufSize);
+ if (!xzu.InBuf)
+ return E_OUTOFMEMORY;
+ }
+ xzu.p.streamFlags = (UInt16)streamFlags;
+ XzUnpacker_PrepareToRandomBlockDecoding(&xzu.p);
+
+ XzUnpacker_SetOutBuf(&xzu.p, dest, unpackSize);
+
+ const UInt64 packSizeAligned = packSize + ((0 - (unsigned)packSize) & 3);
+ UInt64 packRem = packSizeAligned;
+
UInt32 inSize = 0;
SizeT inPos = 0;
SizeT outPos = 0;
+ HRESULT readRes = S_OK;
+
for (;;)
{
- if (inPos == inSize)
+ if (inPos == inSize && readRes == S_OK)
{
- inPos = inSize = 0;
- RINOK(seqInStream->Read(xzu.InBuf, kInBufSize, &inSize));
+ inPos = 0;
+ inSize = 0;
+ UInt32 rem = kInBufSize;
+ if (rem > packRem)
+ rem = (UInt32)packRem;
+ if (rem != 0)
+ readRes = seqInStream->Read(xzu.InBuf, rem, &inSize);
}
SizeT inLen = inSize - inPos;
- SizeT outLen = kOutBufSize - outPos;
- ECoderStatus status;
+ SizeT outLen = unpackSize - outPos;
- SRes res = XzUnpacker_Code(&xzu.p,
- xzu.OutBuf + outPos, &outLen,
+ ECoderStatus status;
+
+ const SRes res = XzUnpacker_Code(&xzu.p,
+ // dest + outPos,
+ NULL,
+ &outLen,
xzu.InBuf + inPos, &inLen,
- (inSize == 0 ? CODER_FINISH_END : CODER_FINISH_ANY), &status);
+ (inLen == 0), // srcFinished
+ CODER_FINISH_END, &status);
- inPos += inLen;
- outPos += outLen;
+ // return E_OUTOFMEMORY;
+ // res = SZ_ERROR_CRC;
- InSize += inLen;
- OutSize += outLen;
+ if (res != SZ_OK)
+ {
+ if (res == SZ_ERROR_CRC)
+ return S_FALSE;
+ return SResToHRESULT(res);
+ }
- DecodeRes = res;
+ inPos += inLen;
+ outPos += outLen;
- bool finished = ((inLen == 0 && outLen == 0) || res != SZ_OK);
+ packRem -= inLen;
+
+ const BoolInt blockFinished = XzUnpacker_IsBlockFinished(&xzu.p);
- if (outStream)
+ if ((inLen == 0 && outLen == 0) || blockFinished)
{
- if (outPos == kOutBufSize || finished)
- {
- if (outPos != 0)
- {
- RINOK(WriteStream(outStream, xzu.OutBuf, outPos));
- outPos = 0;
- }
- }
+ if (packRem != 0 || !blockFinished || unpackSize != outPos)
+ return S_FALSE;
+ if (XzUnpacker_GetPackSizeForIndex(&xzu.p) != packSize)
+ return S_FALSE;
+ return S_OK;
}
- else
- outPos = 0;
-
- if (progress)
+ }
+}
+
+
+Z7_COM7F_IMF(CInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
+{
+ COM_TRY_BEGIN
+
+ if (processedSize)
+ *processedSize = 0;
+ if (size == 0)
+ return S_OK;
+
+ {
+ if (_virtPos >= Size)
+ return S_OK; // (Size == _virtPos) ? S_OK: E_FAIL;
{
- RINOK(progress->SetRatioInfo(&InSize, &OutSize));
+ UInt64 rem = Size - _virtPos;
+ if (size > rem)
+ size = (UInt32)rem;
}
-
- if (finished)
- {
- PhySize = InSize;
- NumStreams = xzu.p.numStartedStreams;
- if (NumStreams > 0)
- IsArc = true;
- NumBlocks = xzu.p.numTotalBlocks;
+ }
- UnpackSize_Defined = true;
- NumStreams_Defined = true;
- NumBlocks_Defined = true;
+ if (size == 0)
+ return S_OK;
- UInt64 extraSize = XzUnpacker_GetExtraSize(&xzu.p);
+ if (_virtPos < _cacheStartPos || _virtPos >= _cacheStartPos + _cacheSize)
+ {
+ const size_t bi = FindBlock(_handlerSpec->_blocks, _handlerSpec->_blocksArraySize, _virtPos);
+ const CBlockInfo &block = _handlerSpec->_blocks[bi];
+ const UInt64 unpackSize = _handlerSpec->_blocks[bi + 1].UnpackPos - block.UnpackPos;
+ if (_cache.Size() < unpackSize)
+ return E_FAIL;
- if (res == SZ_OK)
- {
- if (status == CODER_STATUS_NEEDS_MORE_INPUT)
- {
- extraSize = 0;
- if (!XzUnpacker_IsStreamWasFinished(&xzu.p))
- {
- // finished at padding bytes, but padding is not aligned for 4
- UnexpectedEnd = true;
- res = SZ_ERROR_DATA;
- }
- }
- else // status == CODER_STATUS_NOT_FINISHED
- res = SZ_ERROR_DATA;
- }
- else if (res == SZ_ERROR_NO_ARCHIVE)
- {
- if (InSize == extraSize)
- IsArc = false;
- else
- {
- if (extraSize != 0 || inPos != inSize)
- {
- DataAfterEnd = true;
- res = SZ_OK;
- }
- }
- }
+ _cacheSize = 0;
- DecodeRes = res;
- PhySize -= extraSize;
+ RINOK(_handlerSpec->SeekToPackPos(block.PackPos))
+ RINOK(DecodeBlock(xz, _handlerSpec->_seqStream, block.StreamFlags, block.PackSize,
+ (size_t)unpackSize, _cache))
+ _cacheStartPos = block.UnpackPos;
+ _cacheSize = (size_t)unpackSize;
+ }
- switch (res)
- {
- case SZ_OK: break;
- case SZ_ERROR_NO_ARCHIVE: IsArc = false; break;
- case SZ_ERROR_ARCHIVE: HeadersError = true; break;
- case SZ_ERROR_UNSUPPORTED: Unsupported = true; break;
- case SZ_ERROR_CRC: CrcError = true; break;
- case SZ_ERROR_DATA: DataError = true; break;
- default: DataError = true; break;
- }
+ {
+ const size_t offset = (size_t)(_virtPos - _cacheStartPos);
+ const size_t rem = _cacheSize - offset;
+ if (size > rem)
+ size = (UInt32)rem;
+ memcpy(data, _cache + offset, size);
+ _virtPos += size;
+ if (processedSize)
+ *processedSize = size;
+ return S_OK;
+ }
- break;
- }
+ COM_TRY_END
+}
+
+
+Z7_COM7F_IMF(CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
+{
+ switch (seekOrigin)
+ {
+ case STREAM_SEEK_SET: break;
+ case STREAM_SEEK_CUR: offset += _virtPos; break;
+ case STREAM_SEEK_END: offset += Size; break;
+ default: return STG_E_INVALIDFUNCTION;
}
+ if (offset < 0)
+ return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
+ _virtPos = (UInt64)offset;
+ if (newPosition)
+ *newPosition = (UInt64)offset;
+ return S_OK;
+}
+
+
+
+static const UInt64 kMaxBlockSize_for_GetStream = (UInt64)1 << 40;
+
+Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream))
+{
+ COM_TRY_BEGIN
+
+ *stream = NULL;
+
+ if (index != 0)
+ return E_INVALIDARG;
+
+ if (!_stat.UnpackSize_Defined
+ || _maxBlocksSize == 0 // 18.02
+ || _maxBlocksSize > kMaxBlockSize_for_GetStream
+ || _maxBlocksSize != (size_t)_maxBlocksSize)
+ return S_FALSE;
+ UInt64 memSize;
+ if (!NSystem::GetRamSize(memSize))
+ memSize = (UInt64)(sizeof(size_t)) << 28;
+ {
+ if (_maxBlocksSize > memSize / 4)
+ return S_FALSE;
+ }
+
+ CInStream *spec = new CInStream;
+ CMyComPtr<ISequentialInStream> specStream = spec;
+ spec->_cache.Alloc((size_t)_maxBlocksSize);
+ spec->_handlerSpec = this;
+ spec->_handler = (IInArchive *)this;
+ spec->Size = _stat.OutSize;
+ spec->InitAndSeek();
+
+ *stream = specStream.Detach();
return S_OK;
+
+ COM_TRY_END
}
-Int32 CDecoder::Get_Extract_OperationResult() const
+
+static Int32 Get_Extract_OperationResult(const NCompress::NXz::CDecoder &decoder)
{
Int32 opRes;
- if (!IsArc)
+ SRes sres = decoder.MainDecodeSRes;
+ if (sres == SZ_ERROR_NO_ARCHIVE) // (!IsArc)
opRes = NExtract::NOperationResult::kIsNotArc;
- else if (UnexpectedEnd)
+ else if (sres == SZ_ERROR_INPUT_EOF) // (UnexpectedEnd)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
- else if (DataAfterEnd)
+ else if (decoder.Stat.DataAfterEnd)
opRes = NExtract::NOperationResult::kDataAfterEnd;
- else if (CrcError)
+ else if (sres == SZ_ERROR_CRC) // (CrcError)
opRes = NExtract::NOperationResult::kCRCError;
- else if (Unsupported)
+ else if (sres == SZ_ERROR_UNSUPPORTED) // (Unsupported)
opRes = NExtract::NOperationResult::kUnsupportedMethod;
- else if (HeadersError)
+ else if (sres == SZ_ERROR_ARCHIVE) // (HeadersError)
opRes = NExtract::NOperationResult::kDataError;
- else if (DataError)
+ else if (sres == SZ_ERROR_DATA) // (DataError)
opRes = NExtract::NOperationResult::kDataError;
- else if (DecodeRes != SZ_OK)
+ else if (sres != SZ_OK)
opRes = NExtract::NOperationResult::kDataError;
else
opRes = NExtract::NOperationResult::kOK;
return opRes;
}
-STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
- Int32 testMode, IArchiveExtractCallback *extractCallback)
+
+
+
+Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback))
{
COM_TRY_BEGIN
if (numItems == 0)
@@ -703,17 +1029,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
- if (_phySize_Defined)
- extractCallback->SetTotal(_stat.PhySize);
+ const CXzStatInfo *stat = GetStat();
+
+ if (stat)
+ extractCallback->SetTotal(stat->InSize);
UInt64 currentTotalPacked = 0;
- RINOK(extractCallback->SetCompleted(&currentTotalPacked));
+ RINOK(extractCallback->SetCompleted(&currentTotalPacked))
CMyComPtr<ISequentialOutStream> realOutStream;
- Int32 askMode = testMode ?
+ const Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
- RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
+ RINOK(extractCallback->GetStream(0, &realOutStream, askMode))
if (!testMode && !realOutStream)
return S_OK;
@@ -728,55 +1056,76 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
if (!_stream)
return E_FAIL;
- RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(InStream_SeekToBegin(_stream))
}
else
_needSeekToStart = true;
- CDecoder decoder;
- RINOK(Decode2(_seqStream, realOutStream, decoder, lpsRef));
- Int32 opRes = decoder.Get_Extract_OperationResult();
+
+ NCompress::NXz::CDecoder decoder;
+
+ HRESULT hres = Decode(decoder, _seqStream, realOutStream, lpsRef);
+
+ if (!decoder.MainDecodeSRes_wasUsed)
+ return hres == S_OK ? E_FAIL : hres;
+
+ Int32 opRes = Get_Extract_OperationResult(decoder);
+ if (opRes == NExtract::NOperationResult::kOK
+ && hres != S_OK)
+ opRes = NExtract::NOperationResult::kDataError;
realOutStream.Release();
return extractCallback->SetOperationResult(opRes);
COM_TRY_END
}
-#ifndef EXTRACT_ONLY
-STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
+
+#ifndef Z7_EXTRACT_ONLY
+
+Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType))
{
- *timeType = NFileTimeType::kUnix;
+ *timeType = GET_FileTimeType_NotDefined_for_GetFileTimeType;
+ // *timeType = NFileTimeType::kUnix;
return S_OK;
}
-STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
- IArchiveUpdateCallback *updateCallback)
+
+Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback))
{
COM_TRY_BEGIN
- CSeqOutStreamWrap seqOutStream(outStream);
-
if (numItems == 0)
{
- SRes res = Xz_EncodeEmpty(&seqOutStream.p);
+ CSeqOutStreamWrap seqOutStream;
+ seqOutStream.Init(outStream);
+ SRes res = Xz_EncodeEmpty(&seqOutStream.vt);
return SResToHRESULT(res);
}
if (numItems != 1)
return E_INVALIDARG;
+ {
+ Z7_DECL_CMyComPtr_QI_FROM(
+ IStreamSetRestriction,
+ setRestriction, outStream)
+ if (setRestriction)
+ RINOK(setRestriction->SetRestriction(0, 0))
+ }
+
Int32 newData, newProps;
UInt32 indexInArchive;
if (!updateCallback)
return E_FAIL;
- RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive));
+ RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive))
if (IntToBool(newProps))
{
{
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop));
+ RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop))
if (prop.vt != VT_EMPTY)
if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE)
return E_INVALIDARG;
@@ -785,101 +1134,173 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (IntToBool(newData))
{
- UInt64 size;
+ UInt64 dataSize;
{
NCOM::CPropVariant prop;
- RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
+ RINOK(updateCallback->GetProperty(0, kpidSize, &prop))
if (prop.vt != VT_UI8)
return E_INVALIDARG;
- size = prop.uhVal.QuadPart;
- RINOK(updateCallback->SetTotal(size));
+ dataSize = prop.uhVal.QuadPart;
}
- CLzma2EncProps lzma2Props;
- Lzma2EncProps_Init(&lzma2Props);
-
- lzma2Props.lzmaProps.level = GetLevel();
+ NCompress::NXz::CEncoder *encoderSpec = new NCompress::NXz::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
- CMyComPtr<ISequentialInStream> fileInStream;
- RINOK(updateCallback->GetStream(0, &fileInStream));
+ CXzProps &xzProps = encoderSpec->xzProps;
+ CLzma2EncProps &lzma2Props = xzProps.lzma2Props;
- CSeqInStreamWrap seqInStream(fileInStream);
+ lzma2Props.lzmaProps.level = GetLevel();
+ xzProps.reduceSize = dataSize;
+ /*
{
- NCOM::CPropVariant prop = (UInt64)size;
- RINOK(NCompress::NLzma2::SetLzma2Prop(NCoderPropID::kReduceSize, prop, lzma2Props));
+ NCOM::CPropVariant prop = (UInt64)dataSize;
+ RINOK(encoderSpec->SetCoderProp(NCoderPropID::kReduceSize, prop))
}
+ */
- FOR_VECTOR (i, _methods)
+ #ifndef Z7_ST
+
+ UInt32 numThreads = _numThreads;
+
+ const UInt32 kNumThreads_Max = 1024;
+ if (numThreads > kNumThreads_Max)
+ numThreads = kNumThreads_Max;
+
+ if (!_numThreads_WasForced
+ && _numThreads >= 1
+ && _memUsage_WasSet)
{
- COneMethodInfo &m = _methods[i];
- SetGlobalLevelAndThreads(m
- #ifndef _7ZIP_ST
- , _numThreads
- #endif
- );
+ COneMethodInfo oneMethodInfo;
+ if (!_methods.IsEmpty())
+ oneMethodInfo = _methods[0];
+
+ SetGlobalLevelTo(oneMethodInfo);
+
+ const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0);
+ if (!numThreads_WasSpecifiedInMethod)
{
- FOR_VECTOR (j, m.Props)
+ // here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already
+ CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, numThreads);
+ }
+
+ UInt64 cs = _numSolidBytes;
+ if (cs != XZ_PROPS_BLOCK_SIZE_AUTO)
+ oneMethodInfo.AddProp_BlockSize2(cs);
+ cs = oneMethodInfo.Get_Xz_BlockSize();
+
+ if (cs != XZ_PROPS_BLOCK_SIZE_AUTO &&
+ cs != XZ_PROPS_BLOCK_SIZE_SOLID)
+ {
+ const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads();
+ const UInt32 numBlockThreads_Original = numThreads / lzmaThreads;
+
+ if (numBlockThreads_Original > 1)
{
- const CProp &prop = m.Props[j];
- RINOK(NCompress::NLzma2::SetLzma2Prop(prop.Id, prop.Value, lzma2Props));
+ UInt32 numBlockThreads = numBlockThreads_Original;
+ {
+ const UInt64 lzmaMemUsage = oneMethodInfo.Get_Lzma_MemUsage(false);
+ for (; numBlockThreads > 1; numBlockThreads--)
+ {
+ UInt64 size = numBlockThreads * (lzmaMemUsage + cs);
+ UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1;
+ if (cs < ((UInt32)1 << 26)) numPackChunks++;
+ if (cs < ((UInt32)1 << 24)) numPackChunks++;
+ if (cs < ((UInt32)1 << 22)) numPackChunks++;
+ size += numPackChunks * cs;
+ // printf("\nnumBlockThreads = %d, size = %d\n", (unsigned)(numBlockThreads), (unsigned)(size >> 20));
+ if (size <= _memUsage_Compress)
+ break;
+ }
+ }
+ if (numBlockThreads == 0)
+ numBlockThreads = 1;
+ if (numBlockThreads != numBlockThreads_Original)
+ numThreads = numBlockThreads * lzmaThreads;
}
}
}
+ xzProps.numTotalThreads = (int)numThreads;
- #ifndef _7ZIP_ST
- lzma2Props.numTotalThreads = _numThreads;
- #endif
+ #endif // Z7_ST
- CLocalProgress *lps = new CLocalProgress;
- CMyComPtr<ICompressProgressInfo> progress = lps;
- lps->Init(updateCallback, true);
-
- CCompressProgressWrap progressWrap(progress);
- CXzProps xzProps;
- CXzFilterProps filter;
- XzProps_Init(&xzProps);
- XzFilterProps_Init(&filter);
- xzProps.lzma2Props = &lzma2Props;
- xzProps.filterProps = (_filterId != 0 ? &filter : NULL);
- switch (_crcSize)
+
+ xzProps.blockSize = _numSolidBytes;
+ if (_numSolidBytes == XZ_PROPS_BLOCK_SIZE_SOLID)
{
- case 0: xzProps.checkId = XZ_CHECK_NO; break;
- case 4: xzProps.checkId = XZ_CHECK_CRC32; break;
- case 8: xzProps.checkId = XZ_CHECK_CRC64; break;
- case 32: xzProps.checkId = XZ_CHECK_SHA256; break;
- default: return E_INVALIDARG;
+ xzProps.lzma2Props.blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID;
}
- filter.id = _filterId;
- if (_filterId == XZ_ID_Delta)
+
+ RINOK(encoderSpec->SetCheckSize(_crcSize))
+
{
- bool deltaDefined = false;
- FOR_VECTOR (j, _filterMethod.Props)
+ CXzFilterProps &filter = xzProps.filterProps;
+
+ if (_filterId == XZ_ID_Delta)
{
- const CProp &prop = _filterMethod.Props[j];
- if (prop.Id == NCoderPropID::kDefaultProp && prop.Value.vt == VT_UI4)
+ bool deltaDefined = false;
+ FOR_VECTOR (j, _filterMethod.Props)
{
- UInt32 delta = (UInt32)prop.Value.ulVal;
- if (delta < 1 || delta > 256)
+ const CProp &prop = _filterMethod.Props[j];
+ if (prop.Id == NCoderPropID::kDefaultProp && prop.Value.vt == VT_UI4)
+ {
+ UInt32 delta = (UInt32)prop.Value.ulVal;
+ if (delta < 1 || delta > 256)
+ return E_INVALIDARG;
+ filter.delta = delta;
+ deltaDefined = true;
+ }
+ else
return E_INVALIDARG;
- filter.delta = delta;
- deltaDefined = true;
}
+ if (!deltaDefined)
+ return E_INVALIDARG;
}
- if (!deltaDefined)
- return E_INVALIDARG;
+ filter.id = _filterId;
}
- SRes res = Xz_Encode(&seqOutStream.p, &seqInStream.p, &xzProps, &progressWrap.p);
- if (res == SZ_OK)
- return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
- return SResToHRESULT(res);
+
+ FOR_VECTOR (i, _methods)
+ {
+ COneMethodInfo &m = _methods[i];
+
+ FOR_VECTOR (j, m.Props)
+ {
+ const CProp &prop = m.Props[j];
+ RINOK(encoderSpec->SetCoderProp(prop.Id, prop.Value))
+ }
+ }
+
+ {
+ CMyComPtr<ISequentialInStream> fileInStream;
+ RINOK(updateCallback->GetStream(0, &fileInStream))
+ if (!fileInStream)
+ return S_FALSE;
+ {
+ CMyComPtr<IStreamGetSize> streamGetSize;
+ fileInStream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
+ if (streamGetSize)
+ {
+ UInt64 size;
+ if (streamGetSize->GetSize(&size) == S_OK)
+ dataSize = size;
+ }
+ }
+ RINOK(updateCallback->SetTotal(dataSize))
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(updateCallback, true);
+ RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, progress))
+ }
+
+ return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
}
if (indexInArchive != 0)
return E_INVALIDARG;
- CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
- updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
+ Z7_DECL_CMyComPtr_QI_FROM(
+ IArchiveUpdateCallbackFile,
+ opCallback, updateCallback)
if (opCallback)
{
RINOK(opCallback->ReportOperation(NEventIndexType::kInArcIndex, 0, NUpdateNotifyOp::kReplicate))
@@ -887,9 +1308,12 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (_stream)
{
- if (_phySize_Defined)
- RINOK(updateCallback->SetTotal(_stat.PhySize));
- RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
+ const CXzStatInfo *stat = GetStat();
+ if (stat)
+ {
+ RINOK(updateCallback->SetTotal(stat->InSize))
+ }
+ RINOK(InStream_SeekToBegin(_stream))
}
CLocalProgress *lps = new CLocalProgress;
@@ -901,20 +1325,80 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
COM_TRY_END
}
-STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
+#endif
+
+
+HRESULT CHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
+{
+ UString name = nameSpec;
+ name.MakeLower_Ascii();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+
+ #ifndef Z7_EXTRACT_ONLY
+
+ if (name[0] == L's')
+ {
+ const wchar_t *s = name.Ptr(1);
+ if (*s == 0)
+ {
+ bool useStr = false;
+ bool isSolid;
+ switch (value.vt)
+ {
+ case VT_EMPTY: isSolid = true; break;
+ case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break;
+ case VT_BSTR:
+ if (!StringToBool(value.bstrVal, isSolid))
+ useStr = true;
+ break;
+ default: return E_INVALIDARG;
+ }
+ if (!useStr)
+ {
+ _numSolidBytes = (isSolid ? XZ_PROPS_BLOCK_SIZE_SOLID : XZ_PROPS_BLOCK_SIZE_AUTO);
+ return S_OK;
+ }
+ }
+ return ParseSizeString(s, value,
+ 0, // percentsBase
+ _numSolidBytes) ? S_OK: E_INVALIDARG;
+ }
+
+ return CMultiMethodProps::SetProperty(name, value);
+
+ #else
+
+ {
+ HRESULT hres;
+ if (SetCommonProperty(name, value, hres))
+ return hres;
+ }
+
+ return E_INVALIDARG;
+
+ #endif
+}
+
+
+
+Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
{
COM_TRY_BEGIN
Init();
+
for (UInt32 i = 0; i < numProps; i++)
{
- RINOK(SetProperty(names[i], values[i]));
+ RINOK(SetProperty(names[i], values[i]))
}
+ #ifndef Z7_EXTRACT_ONLY
+
if (!_filterMethod.MethodName.IsEmpty())
{
unsigned k;
- for (k = 0; k < ARRAY_SIZE(g_NamePairs); k++)
+ for (k = 0; k < Z7_ARRAY_SIZE(g_NamePairs); k++)
{
const CMethodNamePair &pair = g_NamePairs[k];
if (StringsAreEqualNoCase_Ascii(_filterMethod.MethodName, pair.Name))
@@ -923,7 +1407,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
break;
}
}
- if (k == ARRAY_SIZE(g_NamePairs))
+ if (k == Z7_ARRAY_SIZE(g_NamePairs))
return E_INVALIDARG;
}
@@ -935,22 +1419,25 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
AString &methodName = _methods[0].MethodName;
if (methodName.IsEmpty())
methodName = k_LZMA2_Name;
- else if (!methodName.IsEqualTo_Ascii_NoCase(k_LZMA2_Name))
+ else if (
+ !methodName.IsEqualTo_Ascii_NoCase(k_LZMA2_Name)
+ && !methodName.IsEqualTo_Ascii_NoCase("xz"))
return E_INVALIDARG;
}
+ #endif
+
return S_OK;
COM_TRY_END
}
-#endif
REGISTER_ARC_IO(
"xz", "xz txz", "* .tar", 0xC,
- XZ_SIG,
- 0,
- NArcInfoFlags::kKeepName,
- NULL)
+ XZ_SIG, 0
+ , NArcInfoFlags::kKeepName
+ , 0
+ , NULL)
}}
diff --git a/3rdparty/lzma/CPP/7zip/Archive/XzHandler.h b/3rdparty/lzma/CPP/7zip/Archive/XzHandler.h
index 4a59e356a85..4d099548936 100644
--- a/3rdparty/lzma/CPP/7zip/Archive/XzHandler.h
+++ b/3rdparty/lzma/CPP/7zip/Archive/XzHandler.h
@@ -1,65 +1,11 @@
// XzHandler.h
-#ifndef __XZ_HANDLER_H
-#define __XZ_HANDLER_H
-
-#include "../../../C/Xz.h"
-
-#include "../ICoder.h"
+#ifndef ZIP7_INC_XZ_HANDLER_H
+#define ZIP7_INC_XZ_HANDLER_H
namespace NArchive {
namespace NXz {
-struct CXzUnpackerCPP
-{
- Byte *InBuf;
- Byte *OutBuf;
- CXzUnpacker p;
-
- CXzUnpackerCPP();
- ~CXzUnpackerCPP();
-};
-
-struct CStatInfo
-{
- UInt64 InSize;
- UInt64 OutSize;
- UInt64 PhySize;
-
- UInt64 NumStreams;
- UInt64 NumBlocks;
-
- bool UnpackSize_Defined;
-
- bool NumStreams_Defined;
- bool NumBlocks_Defined;
-
- bool IsArc;
- bool UnexpectedEnd;
- bool DataAfterEnd;
- bool Unsupported;
- bool HeadersError;
- bool DataError;
- bool CrcError;
-
- CStatInfo() { Clear(); }
-
- void Clear();
-};
-
-struct CDecoder: public CStatInfo
-{
- CXzUnpackerCPP xzu;
- SRes DecodeRes; // it's not HRESULT
-
- CDecoder(): DecodeRes(SZ_OK) {}
-
- /* Decode() can return ERROR code only if there is progress or stream error.
- Decode() returns S_OK in case of xz decoding error, but DecodeRes and CStatInfo contain error information */
- HRESULT Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, ICompressProgressInfo *compressProgress);
- Int32 Get_Extract_OperationResult() const;
-};
-
}}
#endif