aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip
diff options
context:
space:
mode:
authorSen Jiang <senj@google.com>2018-05-02 18:54:43 -0700
committerSen Jiang <senj@google.com>2018-05-02 19:01:41 -0700
commit60f31b62204c0b25838ef36c5c2de187001efc6c (patch)
tree598a63536cfeda1e2c8d50a947bf33027be148b3 /CPP/7zip
parent9186d4157ac38b8c314ffe99ea031faff87de996 (diff)
downloadlzma-60f31b62204c0b25838ef36c5c2de187001efc6c.tar.gz
Update LZMA SDK to 18.05.
Downloaded from https://www.7-zip.org/a/lzma1805.7z Test: mma Change-Id: I95bf31512854191c040e94cc677794f9abc4c46a
Diffstat (limited to 'CPP/7zip')
-rw-r--r--CPP/7zip/Aes.mak2
-rw-r--r--CPP/7zip/Archive/7z/7zCompressionMode.h2
-rw-r--r--CPP/7zip/Archive/7z/7zDecode.cpp66
-rw-r--r--CPP/7zip/Archive/7z/7zDecode.h6
-rw-r--r--CPP/7zip/Archive/7z/7zEncode.cpp30
-rw-r--r--CPP/7zip/Archive/7z/7zExtract.cpp29
-rw-r--r--CPP/7zip/Archive/7z/7zFolderInStream.cpp15
-rw-r--r--CPP/7zip/Archive/7z/7zHandler.cpp21
-rw-r--r--CPP/7zip/Archive/7z/7zHandler.h40
-rw-r--r--CPP/7zip/Archive/7z/7zHandlerOut.cpp62
-rw-r--r--CPP/7zip/Archive/7z/7zIn.cpp138
-rw-r--r--CPP/7zip/Archive/7z/7zIn.h4
-rw-r--r--CPP/7zip/Archive/7z/7zItem.h47
-rw-r--r--CPP/7zip/Archive/7z/7zOut.cpp95
-rw-r--r--CPP/7zip/Archive/7z/7zOut.h32
-rw-r--r--CPP/7zip/Archive/7z/7zUpdate.cpp90
-rw-r--r--CPP/7zip/Archive/Common/CoderMixer2.cpp88
-rw-r--r--CPP/7zip/Archive/Common/CoderMixer2.h30
-rw-r--r--CPP/7zip/Archive/Common/HandlerOut.cpp165
-rw-r--r--CPP/7zip/Archive/Common/HandlerOut.h77
-rw-r--r--CPP/7zip/Archive/Common/ItemNameUtils.cpp78
-rw-r--r--CPP/7zip/Archive/Common/ItemNameUtils.h27
-rw-r--r--CPP/7zip/Archive/IArchive.h10
-rw-r--r--CPP/7zip/Archive/LzmaHandler.cpp78
-rw-r--r--CPP/7zip/Archive/SplitHandler.cpp2
-rw-r--r--CPP/7zip/Archive/XzHandler.cpp936
-rw-r--r--CPP/7zip/Archive/XzHandler.h54
-rw-r--r--CPP/7zip/Asm.mak2
-rw-r--r--CPP/7zip/Bundles/Alone7z/Alone.dsp92
-rw-r--r--CPP/7zip/Bundles/Alone7z/makefile9
-rw-r--r--CPP/7zip/Bundles/Alone7z/resource.rc4
-rw-r--r--CPP/7zip/Bundles/Format7zExtractR/makefile3
-rw-r--r--CPP/7zip/Bundles/Format7zR/makefile3
-rw-r--r--CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp47
-rw-r--r--CPP/7zip/Bundles/SFXCon/SFXCon.dsp34
-rw-r--r--CPP/7zip/Bundles/SFXCon/SfxCon.cpp32
-rw-r--r--CPP/7zip/Bundles/SFXCon/makefile6
-rw-r--r--CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp6
-rw-r--r--CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp6
-rw-r--r--CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp34
-rw-r--r--CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp24
-rw-r--r--CPP/7zip/Bundles/SFXSetup/makefile7
-rw-r--r--CPP/7zip/Bundles/SFXWin/SFXWin.dsp26
-rw-r--r--CPP/7zip/Bundles/SFXWin/SfxWin.cpp2
-rw-r--r--CPP/7zip/Bundles/SFXWin/makefile6
-rw-r--r--CPP/7zip/Common/CWrappers.cpp126
-rw-r--r--CPP/7zip/Common/CWrappers.h28
-rw-r--r--CPP/7zip/Common/CreateCoder.cpp113
-rw-r--r--CPP/7zip/Common/CreateCoder.h26
-rw-r--r--CPP/7zip/Common/FilePathAutoRename.cpp9
-rw-r--r--CPP/7zip/Common/FilterCoder.h9
-rw-r--r--CPP/7zip/Common/InBuffer.cpp28
-rw-r--r--CPP/7zip/Common/InBuffer.h4
-rw-r--r--CPP/7zip/Common/InOutTempBuffer.cpp2
-rw-r--r--CPP/7zip/Common/MethodProps.cpp75
-rw-r--r--CPP/7zip/Common/MethodProps.h86
-rw-r--r--CPP/7zip/Common/OutBuffer.h7
-rw-r--r--CPP/7zip/Compress/Bcj2Coder.cpp12
-rw-r--r--CPP/7zip/Compress/Bcj2Coder.h5
-rw-r--r--CPP/7zip/Compress/CopyCoder.cpp5
-rw-r--r--CPP/7zip/Compress/CopyCoder.h5
-rw-r--r--CPP/7zip/Compress/Lzma2Decoder.cpp391
-rw-r--r--CPP/7zip/Compress/Lzma2Decoder.h66
-rw-r--r--CPP/7zip/Compress/Lzma2Encoder.cpp65
-rw-r--r--CPP/7zip/Compress/Lzma2Encoder.h8
-rw-r--r--CPP/7zip/Compress/LzmaDecoder.cpp301
-rw-r--r--CPP/7zip/Compress/LzmaDecoder.h50
-rw-r--r--CPP/7zip/Compress/LzmaEncoder.cpp54
-rw-r--r--CPP/7zip/Compress/LzmaEncoder.h10
-rw-r--r--CPP/7zip/Compress/PpmdDecoder.cpp9
-rw-r--r--CPP/7zip/Compress/PpmdDecoder.h26
-rw-r--r--CPP/7zip/Compress/PpmdEncoder.cpp2
-rw-r--r--CPP/7zip/Compress/XzDecoder.cpp150
-rw-r--r--CPP/7zip/Compress/XzDecoder.h92
-rw-r--r--CPP/7zip/Compress/XzEncoder.cpp245
-rw-r--r--CPP/7zip/Compress/XzEncoder.h46
-rw-r--r--CPP/7zip/Crc.mak2
-rw-r--r--CPP/7zip/Crc64.mak2
-rw-r--r--CPP/7zip/Crypto/MyAes.h2
-rw-r--r--CPP/7zip/GuiCommon.rc3
-rw-r--r--CPP/7zip/Guid.txt4
-rw-r--r--CPP/7zip/ICoder.h60
-rw-r--r--CPP/7zip/LzmaDec.mak5
-rw-r--r--CPP/7zip/UI/Client7z/Client7z.cpp163
-rw-r--r--CPP/7zip/UI/Client7z/Client7z.dsp2
-rw-r--r--CPP/7zip/UI/Client7z/resource.rc2
-rw-r--r--CPP/7zip/UI/Common/ArchiveCommandLine.cpp278
-rw-r--r--CPP/7zip/UI/Common/ArchiveCommandLine.h21
-rw-r--r--CPP/7zip/UI/Common/ArchiveExtractCallback.cpp266
-rw-r--r--CPP/7zip/UI/Common/ArchiveExtractCallback.h73
-rw-r--r--CPP/7zip/UI/Common/ArchiveName.cpp2
-rw-r--r--CPP/7zip/UI/Common/Bench.cpp532
-rw-r--r--CPP/7zip/UI/Common/Bench.h17
-rw-r--r--CPP/7zip/UI/Common/DirItem.h35
-rw-r--r--CPP/7zip/UI/Common/EnumDirItems.cpp208
-rw-r--r--CPP/7zip/UI/Common/EnumDirItems.h20
-rw-r--r--CPP/7zip/UI/Common/Extract.cpp20
-rw-r--r--CPP/7zip/UI/Common/ExtractingFilePath.cpp87
-rw-r--r--CPP/7zip/UI/Common/ExtractingFilePath.h14
-rw-r--r--CPP/7zip/UI/Common/HashCalc.cpp8
-rw-r--r--CPP/7zip/UI/Common/HashCalc.h1
-rw-r--r--CPP/7zip/UI/Common/LoadCodecs.cpp26
-rw-r--r--CPP/7zip/UI/Common/OpenArchive.cpp48
-rw-r--r--CPP/7zip/UI/Common/OpenArchive.h19
-rw-r--r--CPP/7zip/UI/Common/PropIDUtils.cpp230
-rw-r--r--CPP/7zip/UI/Common/PropIDUtils.h4
-rw-r--r--CPP/7zip/UI/Common/Update.cpp274
-rw-r--r--CPP/7zip/UI/Common/Update.h2
-rw-r--r--CPP/7zip/UI/Common/UpdateCallback.cpp26
-rw-r--r--CPP/7zip/UI/Common/UpdateCallback.h17
-rw-r--r--CPP/7zip/UI/Common/UpdatePair.cpp9
-rw-r--r--CPP/7zip/UI/Common/UpdateProduce.cpp2
-rw-r--r--CPP/7zip/UI/Common/ZipRegistry.h7
-rw-r--r--CPP/7zip/UI/Console/Console.manifest13
-rw-r--r--CPP/7zip/UI/Console/ExtractCallbackConsole.cpp161
-rw-r--r--CPP/7zip/UI/Console/HashCon.cpp8
-rw-r--r--CPP/7zip/UI/Console/List.cpp127
-rw-r--r--CPP/7zip/UI/Console/Main.cpp119
-rw-r--r--CPP/7zip/UI/Console/MainAr.cpp14
-rw-r--r--CPP/7zip/UI/Console/OpenCallbackConsole.cpp12
-rw-r--r--CPP/7zip/UI/Console/OpenCallbackConsole.h7
-rw-r--r--CPP/7zip/UI/Console/PercentPrinter.cpp8
-rw-r--r--CPP/7zip/UI/Console/UpdateCallbackConsole.cpp68
-rw-r--r--CPP/7zip/UI/Console/UserInputUtils.cpp44
-rw-r--r--CPP/7zip/UI/Console/UserInputUtils.h7
-rw-r--r--CPP/7zip/UI/Console/resource.rc6
-rw-r--r--CPP/7zip/UI/FileManager/BrowseDialog.cpp37
-rw-r--r--CPP/7zip/UI/FileManager/ExtractCallback.cpp28
-rw-r--r--CPP/7zip/UI/FileManager/OverwriteDialog.cpp15
-rw-r--r--CPP/7zip/UI/FileManager/ProgressDialog.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/ProgressDialog2.cpp56
-rw-r--r--CPP/7zip/UI/FileManager/ProgressDialog2.h70
-rw-r--r--CPP/7zip/UI/FileManager/resource.h2
-rw-r--r--CPP/7zip/UI/GUI/ExtractDialog.cpp6
-rw-r--r--CPP/7zip/UI/GUI/ExtractGUI.cpp80
-rw-r--r--CPP/7zip/UI/GUI/HashGUI.h11
136 files changed, 5674 insertions, 2340 deletions
diff --git a/CPP/7zip/Aes.mak b/CPP/7zip/Aes.mak
index 7ce28cf..4d5e98b 100644
--- a/CPP/7zip/Aes.mak
+++ b/CPP/7zip/Aes.mak
@@ -1,7 +1,7 @@
C_OBJS = $(C_OBJS) \
$O\Aes.obj
-!IF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM"
+!IF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM" && "$(CPU)" != "ARM64"
ASM_OBJS = $(ASM_OBJS) \
$O\AesOpt.obj
!ENDIF
diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.h b/CPP/7zip/Archive/7z/7zCompressionMode.h
index 80e4154..2360017 100644
--- a/CPP/7zip/Archive/7z/7zCompressionMode.h
+++ b/CPP/7zip/Archive/7z/7zCompressionMode.h
@@ -13,7 +13,9 @@ struct CMethodFull: public CMethodProps
{
CMethodId Id;
UInt32 NumStreams;
+ int CodecIndex;
+ CMethodFull(): CodecIndex(-1) {}
bool IsSimpleCoder() const { return NumStreams == 1; }
};
diff --git a/CPP/7zip/Archive/7z/7zDecode.cpp b/CPP/7zip/Archive/7z/7zDecode.cpp
index 1f709cb..2705ecb 100644
--- a/CPP/7zip/Archive/7z/7zDecode.cpp
+++ b/CPP/7zip/Archive/7z/7zDecode.cpp
@@ -226,19 +226,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
- #if !defined(_7ZIP_ST) && !defined(_SFX)
- , bool mtMode, UInt32 numThreads
+ #if !defined(_7ZIP_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);
@@ -308,7 +312,7 @@ HRESULT CDecoder::Decode(
#endif
CCreatedCoder cod;
- RINOK(CreateCoder(
+ RINOK(CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
coderInfo.MethodID, false, cod));
@@ -351,11 +355,39 @@ HRESULT CDecoder::Decode(
unsigned i;
+ bool mt_wasUsed = false;
+
for (i = 0; i < folderInfo.Coders.Size(); i++)
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
IUnknown *decoder = _mixer->GetCoder(i).GetUnknown();
+ #if !defined(_7ZIP_ST)
+ if (!mt_wasUsed)
+ {
+ if (mtMode)
+ {
+ CMyComPtr<ICompressSetCoderMt> setCoderMt;
+ decoder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
+ if (setCoderMt)
+ {
+ mt_wasUsed = true;
+ RINOK(setCoderMt->SetNumberOfThreads(numThreads));
+ }
+ }
+ // if (memUsage != 0)
+ {
+ CMyComPtr<ICompressSetMemLimit> setMemLimit;
+ decoder->QueryInterface(IID_ICompressSetMemLimit, (void **)&setMemLimit);
+ if (setMemLimit)
+ {
+ mt_wasUsed = true;
+ RINOK(setMemLimit->SetMemLimit(memUsage));
+ }
+ }
+ }
+ #endif
+
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
decoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
@@ -372,18 +404,6 @@ HRESULT CDecoder::Decode(
}
}
- #if !defined(_7ZIP_ST) && !defined(_SFX)
- if (mtMode)
- {
- CMyComPtr<ICompressSetCoderMt> setCoderMt;
- decoder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
- if (setCoderMt)
- {
- RINOK(setCoderMt->SetNumberOfThreads(numThreads));
- }
- }
- #endif
-
#ifndef _NO_CRYPTO
{
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
@@ -415,12 +435,14 @@ HRESULT CDecoder::Decode(
}
#endif
+ bool finishMode = false;
{
CMyComPtr<ICompressSetFinishMode> setFinishMode;
decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
if (setFinishMode)
{
- RINOK(setFinishMode->SetFinishMode(BoolToInt(fullUnpack)));
+ finishMode = fullUnpack;
+ RINOK(setFinishMode->SetFinishMode(BoolToInt(finishMode)));
}
}
@@ -450,7 +472,7 @@ HRESULT CDecoder::Decode(
unpackSize :
&folders.CoderUnpackSizes[unpackStreamIndexStart + i];
- _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers);
+ _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers, finishMode);
}
if (outStream)
@@ -530,7 +552,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/CPP/7zip/Archive/7z/7zDecode.h b/CPP/7zip/Archive/7z/7zDecode.h
index 051f843..944f8a3 100644
--- a/CPP/7zip/Archive/7z/7zDecode.h
+++ b/CPP/7zip/Archive/7z/7zDecode.h
@@ -53,12 +53,14 @@ public:
, ISequentialOutStream *outStream
, ICompressProgressInfo *compressProgress
+
, ISequentialInStream **inStreamMainRes
+ , bool &dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS_DECL
- #if !defined(_7ZIP_ST) && !defined(_SFX)
- , bool mtMode, UInt32 numThreads
+ #if !defined(_7ZIP_ST)
+ , bool mtMode, UInt32 numThreads, UInt64 memUsage
#endif
);
};
diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp
index 7636c60..4c0d221 100644
--- a/CPP/7zip/Archive/7z/7zEncode.cpp
+++ b/CPP/7zip/Archive/7z/7zEncode.cpp
@@ -154,9 +154,18 @@ HRESULT CEncoder::CreateMixerCoder(
CCreatedCoder cod;
- RINOK(CreateCoder(
+ if (methodFull.CodecIndex >= 0)
+ {
+ RINOK(CreateCoder_Index(
+ EXTERNAL_CODECS_LOC_VARS
+ methodFull.CodecIndex, true, cod));
+ }
+ else
+ {
+ RINOK(CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
methodFull.Id, true, cod));
+ }
if (cod.NumStreams != methodFull.NumStreams)
return E_FAIL;
@@ -333,7 +342,7 @@ HRESULT CEncoder::Encode(
}
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.
@@ -370,6 +379,17 @@ HRESULT CEncoder::Encode(
resetInitVector->ResetInitVector();
}
+ {
+ CMyComPtr<ICompressSetCoderPropertiesOpt> optProps;
+ coder->QueryInterface(IID_ICompressSetCoderPropertiesOpt, (void **)&optProps);
+ if (optProps)
+ {
+ PROPID propID = NCoderPropID::kExpectedDataSize;
+ NWindows::NCOM::CPropVariant prop = (UInt64)unpackSize;
+ RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1));
+ }
+ }
+
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
@@ -380,7 +400,7 @@ HRESULT CEncoder::Encode(
CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
CMyComPtr<ISequentialOutStream> dynOutStream(outStreamSpec);
outStreamSpec->Init();
- writeCoderProperties->WriteCoderProperties(dynOutStream);
+ RINOK(writeCoderProperties->WriteCoderProperties(dynOutStream));
outStreamSpec->CopyToBuffer(props);
}
else
@@ -429,10 +449,12 @@ 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());
diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp
index a675797..075644f 100644
--- a/CPP/7zip/Archive/7z/7zExtract.cpp
+++ b/CPP/7zip/Archive/7z/7zExtract.cpp
@@ -152,6 +152,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);
@@ -348,6 +354,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
#endif
+ bool dataAfterEnd_Error = false;
+
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_VARS
_inStream,
@@ -358,20 +366,27 @@ 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
+ #if !defined(_7ZIP_ST)
+ , true, _numThreads, _memUsage
#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);
+
+ 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));
diff --git a/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/CPP/7zip/Archive/7z/7zFolderInStream.cpp
index 51a6f68..eee11a0 100644
--- a/CPP/7zip/Archive/7z/7zFolderInStream.cpp
+++ b/CPP/7zip/Archive/7z/7zFolderInStream.cpp
@@ -80,14 +80,17 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
{
if (_stream)
{
- UInt32 processed2;
- RINOK(_stream->Read(data, size, &processed2));
- if (processed2 != 0)
+ 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;
+ _crc = CrcUpdate(_crc, data, cur);
+ _pos += cur;
if (processedSize)
- *processedSize = processed2;
+ *processedSize = cur;
return S_OK;
}
diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp
index ce955a6..a3b0bce 100644
--- a/CPP/7zip/Archive/7z/7zHandler.cpp
+++ b/CPP/7zip/Archive/7z/7zHandler.cpp
@@ -40,7 +40,6 @@ CHandler::CHandler()
_crcSize = 4;
#ifdef __7Z_SET_PROPERTIES
- _numThreads = NSystem::GetNumberOfProcessors();
_useMultiThreadMixer = true;
#endif
@@ -540,7 +539,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)
{
@@ -575,7 +574,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;
@@ -714,8 +713,8 @@ STDMETHODIMP CHandler::Close()
STDMETHODIMP 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++)
@@ -734,13 +733,15 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
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/CPP/7zip/Archive/7z/7zHandler.h b/CPP/7zip/Archive/7z/7zHandler.h
index 00a8e83..7d5a5f0 100644
--- a/CPP/7zip/Archive/7z/7zHandler.h
+++ b/CPP/7zip/Archive/7z/7zHandler.h
@@ -8,16 +8,6 @@
#include "../../Common/CreateCoder.h"
-#ifndef EXTRACT_ONLY
-#include "../Common/HandlerOut.h"
-#endif
-
-#include "7zCompressionMode.h"
-#include "7zIn.h"
-
-namespace NArchive {
-namespace N7z {
-
#ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
@@ -30,6 +20,16 @@ namespace N7z {
#endif
+// #ifdef __7Z_SET_PROPERTIES
+#include "../Common/HandlerOut.h"
+// #endif
+
+#include "7zCompressionMode.h"
+#include "7zIn.h"
+
+namespace NArchive {
+namespace N7z {
+
#ifndef EXTRACT_ONLY
@@ -38,8 +38,6 @@ class COutHandler: public CMultiMethodProps
HRESULT SetSolidFromString(const UString &s);
HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value);
public:
- bool _removeSfxBlock;
-
UInt64 _numSolidFiles;
UInt64 _numSolidBytes;
bool _numSolidBytesDefined;
@@ -54,9 +52,12 @@ public:
CBoolPair Write_CTime;
CBoolPair Write_ATime;
CBoolPair Write_MTime;
+ CBoolPair Write_Attrib;
bool _useMultiThreadMixer;
+ bool _removeSfxBlock;
+
// bool _volumeMode;
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
@@ -69,9 +70,10 @@ public:
_numSolidBytesDefined = false;
}
+ void InitProps7z();
void InitProps();
- COutHandler() { InitProps(); }
+ COutHandler() { InitProps7z(); }
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
};
@@ -81,16 +83,23 @@ public:
class CHandler:
public IInArchive,
public IArchiveGetRawProps,
+
#ifdef __7Z_SET_PROPERTIES
public ISetProperties,
#endif
+
#ifndef EXTRACT_ONLY
public IOutArchive,
#endif
+
PUBLIC_ISetCompressCodecsInfo
- public CMyUnknownImp
+
+ public CMyUnknownImp,
+
#ifndef EXTRACT_ONLY
- , public COutHandler
+ public COutHandler
+ #else
+ public CCommonMethodProps
#endif
{
public:
@@ -134,7 +143,6 @@ private:
#ifdef EXTRACT_ONLY
#ifdef __7Z_SET_PROPERTIES
- UInt32 _numThreads;
bool _useMultiThreadMixer;
#endif
diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
index 2f6a072..f0474bb 100644
--- a/CPP/7zip/Archive/7z/7zHandlerOut.cpp
+++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
@@ -13,16 +13,19 @@
#include "7zOut.h"
#include "7zUpdate.h"
+#ifndef 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 =
@@ -40,9 +43,11 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m)
{
- if (!FindMethod(
+ dest.CodecIndex = FindMethod_Index(
EXTERNAL_CODECS_VARS
- m.MethodName, dest.Id, dest.NumStreams))
+ m.MethodName, true,
+ dest.Id, dest.NumStreams);
+ if (dest.CodecIndex < 0)
return E_INVALIDARG;
(CProps &)dest = (CProps &)m;
return S_OK;
@@ -113,11 +118,11 @@ HRESULT CHandler::SetMainMethod(
FOR_VECTOR (i, methods)
{
COneMethodInfo &oneMethodInfo = methods[i];
- SetGlobalLevelAndThreads(oneMethodInfo
- #ifndef _7ZIP_ST
- , numThreads
- #endif
- );
+
+ SetGlobalLevelTo(oneMethodInfo);
+ #ifndef _7ZIP_ST
+ CMultiMethodProps::SetMethodThreadsTo(oneMethodInfo, numThreads);
+ #endif
CMethodFull &methodFull = methodMode.Methods.AddNew();
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
@@ -282,15 +287,18 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
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_Attrib = (Write_Attrib.Def && Write_Attrib.Val || !Write_Attrib.Def);
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 (!Write_Attrib.Def) need_Attrib = !db->Attrib.Defs.IsEmpty();
}
- UString s;
+ // UString s;
+ UString name;
for (UInt32 i = 0; i < numItems; i++)
{
@@ -307,7 +315,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
ui.IsAnti = false;
ui.Size = 0;
- UString name;
+ name.Empty();
// bool isAltStream = false;
if (ui.IndexInArchive != -1)
{
@@ -334,6 +342,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (ui.NewProps)
{
bool folderStatusIsDefined;
+ if (need_Attrib)
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
@@ -377,7 +386,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
else
{
- name = NItemName::MakeLegalName(prop.bstrVal);
+ name = prop.bstrVal;
+ NItemName::ReplaceSlashes_OsToUnix(name);
}
}
{
@@ -614,6 +624,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;
@@ -692,10 +703,8 @@ 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;
@@ -705,6 +714,7 @@ void COutHandler::InitProps()
Write_CTime.Init();
Write_ATime.Init();
Write_MTime.Init();
+ Write_Attrib.Init();
_useMultiThreadMixer = true;
@@ -714,6 +724,14 @@ void COutHandler::InitProps()
_useTypeSorting = false;
}
+void COutHandler::InitProps()
+{
+ CMultiMethodProps::Init();
+ InitProps7z();
+}
+
+
+
HRESULT COutHandler::SetSolidFromString(const UString &s)
{
UString s2 = s;
@@ -754,6 +772,10 @@ HRESULT COutHandler::SetSolidFromString(const UString &s)
}
_numSolidBytes = (v << numBits);
_numSolidBytesDefined = true;
+ /*
+ if (_numSolidBytes == 0)
+ _numSolidFiles = 1;
+ */
}
}
return S_OK;
@@ -802,7 +824,7 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
return E_INVALIDARG;
return SetSolidFromString(name);
}
-
+
UInt32 number;
int index = ParseStringToUInt32(name, number);
// UString realName = name.Ptr(index);
@@ -830,6 +852,8 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
+ if (name.IsEqualTo("tr")) return PROPVARIANT_to_BoolPair(value, Write_Attrib);
+
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
if (name.IsEqualTo("qs")) return PROPVARIANT_to_bool(value, _useTypeSorting);
@@ -911,3 +935,5 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
}
}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp
index b03bc89..bbc77b0 100644
--- a/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/CPP/7zip/Archive/7z/7zIn.cpp
@@ -32,6 +32,21 @@ using namespace NCOM;
namespace NArchive {
namespace N7z {
+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,6 +55,7 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
p[i] = false;
}
+
class CInArchiveException {};
class CUnsupportedFeatureException: public CInArchiveException {};
@@ -566,21 +582,30 @@ 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];
+ 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;
}
}
+
+void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
+{
+ ReadBoolVector2(numItems, crcs.Defs);
+ Read_UInt32_Vector(crcs);
+}
+
+
#define k_Scan_NumCoders_MAX 64
#define k_Scan_NumCodersStreams_in_Folder_MAX 64
@@ -1075,6 +1100,8 @@ 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,
@@ -1083,16 +1110,23 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
outStream,
NULL, // *compressProgress
+
NULL // **inStreamMainRes
+ , dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
- #if !defined(_7ZIP_ST) && !defined(_SFX)
+ #if !defined(_7ZIP_ST)
, false // mtMode
, 1 // numThreads
+ , 0 // memUsage
#endif
);
+
RINOK(result);
+ if (dataAfterEnd_Error)
+ ThereIsHeaderError = true;
+
if (folders.FolderCRCs.ValidAndDefined(i))
if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
ThrowIncorrect();
@@ -1148,19 +1182,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 +1194,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;
@@ -1197,10 +1221,10 @@ HRESULT CInArchive::ReadHeader(
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);
@@ -1216,36 +1240,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 +1283,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 +1328,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 +1373,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 +1398,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);
@@ -1466,6 +1484,7 @@ void CDbEx::FillLinks()
}
}
+
HRESULT CInArchive::ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
@@ -1610,6 +1629,7 @@ HRESULT CInArchive::ReadDatabase2(
);
}
+
HRESULT CInArchive::ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h
index 260d8f7..c5fb909 100644
--- a/CPP/7zip/Archive/7z/7zIn.h
+++ b/CPP/7zip/Archive/7z/7zIn.h
@@ -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();
}
@@ -369,6 +371,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);
diff --git a/CPP/7zip/Archive/7z/7zItem.h b/CPP/7zip/Archive/7z/7zItem.h
index 935ee43..90cf98c 100644
--- a/CPP/7zip/Archive/7z/7zItem.h
+++ b/CPP/7zip/Archive/7z/7zItem.h
@@ -26,12 +26,14 @@ struct CCoderInfo
bool IsSimpleCoder() const { return NumStreams == 1; }
};
+
struct CBond
{
UInt32 PackIndex;
UInt32 UnpackIndex;
};
+
struct CFolder
{
CLASS_NO_COPY(CFolder)
@@ -87,6 +89,7 @@ public:
}
};
+
struct CUInt32DefVector
{
CBoolVector Defs;
@@ -110,9 +113,25 @@ 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);
};
+
struct CUInt64DefVector
{
CBoolVector Defs;
@@ -141,15 +160,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 +178,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/CPP/7zip/Archive/7z/7zOut.cpp b/CPP/7zip/Archive/7z/7zOut.cpp
index 0989978..5bd3a41 100644
--- a/CPP/7zip/Archive/7z/7zOut.cpp
+++ b/CPP/7zip/Archive/7z/7zOut.cpp
@@ -330,13 +330,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 +346,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 +452,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 +472,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 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSizeShifts);
WriteByte(type);
WriteNumber(dataSize);
@@ -486,24 +487,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]);
}
@@ -520,7 +515,7 @@ HRESULT COutArchive::EncodeStream(
outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size()));
// outFolders.NumUnpackStreamsVector.Add(1);
UInt64 dataSize64 = data.Size();
- UInt64 unpackSize;
+ UInt64 unpackSize = data.Size();
RINOK(encoder.Encode(
EXTERNAL_CODECS_LOC_VARS
stream,
@@ -648,7 +643,7 @@ void COutArchive::WriteHeader(
if (numDefined > 0)
{
namesDataSize++;
- SkipAlign(2 + GetBigNumberSize(namesDataSize), 16);
+ SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4);
WriteByte(NID::kName);
WriteNumber(namesDataSize);
@@ -673,28 +668,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 +684,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 +706,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 +737,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);
@@ -888,6 +860,18 @@ HRESULT COutArchive::WriteDatabase(
}
}
+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)
{
while (index >= Defs.Size())
@@ -907,6 +891,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/CPP/7zip/Archive/7z/7zOut.h b/CPP/7zip/Archive/7z/7zOut.h
index 86034f3..12e965f 100644
--- a/CPP/7zip/Archive/7z/7zOut.h
+++ b/CPP/7zip/Archive/7z/7zOut.h
@@ -45,6 +45,7 @@ public:
size_t GetPos() const { return _pos; }
};
+
struct CHeaderOptions
{
bool CompressMainHeader;
@@ -71,24 +72,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 +119,7 @@ struct COutFolders
}
};
+
struct CArchiveDatabaseOut: public COutFolders
{
CRecordVector<UInt64> PackSizes;
@@ -123,10 +132,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 +164,7 @@ struct CArchiveDatabaseOut: public COutFolders
ATime.Clear();
MTime.Clear();
StartPos.Clear();
+ Attrib.Clear();
IsAnti.Clear();
/*
@@ -176,6 +187,7 @@ struct CArchiveDatabaseOut: public COutFolders
ATime.ReserveDown();
MTime.ReserveDown();
StartPos.ReserveDown();
+ Attrib.ReserveDown();
IsAnti.ReserveDown();
/*
@@ -196,11 +208,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,6 +237,7 @@ struct CArchiveDatabaseOut: public COutFolders
void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name);
};
+
class COutArchive
{
UInt64 _prefixHeaderPos;
@@ -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(
diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp
index 509a330..44de9ac 100644
--- a/CPP/7zip/Archive/7z/7zUpdate.cpp
+++ b/CPP/7zip/Archive/7z/7zUpdate.cpp
@@ -1088,18 +1088,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,6 +1112,8 @@ static void FromUpdateItemToFileItem(const CUpdateItem &ui,
// file.IsAltStream = ui.IsAltStream;
}
+
+
class CRepackInStreamWithSizes:
public ISequentialInStream,
public ICompressGetSubStreamSize,
@@ -1437,6 +1444,7 @@ public:
#ifndef _7ZIP_ST
+ bool dataAfterEnd_Error;
HRESULT Result;
CMyComPtr<IInStream> InStream;
@@ -1479,7 +1487,9 @@ void CThreadDecoder::Execute()
bool passwordIsDefined = false;
UString password;
#endif
-
+
+ dataAfterEnd_Error = false;
+
Result = Decoder.Decode(
EXTERNAL_CODECS_LOC_VARS
InStream,
@@ -1491,12 +1501,16 @@ void CThreadDecoder::Execute()
Fos,
NULL, // compressProgress
+
NULL // *inStreamMainRes
+ , dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
#ifndef _7ZIP_ST
- , MtMode, NumThreads
+ , MtMode, NumThreads,
+ 0 // MemUsage
#endif
+
);
}
catch(...)
@@ -1541,6 +1555,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);
}
@@ -1682,13 +1697,14 @@ HRESULT Update(
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;
@@ -1837,7 +1853,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);
}
@@ -1887,7 +1903,8 @@ HRESULT Update(
UString name;
if (ui.NewProps)
{
- FromUpdateItemToFileItem(ui, file, file2);
+ UpdateItem_To_FileItem(ui, file, file2);
+ file.CrcDefined = false;
name = ui.Name;
}
else
@@ -2107,6 +2124,8 @@ HRESULT Update(
#endif
CMyComPtr<ISequentialInStream> decodedStream;
+ bool dataAfterEnd_Error = false;
+
HRESULT res = threadDecoder.Decoder.Decode(
EXTERNAL_CODECS_LOC_VARS
inStream,
@@ -2117,12 +2136,15 @@ HRESULT Update(
NULL, // *outStream
NULL, // *compressProgress
+
&decodedStream
+ , dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
#ifndef _7ZIP_ST
, false // mtMode
, 1 // numThreads
+ , 0 // memUsage
#endif
);
@@ -2151,6 +2173,7 @@ HRESULT Update(
#endif
}
+ curUnpackSize = sizeToEncode;
HRESULT encodeRes = encoder.Encode(
EXTERNAL_CODECS_LOC_VARS
@@ -2175,16 +2198,19 @@ HRESULT Update(
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);
if (encodeRes == S_OK)
@@ -2224,12 +2250,7 @@ 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];
@@ -2238,17 +2259,21 @@ HRESULT Update(
const CUpdateItem &ui = updateItems[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)
@@ -2270,7 +2295,8 @@ HRESULT Update(
continue;
CRecordVector<CRefItem> refItems;
refItems.ClearAndSetSize(numFiles);
- bool sortByType = (options.UseTypeSorting && numSolidFiles > 1);
+ // bool sortByType = (options.UseTypeSorting && isSoid); // numSolidFiles > 1
+ bool sortByType = options.UseTypeSorting;
unsigned i;
@@ -2292,7 +2318,7 @@ HRESULT Update(
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)
@@ -2336,7 +2362,9 @@ HRESULT Update(
inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
unsigned startPackIndex = newDatabase.PackSizes.Size();
- UInt64 curFolderUnpackSize;
+ UInt64 curFolderUnpackSize = totalSize;
+ // curFolderUnpackSize = (UInt64)(Int64)-1;
+
RINOK(encoder.Encode(
EXTERNAL_CODECS_LOC_VARS
solidInStream,
@@ -2367,7 +2395,7 @@ HRESULT Update(
UString name;
if (ui.NewProps)
{
- FromUpdateItemToFileItem(ui, file, file2);
+ UpdateItem_To_FileItem(ui, file, file2);
name = ui.Name;
}
else
@@ -2386,7 +2414,7 @@ HRESULT Update(
{
skippedSize += ui.Size;
continue;
- // file.Name.AddAscii(".locked");
+ // file.Name += ".locked";
}
file.Crc = inStreamSpec->CRCs[subIndex];
diff --git a/CPP/7zip/Archive/Common/CoderMixer2.cpp b/CPP/7zip/Archive/Common/CoderMixer2.cpp
index aeb1d38..d4d9949 100644
--- a/CPP/7zip/Archive/Common/CoderMixer2.cpp
+++ b/CPP/7zip/Archive/Common/CoderMixer2.cpp
@@ -60,6 +60,62 @@ 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);
+ 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;
@@ -151,8 +207,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;
@@ -640,8 +698,12 @@ 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;
@@ -742,7 +804,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;
}
@@ -988,8 +1059,12 @@ 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;
@@ -1031,6 +1106,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/CPP/7zip/Archive/Common/CoderMixer2.h b/CPP/7zip/Archive/Common/CoderMixer2.h
index ce4797f..4bd6418 100644
--- a/CPP/7zip/Archive/Common/CoderMixer2.h
+++ b/CPP/7zip/Archive/Common/CoderMixer2.h
@@ -201,9 +201,13 @@ public:
CRecordVector<UInt64> PackSizes;
CRecordVector<const UInt64 *> PackSizePointers;
- CCoder() {}
+ bool Finish;
- void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes);
+ CCoder(): Finish(false) {}
+
+ void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish);
+
+ HRESULT CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const;
IUnknown *GetUnknown() const
{
@@ -239,9 +243,12 @@ protected:
public:
unsigned MainCoderIndex;
+ // bool InternalPackSizeError;
+
CMixer(bool encodeMode):
EncodeMode(encodeMode),
MainCoderIndex(0)
+ // , InternalPackSizeError(false)
{}
/*
@@ -273,11 +280,12 @@ public:
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 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);
@@ -338,12 +346,13 @@ public:
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 void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
+ { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
- ICompressProgressInfo *progress);
+ ICompressProgressInfo *progress,
+ bool &dataAfterEnd_Error);
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
HRESULT GetMainUnpackStream(
@@ -419,12 +428,13 @@ public:
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 void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
+ { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
ISequentialOutStream * const *outStreams,
- ICompressProgressInfo *progress);
+ ICompressProgressInfo *progress,
+ bool &dataAfterEnd_Error);
virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
CMixerMT(bool encodeMode): CMixer(encodeMode) {}
diff --git a/CPP/7zip/Archive/Common/HandlerOut.cpp b/CPP/7zip/Archive/Common/HandlerOut.cpp
index 3200fd2..41762d9 100644
--- a/CPP/7zip/Archive/Common/HandlerOut.cpp
+++ b/CPP/7zip/Archive/Common/HandlerOut.cpp
@@ -2,54 +2,129 @@
#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 {
+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;
+
+ const wchar_t *end;
+ UInt64 v = ConvertStringToUInt64(s, &end);
+ if (s == end)
+ return false;
+ wchar_t c = *end;
+ if (c == 0)
+ {
+ res = v;
+ return true;
+ }
+ if (end[1] != 0)
+ return false;
+
+ if (c == '%')
+ {
+ res = percentsBase / 100 * 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;
+ }
+ 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 _7ZIP_ST
+ hres = ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads);
+ #endif
+ return true;
+ }
+
+ if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
+ {
+ if (!ParseSizeString(name.Ptr(6), value, _memAvail, _memUsage))
+ hres = E_INVALIDARG;
+ return true;
+ }
+
+ return false;
+}
+
+
+#ifndef EXTRACT_ONLY
+
static void SetMethodProp32(COneMethodInfo &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 _7ZIP_ST
+void CMultiMethodProps::SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads)
+{
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
- #endif
}
+#endif
-void CMultiMethodProps::Init()
+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;
@@ -73,26 +148,24 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
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);
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);
@@ -111,20 +184,20 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
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::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
Init();
+
for (UInt32 i = 0; i < numProps; i++)
{
UString name = names[i];
@@ -138,20 +211,22 @@ HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PR
RINOK(ParsePropToUInt32(name.Ptr(1), value, a));
_level = a;
AddProp_Level(a);
+ continue;
}
- 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));
+ HRESULT hres;
+ if (SetCommonProperty(name, value, hres))
+ {
+ RINOK(hres)
+ continue;
+ }
}
+ RINOK(ParseMethodFromPROPVARIANT(names[i], value));
}
+
return S_OK;
}
+#endif
+
}
diff --git a/CPP/7zip/Archive/Common/HandlerOut.h b/CPP/7zip/Archive/Common/HandlerOut.h
index 44dee09..90b000a 100644
--- a/CPP/7zip/Archive/Common/HandlerOut.h
+++ b/CPP/7zip/Archive/Common/HandlerOut.h
@@ -3,30 +3,69 @@
#ifndef __HANDLER_OUT_H
#define __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()
+ {
+ #ifndef _7ZIP_ST
+ _numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+ #endif
+
+ UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28;
+ _memAvail = memAvail;
+ _memUsage = memAvail;
+ if (NWindows::NSystem::GetRamSize(memAvail))
+ {
+ _memAvail = memAvail;
+ _memUsage = memAvail / 32 * 17;
+ }
+ }
+
public:
#ifndef _7ZIP_ST
UInt32 _numThreads;
UInt32 _numProcessors;
#endif
+ UInt64 _memUsage;
+ UInt64 _memAvail;
+
+ bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres);
+
+ CCommonMethodProps() { InitCommon(); }
+};
+
+
+#ifndef 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 _7ZIP_ST
+ static void SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads);
+ #endif
+
unsigned GetNumEmptyMethods() const
{
@@ -41,27 +80,31 @@ 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 SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
};
+#endif
+
}
#endif
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
index 1608949..e0c35a9 100644
--- a/CPP/7zip/Archive/Common/ItemNameUtils.cpp
+++ b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
@@ -7,58 +7,57 @@
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;
+static const wchar_t kUnixPathSepar = L'/';
-void ReplaceToOsPathSeparator(wchar_t *s)
-{
- #ifdef _WIN32
- for (;;)
+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)
{
if (!name.IsEmpty())
{
- name.Replace(kDirDelimiter, kOSDirDelimiter);
- if (name.Back() == kOSDirDelimiter)
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ name.Replace(kUnixPathSepar, kOsPathSepar);
+ #endif
+
+ if (name.Back() == kOsPathSepar)
name.DeleteBack();
}
}
+
bool HasTailSlash(const AString &name, UINT
#if defined(_WIN32) && !defined(UNDER_CE)
codePage
@@ -67,20 +66,21 @@ 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)
+ *CharPrevExA((WORD)codePage, name, name.Ptr(name.Len()), 0);
+ #else
+ name.Back();
+ #endif
+ 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/CPP/7zip/Archive/Common/ItemNameUtils.h b/CPP/7zip/Archive/Common/ItemNameUtils.h
index 8ee2d0f..404fce4 100644
--- a/CPP/7zip/Archive/Common/ItemNameUtils.h
+++ b/CPP/7zip/Archive/Common/ItemNameUtils.h
@@ -8,19 +8,20 @@
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 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/CPP/7zip/Archive/IArchive.h b/CPP/7zip/Archive/IArchive.h
index 5c0957e..96451a6 100644
--- a/CPP/7zip/Archive/IArchive.h
+++ b/CPP/7zip/Archive/IArchive.h
@@ -488,6 +488,16 @@ ARCHIVE_INTERFACE(IOutArchive, 0xA0)
};
+/*
+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(ISetProperties, 0x03)
{
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) PURE;
diff --git a/CPP/7zip/Archive/LzmaHandler.cpp b/CPP/7zip/Archive/LzmaHandler.cpp
index cd9e89a..28079df 100644
--- a/CPP/7zip/Archive/LzmaHandler.cpp
+++ b/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);
@@ -197,6 +199,8 @@ class CHandler:
UInt64 _unpackSize;
UInt64 _numStreams;
+ void GetMethod(NCOM::CPropVariant &prop);
+
public:
MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq)
@@ -220,6 +224,7 @@ 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;
@@ -229,6 +234,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
if (_dataError) v |= kpv_ErrorFlags_DataError;
prop = v;
+ break;
}
}
prop.Detach(value);
@@ -241,23 +247,60 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
-static void DictSizeToString(UInt32 value, char *s)
+
+static void DictSizeToString(UInt32 val, char *s)
{
- for (int i = 0; i <= 31; i++)
- if (((UInt32)1 << i) == value)
+ for (unsigned i = 0; i <= 31; i++)
+ if (((UInt32)1 << i) == val)
{
::ConvertUInt32ToString(i, s);
return;
}
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);
+ if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
+ else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
+ ::ConvertUInt32ToString(val, s);
s += MyStringLen(s);
*s++ = c;
*s = 0;
}
+static char *AddProp32(char *s, const char *name, UInt32 v)
+{
+ *s++ = ':';
+ s = MyStpCpy(s, name);
+ ::ConvertUInt32ToString(v, s);
+ return s + MyStringLen(s);
+}
+
+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:");
+ DictSizeToString(_header.GetDicSize(), s);
+ s += strlen(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;
+}
+
+
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
@@ -265,18 +308,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
{
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;
@@ -396,9 +428,9 @@ STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const
{
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;
}
@@ -510,7 +542,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;
diff --git a/CPP/7zip/Archive/SplitHandler.cpp b/CPP/7zip/Archive/SplitHandler.cpp
index f20680d..ffb0e33 100644
--- a/CPP/7zip/Archive/SplitHandler.cpp
+++ b/CPP/7zip/Archive/SplitHandler.cpp
@@ -181,7 +181,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);
diff --git a/CPP/7zip/Archive/XzHandler.cpp b/CPP/7zip/Archive/XzHandler.cpp
index 5616aa1..74cbca9 100644
--- a/CPP/7zip/Archive/XzHandler.cpp
+++ b/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,72 +19,55 @@
#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:
public IInArchive,
public IArchiveOpenSeq,
+ public IInArchiveGetStream,
+ public ISetProperties,
+
#ifndef EXTRACT_ONLY
public IOutArchive,
- public ISetProperties,
- public CMultiMethodProps,
#endif
- public CMyUnknownImp
+
+ public CMyUnknownImp,
+
+ #ifndef EXTRACT_ONLY
+ public CMultiMethodProps
+ #else
+ public CCommonMethodProps
+ #endif
{
- CStatInfo _stat;
+ CXzStatInfo _stat;
+ SRes MainDecodeSRes;
bool _isArc;
bool _needSeekToStart;
bool _phySize_Defined;
-
- CMyComPtr<IInStream> _stream;
- CMyComPtr<ISequentialInStream> _seqStream;
+ bool _firstBlockWasRead;
AString _methodsString;
@@ -93,21 +75,50 @@ class CHandler:
UInt32 _filterId;
- void Init()
+ UInt64 _numSolidBytes;
+
+ void InitXz()
{
_filterId = 0;
- CMultiMethodProps::Init();
+ _numSolidBytes = XZ_PROPS__BLOCK_SIZE__AUTO;
}
-
+
#endif
+ void Init()
+ {
+ #ifndef 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;
+ #ifndef _7ZIP_ST
+ decoder._numThreads = _numThreads;
+ #endif
+ decoder._memUsage = _memUsage;
+
+ MainDecodeSRes = SZ_OK;
+
+ RINOK(decoder.Decode(seqInStream, outStream,
+ NULL, // *outSizeLimit
+ true, // finishStream
+ progress));
+
+ _stat = decoder.Stat;
+ MainDecodeSRes = decoder.MainDecodeSRes;
+
_phySize_Defined = true;
return S_OK;
}
@@ -115,31 +126,55 @@ class CHandler:
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
MY_QUERYINTERFACE_ENTRY(IArchiveOpenSeq)
+ MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
+ MY_QUERYINTERFACE_ENTRY(ISetProperties)
#ifndef EXTRACT_ONLY
MY_QUERYINTERFACE_ENTRY(IOutArchive)
- MY_QUERYINTERFACE_ENTRY(ISetProperties)
#endif
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
INTERFACE_IInArchive(;)
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+ STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
#ifndef EXTRACT_ONLY
INTERFACE_IOutArchive(;)
- STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
#endif
+ size_t _blocksArraySize;
+ CBlockInfo *_blocks;
+ UInt64 _maxBlocksSize;
+ CMyComPtr<IInStream> _stream;
+ CMyComPtr<ISequentialInStream> _seqStream;
+
+ CXzBlock _firstBlock;
+
CHandler();
+ ~CHandler();
+
+ HRESULT SeekToPackPos(UInt64 pos)
+ {
+ return _stream->Seek(pos, STREAM_SEEK_SET, NULL);
+ }
};
-CHandler::CHandler()
+
+CHandler::CHandler():
+ _blocks(NULL),
+ _blocksArraySize(0)
{
#ifndef EXTRACT_ONLY
- Init();
+ InitXz();
#endif
}
+CHandler::~CHandler()
+{
+ MyFree(_blocks);
+}
+
static const Byte kProps[] =
{
@@ -152,7 +187,9 @@ static const Byte kArcProps[] =
{
kpidMethod,
kpidNumStreams,
- kpidNumBlocks
+ kpidNumBlocks,
+ kpidClusterSize,
+ kpidCharacts
};
IMP_IInArchive_Props
@@ -169,13 +206,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 +222,7 @@ static void Lzma2PropToString(AString &s, unsigned prop)
c = 'm';
}
}
- AddUInt32ToString(s, size);
+ s.Add_UInt32(size);
if (c != 0)
s += c;
}
@@ -216,7 +246,7 @@ static const CMethodNamePair g_NamePairs[] =
{ 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++)
@@ -232,7 +262,7 @@ static AString GetMethodString(const CXzFilter &f)
p = temp;
}
- AString s = p;
+ s += p;
if (f.propsSize > 0)
{
@@ -240,7 +270,7 @@ 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
{
s += '[';
@@ -249,13 +279,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,27 +301,24 @@ 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)
@@ -307,22 +327,47 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
NCOM::CPropVariant prop;
switch (propID)
{
- case kpidPhySize: if (_phySize_Defined) prop = _stat.PhySize; break;
+ case kpidPhySize: if (_phySize_Defined) prop = _stat.InSize; 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 kpidClusterSize: if (_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;
+ SRes sres = MainDecodeSRes; // _stat.DecodeRes2; //
+ if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
+ if (/*_stat.UnexpectedEnd */ sres == SZ_ERROR_INPUT_EOF) 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;
+ if (/* _stat.HeadersError */ sres == SZ_ERROR_ARCHIVE) v |= kpv_ErrorFlags_HeadersError;
+ if (/* _stat.Unsupported */ sres == SZ_ERROR_UNSUPPORTED) v |= kpv_ErrorFlags_UnsupportedMethod;
+ if (/* _stat.DataError */ sres == SZ_ERROR_DATA) v |= kpv_ErrorFlags_DataError;
+ if (/* _stat.CrcError */ 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);
@@ -343,7 +388,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)
switch (propID)
{
case kpidSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break;
- case kpidPackSize: if (_phySize_Defined) prop = _stat.PhySize; break;
+ case kpidPackSize: if (_phySize_Defined) prop = _stat.InSize; break;
case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;
}
prop.Detach(value);
@@ -354,27 +399,28 @@ STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)
struct COpenCallbackWrap
{
- ICompressProgress p;
+ ICompressProgress vt;
IArchiveOpenCallback *OpenCallback;
HRESULT Res;
COpenCallbackWrap(IArchiveOpenCallback *progress);
};
-static SRes OpenCallbackProgress(void *pp, UInt64 inSize, UInt64 /* outSize */)
+static SRes OpenCallbackProgress(const ICompressProgress *pp, UInt64 inSize, UInt64 /* outSize */)
{
- COpenCallbackWrap *p = (COpenCallbackWrap *)pp;
+ COpenCallbackWrap *p = CONTAINER_FROM_VTBL(pp, COpenCallbackWrap, vt);
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)
{
- p.Progress = OpenCallbackProgress;
+ vt.Progress = OpenCallbackProgress;
OpenCallback = callback;
Res = SZ_OK;
}
+
struct CXzsCPP
{
CXzs p;
@@ -382,6 +428,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,14 +471,18 @@ 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 (res != SZ_OK)
return SRes_to_Open_HRESULT(res);
@@ -416,34 +490,47 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
CXzBlock block;
Bool isIndex;
UInt32 headerSizeRes;
- SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.p, &isIndex, &headerSizeRes);
+ SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.vt, &isIndex, &headerSizeRes);
if (res2 == SZ_OK && !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->Seek(0, STREAM_SEEK_END, &_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);
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;
/*
@@ -463,7 +550,64 @@ 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
{
@@ -477,6 +621,8 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
return S_OK;
}
+
+
STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)
{
COM_TRY_BEGIN
@@ -498,202 +644,338 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
STDMETHODIMP CHandler::Close()
{
- _stat.Clear();
+ XzStatInfo_Clear(&_stat);
_isArc = false;
_needSeekToStart = false;
-
_phySize_Defined = false;
+ _firstBlockWasRead = false;
_methodsString.Empty();
_stream.Release();
_seqStream.Release();
+
+ MyFree(_blocks);
+ _blocks = NULL;
+ _blocksArraySize = 0;
+ _maxBlocksSize = 0;
+
+ MainDecodeSRes = SZ_OK;
+
return S_OK;
}
-class CSeekToSeqStream:
+
+struct CXzUnpackerCPP2
+{
+ Byte *InBuf;
+ // Byte *OutBuf;
+ CXzUnpacker p;
+
+ CXzUnpackerCPP2();
+ ~CXzUnpackerCPP2();
+};
+
+CXzUnpackerCPP2::CXzUnpackerCPP2(): InBuf(NULL)
+ // , OutBuf(NULL)
+{
+ XzUnpacker_Construct(&p, &g_Alloc);
+}
+
+CXzUnpackerCPP2::~CXzUnpackerCPP2()
+{
+ XzUnpacker_Free(&p);
+ MidFree(InBuf);
+ // MidFree(OutBuf);
+}
+
+
+class CInStream:
public IInStream,
public CMyUnknownImp
{
public:
- CMyComPtr<ISequentialInStream> Stream;
+ UInt64 _virtPos;
+ 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;
+
MY_UNKNOWN_IMP1(IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+
+ ~CInStream();
};
-STDMETHODIMP CSeekToSeqStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+
+CInStream::~CInStream()
{
- return Stream->Read(data, size, processedSize);
+ // _cache.Free();
}
-STDMETHODIMP CSeekToSeqStream::Seek(Int64, UInt32, UInt64 *) { return E_NOTIMPL; }
-CXzUnpackerCPP::CXzUnpackerCPP(): InBuf(0), OutBuf(0)
+size_t FindBlock(const CBlockInfo *blocks, size_t numBlocks, UInt64 pos)
{
- XzUnpacker_Construct(&p, &g_Alloc);
+ 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;
+ }
}
-CXzUnpackerCPP::~CXzUnpackerCPP()
-{
- XzUnpacker_Free(&p);
- MyFree(InBuf);
- MyFree(OutBuf);
-}
-HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
-{
- const size_t kInBufSize = 1 << 15;
- const size_t kOutBufSize = 1 << 21;
- 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;
+ ECoderStatus status;
+
SRes res = XzUnpacker_Code(&xzu.p,
- xzu.OutBuf + outPos, &outLen,
+ // 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;
+
+ Bool 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)
+ }
+}
+
+
+STDMETHODIMP 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)
+ {
+ 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;
- }
+ {
+ size_t offset = (size_t)(_virtPos - _cacheStartPos);
+ 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
+}
+
+
+STDMETHODIMP 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 = offset;
+ if (newPosition)
+ *newPosition = offset;
+ return S_OK;
+}
+
+
+
+static const UInt64 kMaxBlockSize_for_GetStream = (UInt64)1 << 40;
+
+STDMETHODIMP 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; // decoder.Stat.DecodeRes2;
+ 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)
{
@@ -704,7 +986,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
return E_INVALIDARG;
if (_phySize_Defined)
- extractCallback->SetTotal(_stat.PhySize);
+ extractCallback->SetTotal(_stat.InSize);
UInt64 currentTotalPacked = 0;
RINOK(extractCallback->SetCompleted(&currentTotalPacked));
@@ -733,15 +1015,26 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
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)
@@ -750,16 +1043,17 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
return S_OK;
}
+
STDMETHODIMP 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);
}
@@ -795,84 +1089,79 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
RINOK(updateCallback->SetTotal(size));
}
- CLzma2EncProps lzma2Props;
- Lzma2EncProps_Init(&lzma2Props);
+ NCompress::NXz::CEncoder *encoderSpec = new NCompress::NXz::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
+
+ CXzProps &xzProps = encoderSpec->xzProps;
+ CLzma2EncProps &lzma2Props = xzProps.lzma2Props;
lzma2Props.lzmaProps.level = GetLevel();
- CMyComPtr<ISequentialInStream> fileInStream;
- RINOK(updateCallback->GetStream(0, &fileInStream));
+ xzProps.reduceSize = size;
+ /*
+ {
+ NCOM::CPropVariant prop = (UInt64)size;
+ RINOK(encoderSpec->SetCoderProp(NCoderPropID::kReduceSize, prop));
+ }
+ */
- CSeqInStreamWrap seqInStream(fileInStream);
+ #ifndef _7ZIP_ST
+ xzProps.numTotalThreads = _numThreads;
+ #endif
+ xzProps.blockSize = _numSolidBytes;
+ if (_numSolidBytes == XZ_PROPS__BLOCK_SIZE__SOLID)
{
- NCOM::CPropVariant prop = (UInt64)size;
- RINOK(NCompress::NLzma2::SetLzma2Prop(NCoderPropID::kReduceSize, prop, lzma2Props));
+ xzProps.lzma2Props.blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID;
}
- FOR_VECTOR (i, _methods)
+ RINOK(encoderSpec->SetCheckSize(_crcSize));
+
{
- COneMethodInfo &m = _methods[i];
- SetGlobalLevelAndThreads(m
- #ifndef _7ZIP_ST
- , _numThreads
- #endif
- );
+ CXzFilterProps &filter = xzProps.filterProps;
+
+ if (_filterId == XZ_ID_Delta)
{
- FOR_VECTOR (j, m.Props)
+ bool deltaDefined = false;
+ FOR_VECTOR (j, _filterMethod.Props)
{
- const CProp &prop = m.Props[j];
- RINOK(NCompress::NLzma2::SetLzma2Prop(prop.Id, prop.Value, lzma2Props));
+ 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;
}
+ if (!deltaDefined)
+ return E_INVALIDARG;
}
+ filter.id = _filterId;
}
- #ifndef _7ZIP_ST
- lzma2Props.numTotalThreads = _numThreads;
- #endif
+ 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));
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)
- {
- 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;
- }
- filter.id = _filterId;
- if (_filterId == XZ_ID_Delta)
- {
- bool deltaDefined = false;
- FOR_VECTOR (j, _filterMethod.Props)
- {
- 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;
- }
- }
- if (!deltaDefined)
- return E_INVALIDARG;
- }
- 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);
+ return encoderSpec->Code(fileInStream, outStream, NULL, NULL, progress);
}
if (indexInArchive != 0)
@@ -888,7 +1177,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (_stream)
{
if (_phySize_Defined)
- RINOK(updateCallback->SetTotal(_stat.PhySize));
+ RINOK(updateCallback->SetTotal(_stat.InSize));
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
}
@@ -901,16 +1190,76 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
COM_TRY_END
}
+#endif
+
+
+HRESULT CHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
+{
+ UString name = nameSpec;
+ name.MakeLower_Ascii();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+
+ #ifndef 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
+}
+
+
+
STDMETHODIMP 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]));
}
+ #ifndef EXTRACT_ONLY
+
if (!_filterMethod.MethodName.IsEmpty())
{
unsigned k;
@@ -935,16 +1284,19 @@ 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,
diff --git a/CPP/7zip/Archive/XzHandler.h b/CPP/7zip/Archive/XzHandler.h
index a61d4f7..18633fb 100644
--- a/CPP/7zip/Archive/XzHandler.h
+++ b/CPP/7zip/Archive/XzHandler.h
@@ -3,63 +3,9 @@
#ifndef __XZ_HANDLER_H
#define __XZ_HANDLER_H
-#include "../../../C/Xz.h"
-
-#include "../ICoder.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
diff --git a/CPP/7zip/Asm.mak b/CPP/7zip/Asm.mak
index 1012b16..3ad238a 100644
--- a/CPP/7zip/Asm.mak
+++ b/CPP/7zip/Asm.mak
@@ -2,7 +2,7 @@
!IF "$(CPU)" == "ARM"
$(ASM_OBJS): ../../../../Asm/Arm/$(*B).asm
$(COMPL_ASM)
-!ELSEIF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS"
+!ELSEIF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM64"
$(ASM_OBJS): ../../../../Asm/x86/$(*B).asm
$(COMPL_ASM)
!ENDIF
diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsp b/CPP/7zip/Bundles/Alone7z/Alone.dsp
index 37c059d..6147e10 100644
--- a/CPP/7zip/Bundles/Alone7z/Alone.dsp
+++ b/CPP/7zip/Bundles/Alone7z/Alone.dsp
@@ -44,7 +44,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /Gr /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /FAc /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gr /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAc /Yu"StdAfx.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -69,7 +69,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /Gr /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /Gr /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
@@ -94,7 +94,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /Yu"StdAfx.h" /FD /c
-# ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -121,7 +121,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
-# ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
@@ -406,6 +406,10 @@ SOURCE=..\..\..\Common\Wildcard.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Common\XzCrc64Init.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Common\XzCrc64Reg.cpp
# End Source File
# End Group
@@ -478,6 +482,14 @@ SOURCE=..\..\..\Windows\FileName.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Windows\FileSystem.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileSystem.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Windows\Handle.h
# End Source File
# Begin Source File
@@ -804,6 +816,22 @@ SOURCE=..\..\Compress\LzmaEncoder.h
SOURCE=..\..\Compress\LzmaRegister.cpp
# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\XzEncoder.h
+# End Source File
# End Group
# Begin Group "Archive"
@@ -1676,6 +1704,34 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\Lzma2DecMt.c
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Lzma2DecMt.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\Lzma2Enc.c
!IF "$(CFG)" == "Alone - Win32 Release"
@@ -1769,6 +1825,34 @@ SOURCE=..\..\..\..\C\MtCoder.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\MtDec.c
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\MtDec.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\Threads.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
diff --git a/CPP/7zip/Bundles/Alone7z/makefile b/CPP/7zip/Bundles/Alone7z/makefile
index 814ccb7..91ee192 100644
--- a/CPP/7zip/Bundles/Alone7z/makefile
+++ b/CPP/7zip/Bundles/Alone7z/makefile
@@ -3,7 +3,7 @@ MY_CONSOLE = 1
CFLAGS = $(CFLAGS) -DPROG_VARIANT_R
!IFNDEF UNDER_CE
-CFLAGS = $(CFLAGS) -DWIN_LONG_PATH
+CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE
!ENDIF
COMMON_OBJS = \
@@ -22,6 +22,7 @@ COMMON_OBJS = \
$O\UTFConvert.obj \
$O\MyVector.obj \
$O\Wildcard.obj \
+ $O\XzCrc64Init.obj \
$O\XzCrc64Reg.obj \
WIN_OBJS = \
@@ -32,6 +33,7 @@ WIN_OBJS = \
$O\FileIO.obj \
$O\FileLink.obj \
$O\FileName.obj \
+ $O\FileSystem.obj \
$O\MemoryLock.obj \
$O\PropVariant.obj \
$O\PropVariantConv.obj \
@@ -109,6 +111,8 @@ COMPRESS_OBJS = \
$O\LzmaDecoder.obj \
$O\LzmaEncoder.obj \
$O\LzmaRegister.obj \
+ $O\XzDecoder.obj \
+ $O\XzEncoder.obj \
CRYPTO_OBJS = \
$O\7zAes.obj \
@@ -130,10 +134,12 @@ C_OBJS = \
$O\LzFind.obj \
$O\LzFindMt.obj \
$O\Lzma2Dec.obj \
+ $O\Lzma2DecMt.obj \
$O\Lzma2Enc.obj \
$O\LzmaDec.obj \
$O\LzmaEnc.obj \
$O\MtCoder.obj \
+ $O\MtDec.obj \
$O\Sha256.obj \
$O\Sort.obj \
$O\Threads.obj \
@@ -147,5 +153,6 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
!include "../../Crc64.mak"
+!include "../../LzmaDec.mak"
!include "../../7zip.mak"
diff --git a/CPP/7zip/Bundles/Alone7z/resource.rc b/CPP/7zip/Bundles/Alone7z/resource.rc
index 3be08c9..36d70e7 100644
--- a/CPP/7zip/Bundles/Alone7z/resource.rc
+++ b/CPP/7zip/Bundles/Alone7z/resource.rc
@@ -1,3 +1,7 @@
#include "../../../../C/7zVersion.rc"
MY_VERSION_INFO_APP("7-Zip Reduced Standalone Console", "7zr")
+
+#ifndef UNDER_CE
+1 24 MOVEABLE PURE "../../UI/Console/Console.manifest"
+#endif
diff --git a/CPP/7zip/Bundles/Format7zExtractR/makefile b/CPP/7zip/Bundles/Format7zExtractR/makefile
index d34ab46..3a7f981 100644
--- a/CPP/7zip/Bundles/Format7zExtractR/makefile
+++ b/CPP/7zip/Bundles/Format7zExtractR/makefile
@@ -85,9 +85,12 @@ C_OBJS = \
$O\CpuArch.obj \
$O\Delta.obj \
$O\Lzma2Dec.obj \
+ $O\Lzma2DecMt.obj \
$O\LzmaDec.obj \
+ $O\MtDec.obj \
$O\Threads.obj \
!include "../../Crc.mak"
+!include "../../LzmaDec.mak"
!include "../../7zip.mak"
diff --git a/CPP/7zip/Bundles/Format7zR/makefile b/CPP/7zip/Bundles/Format7zR/makefile
index cd63c72..6a9dfb9 100644
--- a/CPP/7zip/Bundles/Format7zR/makefile
+++ b/CPP/7zip/Bundles/Format7zR/makefile
@@ -102,12 +102,15 @@ C_OBJS = \
$O\LzFind.obj \
$O\LzFindMt.obj \
$O\Lzma2Dec.obj \
+ $O\Lzma2DecMt.obj \
$O\Lzma2Enc.obj \
$O\LzmaDec.obj \
$O\LzmaEnc.obj \
$O\MtCoder.obj \
+ $O\MtDec.obj \
$O\Threads.obj \
!include "../../Crc.mak"
+!include "../../LzmaDec.mak"
!include "../../7zip.mak"
diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp b/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
index fdad478..f273337 100644
--- a/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
+++ b/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
@@ -4,6 +4,8 @@
#include <stdio.h>
+#include "../../../../C/CpuArch.h"
+
#if (defined(_WIN32) || defined(OS2) || defined(MSDOS)) && !defined(UNDER_CE)
#include <fcntl.h>
#include <io.h>
@@ -39,14 +41,16 @@
#include "../../UI/Console/BenchCon.h"
#include "../../UI/Console/ConsoleClose.h"
+bool g_LargePagesMode = false;
+
using namespace NCommandLineParser;
static const unsigned kDictSizeLog = 24;
-static const char *kCopyrightString = "\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n\n";
+#define kCopyrightString "\nLZMA " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n"
-static const char *kHelpString =
- "Usage: LZMA <command> [inputFile] [outputFile] [<switches>...]\n"
+static const char * const kHelpString =
+ "Usage: lzma <command> [inputFile] [outputFile] [<switches>...]\n"
"\n"
"<command>\n"
" e : Encode file\n"
@@ -67,9 +71,9 @@ static const char *kHelpString =
" -so : write data to stdout\n";
-static const char *kCantAllocate = "Can not allocate memory";
-static const char *kReadError = "Read error";
-static const char *kWriteError = "Write error";
+static const char * const kCantAllocate = "Can not allocate memory";
+static const char * const kReadError = "Read error";
+static const char * const kWriteError = "Write error";
namespace NKey {
@@ -117,6 +121,21 @@ static const CSwitchForm kSwitchForms[] =
};
+static void Convert_UString_to_AString(const UString &s, AString &temp)
+{
+ int codePage = CP_OEMCP;
+ /*
+ int g_CodePage = -1;
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8(s, temp);
+ else
+ */
+ UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
+}
+
static void PrintErr(const char *s)
{
fputs(s, stderr);
@@ -135,10 +154,12 @@ static void PrintError(const char *s)
PrintErr_LF(s);
}
-static void PrintError2(const char *s1, const wchar_t *s2)
+static void PrintError2(const char *s1, const UString &s2)
{
PrintError(s1);
- PrintErr_LF(GetOemString(s2));
+ AString a;
+ Convert_UString_to_AString(s2, a);
+ PrintErr_LF(a);
}
static void PrintError_int(const char *s, int code)
@@ -208,7 +229,7 @@ public:
#define BACK_STR \
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
-static const char *kBackSpaces =
+static const char * const kBackSpaces =
BACK_STR
" "
BACK_STR;
@@ -298,7 +319,7 @@ static int Error_HRESULT(const char *s, HRESULT res)
static void AddProp(CObjectVector<CProperty> &props2, const char *name, const wchar_t *val)
{
CProperty &prop = props2.AddNew();
- prop.Name.SetFromAscii(name);
+ prop.Name = name;
prop.Value = val;
}
@@ -322,10 +343,10 @@ static int main2(int numArgs, const char *args[])
for (int i = 1; i < numArgs; i++)
commandStrings.Add(MultiByteToUnicodeString(args[i]));
- CParser parser(ARRAY_SIZE(kSwitchForms));
+ CParser parser;
try
{
- if (!parser.ParseStrings(kSwitchForms, commandStrings))
+ if (!parser.ParseStrings(kSwitchForms, ARRAY_SIZE(kSwitchForms), commandStrings))
{
PrintError2(parser.ErrorMessage, parser.ErrorLine);
return 1;
@@ -376,7 +397,7 @@ static int main2(int numArgs, const char *args[])
AddProp(props2, "x", s);
}
- UString mf = L"BT4";
+ UString mf ("BT4");
if (parser[NKey::kMatchFinder].ThereIs)
mf = parser[NKey::kMatchFinder].PostStrings[0];
diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
index f1e9a9e..8775319 100644
--- a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
+++ b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
@@ -117,6 +117,10 @@ SOURCE=..\..\Archive\Common\CoderMixer2.h
# End Source File
# Begin Source File
+SOURCE=..\..\Archive\Common\HandlerOut.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
# End Source File
# Begin Source File
@@ -293,6 +297,10 @@ SOURCE=..\..\Compress\Lzma2Decoder.cpp
# End Source File
# Begin Source File
+SOURCE=..\..\Compress\Lzma2Decoder.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Compress\Lzma2Register.cpp
# End Source File
# Begin Source File
@@ -411,6 +419,14 @@ SOURCE=..\..\..\Windows\Synchronization.cpp
SOURCE=..\..\..\Windows\Synchronization.h
# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.h
+# End Source File
# End Group
# Begin Group "Common"
@@ -822,6 +838,15 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\Lzma2DecMt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Lzma2DecMt.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\LzmaDec.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -831,6 +856,15 @@ SOURCE=..\..\..\..\C\LzmaDec.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\MtDec.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\MtDec.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\Ppmd7.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
diff --git a/CPP/7zip/Bundles/SFXCon/SfxCon.cpp b/CPP/7zip/Bundles/SFXCon/SfxCon.cpp
index e67c671..9b34a08 100644
--- a/CPP/7zip/Bundles/SFXCon/SfxCon.cpp
+++ b/CPP/7zip/Bundles/SFXCon/SfxCon.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../../../../C/CpuArch.h"
+
#include "../../../Common/MyWindows.h"
#include "../../../Common/MyInitGuid.h"
@@ -37,8 +39,8 @@ HINSTANCE g_hInstance = 0;
int g_CodePage = -1;
extern CStdOutStream *g_StdStream;
-static const char *kCopyrightString =
-"\n7-Zip SFX " MY_VERSION_COPYRIGHT_DATE "\n";
+static const char * const kCopyrightString =
+"\n7-Zip SFX " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n";
static const int kNumSwitches = 6;
@@ -65,7 +67,6 @@ enum EEnum
}
/*
static const char kRecursedIDChar = 'R';
-static const wchar_t *kRecursedPostCharSet = L"0-";
namespace NRecursedPostCharIndex {
enum EEnum
@@ -101,10 +102,10 @@ static const NRecursedType::EEnum kCommandRecursedDefault[kNumCommandForms] =
// static const bool kTestExtractRecursedDefault = true;
// static const bool kAddRecursedDefault = false;
-static const wchar_t *kUniversalWildcard = L"*";
+static const char * const kUniversalWildcard = "*";
static const int kCommandIndex = 0;
-static const char *kHelpString =
+static const char * const kHelpString =
"\nUsage: 7zSFX [<command>] [<switches>...] [<file_name>...]\n"
"\n"
"<Commands>\n"
@@ -121,16 +122,16 @@ static const char *kHelpString =
// ---------------------------
// exception messages
-static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError
-// static const char *kIncorrectListFile = "Incorrect wildcard in listfile";
-static const char *kIncorrectWildcardInCommandLine = "Incorrect wildcard in command line";
+static const char * const kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError
+// static const char * const kIncorrectListFile = "Incorrect wildcard in listfile";
+static const char * const kIncorrectWildcardInCommandLine = "Incorrect wildcard in command line";
// static const CSysString kFileIsNotArchiveMessageBefore = "File \"";
// static const CSysString kFileIsNotArchiveMessageAfter = "\" is not archive";
-// static const char *kProcessArchiveMessage = " archive: ";
+// static const char * const kProcessArchiveMessage = " archive: ";
-static const char *kCantFindSFX = " cannot find sfx";
+static const char * const kCantFindSFX = " cannot find sfx";
namespace NCommandType
{
@@ -280,13 +281,16 @@ int Main2(
#endif
- commandStrings.Delete(0);
+ #ifndef UNDER_CE
+ if (commandStrings.Size() > 0)
+ commandStrings.Delete(0);
+ #endif
- NCommandLineParser::CParser parser(kNumSwitches);
+ NCommandLineParser::CParser parser;
try
{
- if (!parser.ParseStrings(kSwitchForms, commandStrings))
+ if (!parser.ParseStrings(kSwitchForms, kNumSwitches, commandStrings))
{
g_StdOut << "Command line error:" << endl
<< parser.ErrorMessage << endl
@@ -331,7 +335,7 @@ int Main2(
{
if (nonSwitchStrings.Size() == curCommandIndex)
- AddCommandLineWildcardToCensor(wildcardCensor, kUniversalWildcard, true, recursedType);
+ AddCommandLineWildcardToCensor(wildcardCensor, (UString)kUniversalWildcard, true, recursedType);
for (; curCommandIndex < nonSwitchStrings.Size(); curCommandIndex++)
{
const UString &s = nonSwitchStrings[curCommandIndex];
diff --git a/CPP/7zip/Bundles/SFXCon/makefile b/CPP/7zip/Bundles/SFXCon/makefile
index d81e512..30e8a38 100644
--- a/CPP/7zip/Bundles/SFXCon/makefile
+++ b/CPP/7zip/Bundles/SFXCon/makefile
@@ -1,5 +1,7 @@
PROG = 7zCon.sfx
MY_CONSOLE = 1
+MY_FIXED = 1
+
CFLAGS = $(CFLAGS) \
-DEXTRACT_ONLY \
-DNO_READ_FROM_CODER \
@@ -41,6 +43,7 @@ WIN_OBJS = \
$O\PropVariant.obj \
$O\PropVariantConv.obj \
$O\Synchronization.obj \
+ $O\System.obj \
7ZIP_COMMON_OBJS = \
$O\CreateCoder.obj \
@@ -117,7 +120,9 @@ C_OBJS = \
$O\Delta.obj \
$O\DllSecur.obj \
$O\Lzma2Dec.obj \
+ $O\Lzma2DecMt.obj \
$O\LzmaDec.obj \
+ $O\MtDec.obj \
$O\Ppmd7.obj \
$O\Ppmd7Dec.obj \
$O\Sha256.obj \
@@ -125,5 +130,6 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
+!include "../../LzmaDec.mak"
!include "../../7zip.mak"
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp
index 5708349..d35a24f 100644
--- a/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp
@@ -15,9 +15,9 @@ using namespace NWindows;
using namespace NFile;
using namespace NDir;
-static LPCWSTR kCantDeleteFile = L"Can not delete output file";
-static LPCWSTR kCantOpenFile = L"Can not open output file";
-static LPCWSTR kUnsupportedMethod = L"Unsupported Method";
+static LPCSTR const kCantDeleteFile = "Can not delete output file";
+static LPCSTR const kCantOpenFile = "Can not open output file";
+static LPCSTR const kUnsupportedMethod = "Unsupported Method";
void CExtractCallbackImp::Init(IInArchive *archiveHandler,
const FString &directoryPath,
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
index 6d5b55a..194e376 100644
--- a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
@@ -18,8 +18,8 @@ using namespace NWindows;
using namespace NFile;
using namespace NDir;
-static LPCWSTR kCantFindArchive = L"Can not find archive file";
-static LPCWSTR kCantOpenArchive = L"Can not open the file as archive";
+static LPCSTR const kCantFindArchive = "Can not find archive file";
+static LPCSTR const kCantOpenArchive = "Can not open the file as archive";
struct CThreadExtracting
{
@@ -73,7 +73,7 @@ struct CThreadExtracting
return;
}
- ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, L"Default", fi.MTime, 0);
+ ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, (UString)"Default", fi.MTime, 0);
Result = ArchiveLink.GetArchive()->Extract(0, (UInt32)(Int32)-1 , BoolToInt(false), ExtractCallback);
}
diff --git a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp
index 4bf2fb8..b1d740e 100644
--- a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp
+++ b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp
@@ -449,6 +449,14 @@ SOURCE=..\..\..\Windows\Synchronization.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Windows\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Windows\Window.cpp
# End Source File
# Begin Source File
@@ -469,6 +477,14 @@ SOURCE=..\..\Common\CreateCoder.h
# End Source File
# Begin Source File
+SOURCE=..\..\Common\CWrappers.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\CWrappers.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Common\FileStreams.cpp
# End Source File
# Begin Source File
@@ -724,6 +740,15 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\Lzma2DecMt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Lzma2DecMt.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\LzmaDec.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -733,6 +758,15 @@ SOURCE=..\..\..\..\C\LzmaDec.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\MtDec.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\MtDec.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\Threads.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
diff --git a/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp b/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp
index be44f39..1705a8d 100644
--- a/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp
@@ -33,7 +33,7 @@ using namespace NDir;
HINSTANCE g_hInstance;
-static CFSTR kTempDirPrefix = FTEXT("7zS");
+static CFSTR const kTempDirPrefix = FTEXT("7zS");
#define _SHELL_EXECUTE
@@ -169,7 +169,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
return 1;
}
- UString dirPrefix = L"." WSTRING_PATH_SEPARATOR;
+ UString dirPrefix ("." STRING_PATH_SEPARATOR);
UString appLaunched;
bool showProgress = true;
if (!config.IsEmpty())
@@ -181,12 +181,12 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
ShowErrorMessage(L"Config failed");
return 1;
}
- UString friendlyName = GetTextConfigValue(pairs, L"Title");
- UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt");
- UString progress = GetTextConfigValue(pairs, L"Progress");
+ UString friendlyName = GetTextConfigValue(pairs, "Title");
+ UString installPrompt = GetTextConfigValue(pairs, "BeginPrompt");
+ UString progress = GetTextConfigValue(pairs, "Progress");
if (progress.IsEqualTo_Ascii_NoCase("no"))
showProgress = false;
- int index = FindTextConfigItem(pairs, L"Directory");
+ int index = FindTextConfigItem(pairs, "Directory");
if (index >= 0)
dirPrefix = pairs[index].String;
if (!installPrompt.IsEmpty() && !assumeYes)
@@ -195,11 +195,11 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
MB_ICONQUESTION) != IDYES)
return 0;
}
- appLaunched = GetTextConfigValue(pairs, L"RunProgram");
+ appLaunched = GetTextConfigValue(pairs, "RunProgram");
#ifdef _SHELL_EXECUTE
- executeFile = GetTextConfigValue(pairs, L"ExecuteFile");
- executeParameters = GetTextConfigValue(pairs, L"ExecuteParameters");
+ executeFile = GetTextConfigValue(pairs, "ExecuteFile");
+ executeParameters = GetTextConfigValue(pairs, "ExecuteParameters");
#endif
}
@@ -260,7 +260,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
#ifdef _SHELL_EXECUTE
if (!executeFile.IsEmpty())
{
- CSysString filePath = GetSystemString(executeFile);
+ CSysString filePath (GetSystemString(executeFile));
SHELLEXECUTEINFO execInfo;
execInfo.cbSize = sizeof(execInfo);
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS
@@ -278,7 +278,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
executeParameters += switches;
}
- CSysString parametersSys = GetSystemString(executeParameters);
+ CSysString parametersSys (GetSystemString(executeParameters));
if (parametersSys.IsEmpty())
execInfo.lpParameters = NULL;
else
@@ -337,7 +337,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
PROCESS_INFORMATION processInformation;
- CSysString appLaunchedSys = GetSystemString(dirPrefix + appLaunched);
+ CSysString appLaunchedSys (GetSystemString(dirPrefix + appLaunched));
BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys,
NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */,
diff --git a/CPP/7zip/Bundles/SFXSetup/makefile b/CPP/7zip/Bundles/SFXSetup/makefile
index 2cd3976..b97daad 100644
--- a/CPP/7zip/Bundles/SFXSetup/makefile
+++ b/CPP/7zip/Bundles/SFXSetup/makefile
@@ -1,4 +1,6 @@
PROG = 7zS.sfx
+MY_FIXED = 1
+
CFLAGS = $(CFLAGS) \
-DNO_REGISTRY \
-DEXTRACT_ONLY \
@@ -33,6 +35,7 @@ WIN_OBJS = \
$O\PropVariant.obj \
$O\ResourceString.obj \
$O\Synchronization.obj \
+ $O\System.obj \
$O\Window.obj \
WIN_CTRL_OBJS = \
@@ -40,6 +43,7 @@ WIN_CTRL_OBJS = \
7ZIP_COMMON_OBJS = \
$O\CreateCoder.obj \
+ $O\CWrappers.obj \
$O\FileStreams.obj \
$O\InBuffer.obj \
$O\FilterCoder.obj \
@@ -102,9 +106,12 @@ C_OBJS = \
$O\Delta.obj \
$O\DllSecur.obj \
$O\Lzma2Dec.obj \
+ $O\Lzma2DecMt.obj \
$O\LzmaDec.obj \
+ $O\MtDec.obj \
$O\Threads.obj \
!include "../../Crc.mak"
+!include "../../LzmaDec.mak"
!include "../../7zip.mak"
diff --git a/CPP/7zip/Bundles/SFXWin/SFXWin.dsp b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
index 9ee6c77..83ec931 100644
--- a/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
+++ b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
@@ -633,6 +633,14 @@ SOURCE=..\..\..\Windows\Synchronization.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Windows\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Windows\Window.cpp
# End Source File
# Begin Source File
@@ -906,6 +914,15 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\Lzma2DecMt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Lzma2DecMt.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\LzmaDec.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -915,6 +932,15 @@ SOURCE=..\..\..\..\C\LzmaDec.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\MtDec.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\MtDec.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\Ppmd7.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
diff --git a/CPP/7zip/Bundles/SFXWin/SfxWin.cpp b/CPP/7zip/Bundles/SFXWin/SfxWin.cpp
index 3f05e10..5eade1a 100644
--- a/CPP/7zip/Bundles/SFXWin/SfxWin.cpp
+++ b/CPP/7zip/Bundles/SFXWin/SfxWin.cpp
@@ -65,7 +65,7 @@ static DWORD GetDllVersion(LPCTSTR dllName)
bool g_LVN_ITEMACTIVATE_Support = true;
-static const wchar_t *kUnknownExceptionMessage = L"ERROR: Unknown Error!";
+static const wchar_t * const kUnknownExceptionMessage = L"ERROR: Unknown Error!";
void ErrorMessageForHRESULT(HRESULT res)
{
diff --git a/CPP/7zip/Bundles/SFXWin/makefile b/CPP/7zip/Bundles/SFXWin/makefile
index 686eaff..21a67dd 100644
--- a/CPP/7zip/Bundles/SFXWin/makefile
+++ b/CPP/7zip/Bundles/SFXWin/makefile
@@ -1,4 +1,6 @@
PROG = 7z.sfx
+MY_FIXED = 1
+
CFLAGS = $(CFLAGS) \
-DNO_REGISTRY \
-DEXTRACT_ONLY \
@@ -41,6 +43,7 @@ WIN_OBJS = \
$O\ResourceString.obj \
$O\Shell.obj \
$O\Synchronization.obj \
+ $O\System.obj \
$O\Window.obj \
WIN_CTRL_OBJS = \
@@ -135,7 +138,9 @@ C_OBJS = \
$O\Delta.obj \
$O\DllSecur.obj \
$O\Lzma2Dec.obj \
+ $O\Lzma2DecMt.obj \
$O\LzmaDec.obj \
+ $O\MtDec.obj \
$O\Ppmd7.obj \
$O\Ppmd7Dec.obj \
$O\Sha256.obj \
@@ -143,5 +148,6 @@ C_OBJS = \
!include "../../Aes.mak"
!include "../../Crc.mak"
+!include "../../LzmaDec.mak"
!include "../../7zip.mak"
diff --git a/CPP/7zip/Common/CWrappers.cpp b/CPP/7zip/Common/CWrappers.cpp
index 8bf3718..e726dad 100644
--- a/CPP/7zip/Common/CWrappers.cpp
+++ b/CPP/7zip/Common/CWrappers.cpp
@@ -8,43 +8,74 @@
#include "StreamUtils.h"
+SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) throw()
+{
+ switch (res)
+ {
+ case S_OK: return SZ_OK;
+ case E_OUTOFMEMORY: return SZ_ERROR_MEM;
+ case E_INVALIDARG: return SZ_ERROR_PARAM;
+ case E_ABORT: return SZ_ERROR_PROGRESS;
+ case S_FALSE: return SZ_ERROR_DATA;
+ case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED;
+ }
+ return defaultRes;
+}
+
+
+HRESULT SResToHRESULT(SRes res) throw()
+{
+ switch (res)
+ {
+ case SZ_OK: return S_OK;
+
+ case SZ_ERROR_DATA:
+ case SZ_ERROR_CRC:
+ case SZ_ERROR_INPUT_EOF:
+ return S_FALSE;
+
+ case SZ_ERROR_MEM: return E_OUTOFMEMORY;
+ case SZ_ERROR_PARAM: return E_INVALIDARG;
+ case SZ_ERROR_PROGRESS: return E_ABORT;
+ case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
+ // case SZ_ERROR_OUTPUT_EOF:
+ // case SZ_ERROR_READ:
+ // case SZ_ERROR_WRITE:
+ // case SZ_ERROR_THREAD:
+ // case SZ_ERROR_ARCHIVE:
+ // case SZ_ERROR_NO_ARCHIVE:
+ // return E_FAIL;
+ }
+ if (res < 0)
+ return res;
+ return E_FAIL;
+}
+
+
#define PROGRESS_UNKNOWN_VALUE ((UInt64)(Int64)-1)
#define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x)
-static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize) throw()
+
+static SRes CompressProgress(const ICompressProgress *pp, UInt64 inSize, UInt64 outSize) throw()
{
- CCompressProgressWrap *p = (CCompressProgressWrap *)pp;
+ CCompressProgressWrap *p = CONTAINER_FROM_VTBL(pp, CCompressProgressWrap, vt);
p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize));
- return (SRes)p->Res;
+ return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS);
}
-CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress) throw()
+void CCompressProgressWrap::Init(ICompressProgressInfo *progress) throw()
{
- p.Progress = CompressProgress;
+ vt.Progress = CompressProgress;
Progress = progress;
Res = SZ_OK;
}
static const UInt32 kStreamStepSize = (UInt32)1 << 31;
-SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes)
-{
- switch (res)
- {
- case S_OK: return SZ_OK;
- case E_OUTOFMEMORY: return SZ_ERROR_MEM;
- case E_INVALIDARG: return SZ_ERROR_PARAM;
- case E_ABORT: return SZ_ERROR_PROGRESS;
- case S_FALSE: return SZ_ERROR_DATA;
- case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED;
- }
- return defaultRes;
-}
-
-static SRes MyRead(void *object, void *data, size_t *size) throw()
+static SRes MyRead(const ISeqInStream *pp, void *data, size_t *size) throw()
{
- CSeqInStreamWrap *p = (CSeqInStreamWrap *)object;
+ CSeqInStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeqInStreamWrap, vt);
UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
p->Res = (p->Stream->Read(data, curSize, &curSize));
*size = curSize;
@@ -54,9 +85,9 @@ static SRes MyRead(void *object, void *data, size_t *size) throw()
return HRESULT_To_SRes(p->Res, SZ_ERROR_READ);
}
-static size_t MyWrite(void *object, const void *data, size_t size) throw()
+static size_t MyWrite(const ISeqOutStream *pp, const void *data, size_t size) throw()
{
- CSeqOutStreamWrap *p = (CSeqOutStreamWrap *)object;
+ CSeqOutStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeqOutStreamWrap, vt);
if (p->Stream)
{
p->Res = WriteStream(p->Stream, data, size);
@@ -69,47 +100,36 @@ static size_t MyWrite(void *object, const void *data, size_t size) throw()
return size;
}
-CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream) throw()
+
+void CSeqInStreamWrap::Init(ISequentialInStream *stream) throw()
{
- p.Read = MyRead;
+ vt.Read = MyRead;
Stream = stream;
Processed = 0;
+ Res = S_OK;
}
-CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw()
+void CSeqOutStreamWrap::Init(ISequentialOutStream *stream) throw()
{
- p.Write = MyWrite;
+ vt.Write = MyWrite;
Stream = stream;
Res = SZ_OK;
Processed = 0;
}
-HRESULT SResToHRESULT(SRes res) throw()
-{
- switch (res)
- {
- case SZ_OK: return S_OK;
- case SZ_ERROR_MEM: return E_OUTOFMEMORY;
- case SZ_ERROR_PARAM: return E_INVALIDARG;
- case SZ_ERROR_PROGRESS: return E_ABORT;
- case SZ_ERROR_DATA: return S_FALSE;
- case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
- }
- return E_FAIL;
-}
-static SRes InStreamWrap_Read(void *pp, void *data, size_t *size) throw()
+static SRes InStreamWrap_Read(const ISeekInStream *pp, void *data, size_t *size) throw()
{
- CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;
+ CSeekInStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeekInStreamWrap, vt);
UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
p->Res = p->Stream->Read(data, curSize, &curSize);
*size = curSize;
return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
}
-static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw()
+static SRes InStreamWrap_Seek(const ISeekInStream *pp, Int64 *offset, ESzSeek origin) throw()
{
- CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;
+ CSeekInStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeekInStreamWrap, vt);
UInt32 moveMethod;
switch (origin)
{
@@ -124,11 +144,11 @@ static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw()
return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
}
-CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw()
+void CSeekInStreamWrap::Init(IInStream *stream) throw()
{
Stream = stream;
- p.Read = InStreamWrap_Read;
- p.Seek = InStreamWrap_Seek;
+ vt.Read = InStreamWrap_Read;
+ vt.Seek = InStreamWrap_Seek;
Res = S_OK;
}
@@ -168,9 +188,9 @@ Byte CByteInBufWrap::ReadByteFromNewBlock() throw()
return 0;
}
-static Byte Wrap_ReadByte(void *pp) throw()
+static Byte Wrap_ReadByte(const IByteIn *pp) throw()
{
- CByteInBufWrap *p = (CByteInBufWrap *)pp;
+ CByteInBufWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CByteInBufWrap, vt);
if (p->Cur != p->Lim)
return *p->Cur++;
return p->ReadByteFromNewBlock();
@@ -178,7 +198,7 @@ static Byte Wrap_ReadByte(void *pp) throw()
CByteInBufWrap::CByteInBufWrap(): Buf(0)
{
- p.Read = Wrap_ReadByte;
+ vt.Read = Wrap_ReadByte;
}
@@ -214,9 +234,9 @@ HRESULT CByteOutBufWrap::Flush() throw()
return Res;
}
-static void Wrap_WriteByte(void *pp, Byte b) throw()
+static void Wrap_WriteByte(const IByteOut *pp, Byte b) throw()
{
- CByteOutBufWrap *p = (CByteOutBufWrap *)pp;
+ CByteOutBufWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CByteOutBufWrap, vt);
Byte *dest = p->Cur;
*dest = b;
p->Cur = ++dest;
@@ -226,5 +246,5 @@ static void Wrap_WriteByte(void *pp, Byte b) throw()
CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0)
{
- p.Write = Wrap_WriteByte;
+ vt.Write = Wrap_WriteByte;
}
diff --git a/CPP/7zip/Common/CWrappers.h b/CPP/7zip/Common/CWrappers.h
index 0872133..f93c98a 100644
--- a/CPP/7zip/Common/CWrappers.h
+++ b/CPP/7zip/Common/CWrappers.h
@@ -6,49 +6,54 @@
#include "../ICoder.h"
#include "../../Common/MyCom.h"
+SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) throw();
+HRESULT SResToHRESULT(SRes res) throw();
+
struct CCompressProgressWrap
{
- ICompressProgress p;
+ ICompressProgress vt;
ICompressProgressInfo *Progress;
HRESULT Res;
- CCompressProgressWrap(ICompressProgressInfo *progress) throw();
+ void Init(ICompressProgressInfo *progress) throw();
};
+
struct CSeqInStreamWrap
{
- ISeqInStream p;
+ ISeqInStream vt;
ISequentialInStream *Stream;
HRESULT Res;
UInt64 Processed;
- CSeqInStreamWrap(ISequentialInStream *stream) throw();
+ void Init(ISequentialInStream *stream) throw();
};
+
struct CSeekInStreamWrap
{
- ISeekInStream p;
+ ISeekInStream vt;
IInStream *Stream;
HRESULT Res;
- CSeekInStreamWrap(IInStream *stream) throw();
+ void Init(IInStream *stream) throw();
};
+
struct CSeqOutStreamWrap
{
- ISeqOutStream p;
+ ISeqOutStream vt;
ISequentialOutStream *Stream;
HRESULT Res;
UInt64 Processed;
- CSeqOutStreamWrap(ISequentialOutStream *stream) throw();
+ void Init(ISequentialOutStream *stream) throw();
};
-HRESULT SResToHRESULT(SRes res) throw();
struct CByteInBufWrap
{
- IByteIn p;
+ IByteIn vt;
const Byte *Cur;
const Byte *Lim;
Byte *Buf;
@@ -79,9 +84,10 @@ struct CByteInBufWrap
}
};
+
struct CByteOutBufWrap
{
- IByteOut p;
+ IByteOut vt;
Byte *Cur;
const Byte *Lim;
Byte *Buf;
diff --git a/CPP/7zip/Common/CreateCoder.cpp b/CPP/7zip/Common/CreateCoder.cpp
index 53e7631..5040765 100644
--- a/CPP/7zip/Common/CreateCoder.cpp
+++ b/CPP/7zip/Common/CreateCoder.cpp
@@ -148,20 +148,23 @@ HRESULT CExternalCodecs::Load()
#endif
-bool FindMethod(
+int FindMethod_Index(
DECL_EXTERNAL_CODECS_LOC_VARS
const AString &name,
- CMethodId &methodId, UInt32 &numStreams)
+ bool encode,
+ CMethodId &methodId,
+ UInt32 &numStreams)
{
unsigned i;
for (i = 0; i < g_NumCodecs; i++)
{
const CCodecInfo &codec = *g_Codecs[i];
- if (StringsAreEqualNoCase_Ascii(name, codec.Name))
+ if ((encode ? codec.CreateEncoder : codec.CreateDecoder)
+ && StringsAreEqualNoCase_Ascii(name, codec.Name))
{
methodId = codec.Id;
numStreams = codec.NumStreams;
- return true;
+ return i;
}
}
@@ -173,19 +176,51 @@ bool FindMethod(
for (i = 0; i < __externalCodecs->Codecs.Size(); i++)
{
const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
- if (StringsAreEqualNoCase_Ascii(name, codec.Name))
+ if ((encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned)
+ && StringsAreEqualNoCase_Ascii(name, codec.Name))
{
methodId = codec.Id;
numStreams = codec.NumStreams;
- return true;
+ return g_NumCodecs + i;
}
}
#endif
- return false;
+ return -1;
+}
+
+
+static int FindMethod_Index(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, bool encode)
+{
+ unsigned i;
+ for (i = 0; i < g_NumCodecs; i++)
+ {
+ const CCodecInfo &codec = *g_Codecs[i];
+ if (codec.Id == methodId && (encode ? codec.CreateEncoder : codec.CreateDecoder))
+ return i;
+ }
+
+ #ifdef EXTERNAL_CODECS
+
+ CHECK_GLOBAL_CODECS
+
+ if (__externalCodecs)
+ for (i = 0; i < __externalCodecs->Codecs.Size(); i++)
+ {
+ const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
+ if (codec.Id == methodId && (encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned))
+ return g_NumCodecs + i;
+ }
+
+ #endif
+
+ return -1;
}
+
bool FindMethod(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId,
@@ -280,9 +315,11 @@ void GetHashMethods(
#endif
}
-HRESULT CreateCoder(
+
+
+HRESULT CreateCoder_Index(
DECL_EXTERNAL_CODECS_LOC_VARS
- CMethodId methodId, bool encode,
+ unsigned i, bool encode,
CMyComPtr<ICompressFilter> &filter,
CCreatedCoder &cod)
{
@@ -290,11 +327,10 @@ HRESULT CreateCoder(
cod.IsFilter = false;
cod.NumStreams = 1;
- unsigned i;
- for (i = 0; i < g_NumCodecs; i++)
+ if (i < g_NumCodecs)
{
const CCodecInfo &codec = *g_Codecs[i];
- if (codec.Id == methodId)
+ // if (codec.Id == methodId)
{
if (encode)
{
@@ -325,11 +361,12 @@ HRESULT CreateCoder(
if (__externalCodecs)
{
+ i -= g_NumCodecs;
cod.IsExternal = true;
- for (i = 0; i < __externalCodecs->Codecs.Size(); i++)
+ if (i < __externalCodecs->Codecs.Size())
{
const CCodecInfoEx &codec = __externalCodecs->Codecs[i];
- if (codec.Id == methodId)
+ // if (codec.Id == methodId)
{
if (encode)
{
@@ -371,13 +408,50 @@ HRESULT CreateCoder(
return S_OK;
}
-HRESULT CreateCoder(
+
+HRESULT CreateCoder_Index(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ unsigned index, bool encode,
+ CCreatedCoder &cod)
+{
+ CMyComPtr<ICompressFilter> filter;
+ HRESULT res = CreateCoder_Index(
+ EXTERNAL_CODECS_LOC_VARS
+ index, encode,
+ filter, cod);
+
+ if (filter)
+ {
+ cod.IsFilter = true;
+ CFilterCoder *coderSpec = new CFilterCoder(encode);
+ cod.Coder = coderSpec;
+ coderSpec->Filter = filter;
+ }
+
+ return res;
+}
+
+
+HRESULT CreateCoder_Id(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ CMethodId methodId, bool encode,
+ CMyComPtr<ICompressFilter> &filter,
+ CCreatedCoder &cod)
+{
+ int index = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS methodId, encode);
+ if (index < 0)
+ return S_OK;
+ return CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS index, encode, filter, cod);
+}
+
+
+HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode,
CCreatedCoder &cod)
{
CMyComPtr<ICompressFilter> filter;
- HRESULT res = CreateCoder(
+ HRESULT res = CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
methodId, encode,
filter, cod);
@@ -393,13 +467,14 @@ HRESULT CreateCoder(
return res;
}
-HRESULT CreateCoder(
+
+HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode,
CMyComPtr<ICompressCoder> &coder)
{
CCreatedCoder cod;
- HRESULT res = CreateCoder(
+ HRESULT res = CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
methodId, encode,
cod);
@@ -413,7 +488,7 @@ HRESULT CreateFilter(
CMyComPtr<ICompressFilter> &filter)
{
CCreatedCoder cod;
- return CreateCoder(
+ return CreateCoder_Id(
EXTERNAL_CODECS_LOC_VARS
methodId, encode,
filter, cod);
diff --git a/CPP/7zip/Common/CreateCoder.h b/CPP/7zip/Common/CreateCoder.h
index e0956e1..2105818 100644
--- a/CPP/7zip/Common/CreateCoder.h
+++ b/CPP/7zip/Common/CreateCoder.h
@@ -116,13 +116,12 @@ extern CExternalCodecs g_ExternalCodecs;
#endif
-
-
-
-bool FindMethod(
+int FindMethod_Index(
DECL_EXTERNAL_CODECS_LOC_VARS
const AString &name,
- CMethodId &methodId, UInt32 &numStreams);
+ bool encode,
+ CMethodId &methodId,
+ UInt32 &numStreams);
bool FindMethod(
DECL_EXTERNAL_CODECS_LOC_VARS
@@ -152,18 +151,29 @@ struct CCreatedCoder
};
-HRESULT CreateCoder(
+HRESULT CreateCoder_Index(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ unsigned codecIndex, bool encode,
+ CMyComPtr<ICompressFilter> &filter,
+ CCreatedCoder &cod);
+
+HRESULT CreateCoder_Index(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ unsigned index, bool encode,
+ CCreatedCoder &cod);
+
+HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode,
CMyComPtr<ICompressFilter> &filter,
CCreatedCoder &cod);
-HRESULT CreateCoder(
+HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode,
CCreatedCoder &cod);
-HRESULT CreateCoder(
+HRESULT CreateCoder_Id(
DECL_EXTERNAL_CODECS_LOC_VARS
CMethodId methodId, bool encode,
CMyComPtr<ICompressCoder> &coder);
diff --git a/CPP/7zip/Common/FilePathAutoRename.cpp b/CPP/7zip/Common/FilePathAutoRename.cpp
index 6cbadf5..84c9e2b 100644
--- a/CPP/7zip/Common/FilePathAutoRename.cpp
+++ b/CPP/7zip/Common/FilePathAutoRename.cpp
@@ -2,9 +2,6 @@
#include "StdAfx.h"
-#include "../../Common/Defs.h"
-#include "../../Common/IntToString.h"
-
#include "../../Windows/FileFind.h"
#include "FilePathAutoRename.h"
@@ -14,10 +11,8 @@ using namespace NWindows;
static bool MakeAutoName(const FString &name,
const FString &extension, UInt32 value, FString &path)
{
- char temp[16];
- ConvertUInt32ToString(value, temp);
path = name;
- path.AddAscii(temp);
+ path.Add_UInt32(value);
path += extension;
return NFile::NFind::DoesFileOrDirExist(path);
}
@@ -34,7 +29,7 @@ bool AutoRenamePath(FString &path)
name.DeleteFrom(dotPos);
extension = path.Ptr(dotPos);
}
- name += FTEXT('_');
+ name += '_';
FString temp;
diff --git a/CPP/7zip/Common/FilterCoder.h b/CPP/7zip/Common/FilterCoder.h
index 7890e56..0e2f84f 100644
--- a/CPP/7zip/Common/FilterCoder.h
+++ b/CPP/7zip/Common/FilterCoder.h
@@ -153,6 +153,15 @@ public:
~C_OutStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); }
};
+ class C_Filter_Releaser
+ {
+ public:
+ CFilterCoder *FilterCoder;
+ C_Filter_Releaser(): FilterCoder(NULL) {}
+ ~C_Filter_Releaser() { if (FilterCoder) FilterCoder->Filter.Release(); }
+ };
+
+
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
diff --git a/CPP/7zip/Common/InBuffer.cpp b/CPP/7zip/Common/InBuffer.cpp
index 7765d1b..826e98b 100644
--- a/CPP/7zip/Common/InBuffer.cpp
+++ b/CPP/7zip/Common/InBuffer.cpp
@@ -97,6 +97,33 @@ Byte CInBufferBase::ReadByte_FromNewBlock()
size_t CInBufferBase::ReadBytes(Byte *buf, size_t size)
{
+ size_t num = 0;
+ for (;;)
+ {
+ const size_t rem = _bufLim - _buf;
+ if (size <= rem)
+ {
+ if (size != 0)
+ {
+ memcpy(buf, _buf, size);
+ _buf += size;
+ num += size;
+ }
+ return num;
+ }
+ if (rem != 0)
+ {
+ memcpy(buf, _buf, rem);
+ _buf += rem;
+ buf += rem;
+ num += rem;
+ size -= rem;
+ }
+ if (!ReadBlock())
+ return num;
+ }
+
+ /*
if ((size_t)(_bufLim - _buf) >= size)
{
const Byte *src = _buf;
@@ -113,6 +140,7 @@ size_t CInBufferBase::ReadBytes(Byte *buf, size_t size)
buf[i] = *_buf++;
}
return size;
+ */
}
size_t CInBufferBase::Skip(size_t size)
diff --git a/CPP/7zip/Common/InBuffer.h b/CPP/7zip/Common/InBuffer.h
index f353b37..76e359a 100644
--- a/CPP/7zip/Common/InBuffer.h
+++ b/CPP/7zip/Common/InBuffer.h
@@ -59,7 +59,8 @@ public:
}
void Init() throw();
-
+
+ MY_FORCE_INLINE
bool ReadByte(Byte &b)
{
if (_buf >= _bufLim)
@@ -68,6 +69,7 @@ public:
return true;
}
+ MY_FORCE_INLINE
Byte ReadByte()
{
if (_buf >= _bufLim)
diff --git a/CPP/7zip/Common/InOutTempBuffer.cpp b/CPP/7zip/Common/InOutTempBuffer.cpp
index cf4bffe..d83d674 100644
--- a/CPP/7zip/Common/InOutTempBuffer.cpp
+++ b/CPP/7zip/Common/InOutTempBuffer.cpp
@@ -15,7 +15,7 @@ using namespace NDir;
static const size_t kTempBufSize = (1 << 20);
-static CFSTR kTempFilePrefixString = FTEXT("7zt");
+#define kTempFilePrefixString FTEXT("7zt")
CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { }
diff --git a/CPP/7zip/Common/MethodProps.cpp b/CPP/7zip/Common/MethodProps.cpp
index 7036572..2134462 100644
--- a/CPP/7zip/Common/MethodProps.cpp
+++ b/CPP/7zip/Common/MethodProps.cpp
@@ -8,9 +8,9 @@
using namespace NWindows;
-bool StringToBool(const UString &s, bool &res)
+bool StringToBool(const wchar_t *s, bool &res)
{
- if (s.IsEmpty() || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON"))
+ if (s[0] == 0 || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON"))
{
res = true;
return true;
@@ -42,6 +42,14 @@ unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number)
return (unsigned)(end - start);
}
+static unsigned ParseStringToUInt64(const UString &srcString, UInt64 &number)
+{
+ const wchar_t *start = srcString;
+ const wchar_t *end;
+ number = ConvertStringToUInt64(start, &end);
+ return (unsigned)(end - start);
+}
+
HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
{
// =VT_UI4
@@ -95,7 +103,7 @@ static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp)
{
const wchar_t *end;
UInt32 number = ConvertStringToUInt32(s, &end);
- unsigned numDigits = (unsigned)(end - s);
+ unsigned numDigits = (unsigned)(end - s.Ptr());
if (numDigits == 0 || s.Len() > numDigits + 1)
return E_INVALIDARG;
@@ -144,17 +152,29 @@ static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVaria
return S_OK;
}
if (prop.vt == VT_BSTR)
- return StringToDictSize(prop.bstrVal, destProp);
+ {
+ UString s;
+ s = prop.bstrVal;
+ return StringToDictSize(s, destProp);
+ }
return E_INVALIDARG;
}
-void CProps::AddProp32(PROPID propid, UInt32 level)
+void CProps::AddProp32(PROPID propid, UInt32 val)
+{
+ CProp &prop = Props.AddNew();
+ prop.IsOptional = true;
+ prop.Id = propid;
+ prop.Value = (UInt32)val;
+}
+
+void CProps::AddPropBool(PROPID propid, bool val)
{
CProp &prop = Props.AddNew();
prop.IsOptional = true;
prop.Id = propid;
- prop.Value = (UInt32)level;
+ prop.Value = val;
}
class CCoderProps
@@ -233,6 +253,9 @@ struct CNameToPropID
const char *Name;
};
+
+// the following are related to NCoderPropID::EEnum values
+
static const CNameToPropID g_NameToPropID[] =
{
{ VT_UI4, "" },
@@ -251,7 +274,12 @@ static const CNameToPropID g_NameToPropID[] =
{ VT_UI4, "mt" },
{ VT_BOOL, "eos" },
{ VT_UI4, "x" },
- { VT_UI4, "reduceSize" }
+ { VT_UI8, "reduce" },
+ { VT_UI8, "expect" },
+ { VT_UI4, "b" },
+ { VT_UI4, "check" },
+ { VT_BSTR, "filter" },
+ { VT_UI8, "memuse" }
};
static int FindPropIdExact(const UString &name)
@@ -269,6 +297,13 @@ static bool ConvertProperty(const PROPVARIANT &srcProp, VARTYPE varType, NCOM::C
destProp = srcProp;
return true;
}
+
+ if (varType == VT_UI8 && srcProp.vt == VT_UI4)
+ {
+ destProp = (UInt64)srcProp.ulVal;
+ return true;
+ }
+
if (varType == VT_BOOL)
{
bool res;
@@ -333,7 +368,8 @@ static bool IsLogSizeProp(PROPID propid)
case NCoderPropID::kDictionarySize:
case NCoderPropID::kUsedMemorySize:
case NCoderPropID::kBlockSize:
- case NCoderPropID::kReduceSize:
+ case NCoderPropID::kBlockSize2:
+ // case NCoderPropID::kReduceSize:
return true;
}
return false;
@@ -366,9 +402,22 @@ HRESULT CMethodProps::SetParam(const UString &name, const UString &value)
}
else if (!value.IsEmpty())
{
- UInt32 number;
- if (ParseStringToUInt32(value, number) == value.Len())
- propValue = number;
+ if (nameToPropID.VarType == VT_UI4)
+ {
+ UInt32 number;
+ if (ParseStringToUInt32(value, number) == value.Len())
+ propValue = number;
+ else
+ propValue = value;
+ }
+ else if (nameToPropID.VarType == VT_UI8)
+ {
+ UInt64 number;
+ if (ParseStringToUInt64(value, number) == value.Len())
+ propValue = number;
+ else
+ propValue = value;
+ }
else
propValue = value;
}
@@ -454,5 +503,7 @@ HRESULT COneMethodInfo::ParseMethodFromPROPVARIANT(const UString &realName, cons
// -m{N}=method
if (value.vt != VT_BSTR)
return E_INVALIDARG;
- return ParseMethodFromString(value.bstrVal);
+ UString s;
+ s = value.bstrVal;
+ return ParseMethodFromString(s);
}
diff --git a/CPP/7zip/Common/MethodProps.h b/CPP/7zip/Common/MethodProps.h
index 3f31c77..c8a3d0d 100644
--- a/CPP/7zip/Common/MethodProps.h
+++ b/CPP/7zip/Common/MethodProps.h
@@ -4,12 +4,15 @@
#define __7Z_METHOD_PROPS_H
#include "../../Common/MyString.h"
+#include "../../Common/Defs.h"
+
+#include "../../Windows/Defs.h"
#include "../../Windows/PropVariant.h"
#include "../ICoder.h"
-bool StringToBool(const UString &s, bool &res);
+bool StringToBool(const wchar_t *s, bool &res);
HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest);
unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number);
HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
@@ -38,7 +41,9 @@ struct CProps
return false;
}
- void AddProp32(PROPID propid, UInt32 level);
+ void AddProp32(PROPID propid, UInt32 val);
+
+ void AddPropBool(PROPID propid, bool val);
void AddProp_Ascii(PROPID propid, const char *s)
{
@@ -99,6 +104,18 @@ public:
return level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26));
}
+ bool Get_Lzma_Eos() const
+ {
+ int i = FindProp(NCoderPropID::kEndMarker);
+ if (i >= 0)
+ {
+ const NWindows::NCOM::CPropVariant &val = Props[i].Value;
+ if (val.vt == VT_BOOL)
+ return VARIANT_BOOLToBool(val.boolVal);
+ }
+ return false;
+ }
+
bool Are_Lzma_Model_Props_Defined() const
{
if (FindProp(NCoderPropID::kPosStateBits) >= 0) return true;
@@ -107,18 +124,64 @@ public:
return false;
}
- UInt32 Get_Lzma_NumThreads(bool &fixedNumber) const
+ UInt32 Get_Lzma_NumThreads() const
{
- fixedNumber = false;
+ if (Get_Lzma_Algo() == 0)
+ return 1;
int numThreads = Get_NumThreads();
if (numThreads >= 0)
- {
- fixedNumber = true;
return numThreads < 2 ? 1 : 2;
+ return 2;
+ }
+
+ int Get_Xz_NumThreads(UInt32 &lzmaThreads) const
+ {
+ lzmaThreads = 1;
+ int numThreads = Get_NumThreads();
+ if (numThreads >= 0 && numThreads <= 1)
+ return 1;
+ if (Get_Lzma_Algo() != 0)
+ lzmaThreads = 2;
+ return numThreads;
+ }
+
+ UInt64 GetProp_BlockSize(PROPID id) const
+ {
+ int i = FindProp(id);
+ if (i >= 0)
+ {
+ const NWindows::NCOM::CPropVariant &val = Props[i].Value;
+ if (val.vt == VT_UI4) { return val.ulVal; }
+ if (val.vt == VT_UI8) { return val.uhVal.QuadPart; }
}
- return Get_Lzma_Algo() == 0 ? 1 : 2;
+ return 0;
}
+ UInt64 Get_Xz_BlockSize() const
+ {
+ {
+ UInt64 blockSize1 = GetProp_BlockSize(NCoderPropID::kBlockSize);
+ UInt64 blockSize2 = GetProp_BlockSize(NCoderPropID::kBlockSize2);
+ UInt64 minSize = MyMin(blockSize1, blockSize2);
+ if (minSize != 0)
+ return minSize;
+ UInt64 maxSize = MyMax(blockSize1, blockSize2);
+ if (maxSize != 0)
+ return maxSize;
+ }
+ const UInt32 kMinSize = (UInt32)1 << 20;
+ const UInt32 kMaxSize = (UInt32)1 << 28;
+ UInt32 dictSize = Get_Lzma_DicSize();
+ UInt64 blockSize = (UInt64)dictSize << 2;
+ if (blockSize < kMinSize) blockSize = kMinSize;
+ if (blockSize > kMaxSize) blockSize = kMaxSize;
+ if (blockSize < dictSize) blockSize = dictSize;
+ blockSize += (kMinSize - 1);
+ blockSize &= ~(UInt64)(kMinSize - 1);
+ return blockSize;
+ }
+
+
UInt32 Get_BZip2_NumThreads(bool &fixedNumber) const
{
fixedNumber = false;
@@ -127,7 +190,8 @@ public:
{
fixedNumber = true;
if (numThreads < 1) return 1;
- if (numThreads > 64) return 64;
+ const unsigned kNumBZip2ThreadsMax = 64;
+ if (numThreads > kNumBZip2ThreadsMax) return kNumBZip2ThreadsMax;
return numThreads;
}
return 1;
@@ -170,6 +234,12 @@ public:
AddProp32(NCoderPropID::kNumThreads, numThreads);
}
+ void AddProp_EndMarker_if_NotFound(bool eos)
+ {
+ if (FindProp(NCoderPropID::kEndMarker) < 0)
+ AddPropBool(NCoderPropID::kEndMarker, eos);
+ }
+
HRESULT ParseParamsFromString(const UString &srcString);
HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
};
diff --git a/CPP/7zip/Common/OutBuffer.h b/CPP/7zip/Common/OutBuffer.h
index 90ce25d..2ffb5cd 100644
--- a/CPP/7zip/Common/OutBuffer.h
+++ b/CPP/7zip/Common/OutBuffer.h
@@ -47,8 +47,11 @@ public:
void WriteByte(Byte b)
{
- _buf[_pos++] = b;
- if (_pos == _limitPos)
+ UInt32 pos = _pos;
+ _buf[pos] = b;
+ pos++;
+ _pos = pos;
+ if (pos == _limitPos)
FlushWithCheck();
}
void WriteBytes(const void *data, size_t size)
diff --git a/CPP/7zip/Compress/Bcj2Coder.cpp b/CPP/7zip/Compress/Bcj2Coder.cpp
index 261a626..4e083bf 100644
--- a/CPP/7zip/Compress/Bcj2Coder.cpp
+++ b/CPP/7zip/Compress/Bcj2Coder.cpp
@@ -463,10 +463,10 @@ HRESULT CDecoder::Code(ISequentialInStream * const *inStreams, const UInt64 * co
if (progress)
{
- UInt64 outSize2 = outSizeProcessed + (dec.dest - _bufs[BCJ2_NUM_STREAMS]);
+ const UInt64 outSize2 = outSizeProcessed + (dec.dest - _bufs[BCJ2_NUM_STREAMS]);
if (outSize2 - prevProgress >= (1 << 22))
{
- UInt64 inSize2 = outSize2 + _inStreamsProcessed[BCJ2_STREAM_RC] - (dec.lims[BCJ2_STREAM_RC] - dec.bufs[BCJ2_STREAM_RC]);
+ const UInt64 inSize2 = outSize2 + _inStreamsProcessed[BCJ2_STREAM_RC] - (dec.lims[BCJ2_STREAM_RC] - dec.bufs[BCJ2_STREAM_RC]);
RINOK(progress->SetRatioInfo(&inSize2, &outSize2));
prevProgress = outSize2;
}
@@ -655,4 +655,12 @@ STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
return res;
}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value)
+{
+ const size_t rem = dec.lims[streamIndex] - dec.bufs[streamIndex] + _extraReadSizes[streamIndex];
+ *value = _inStreamsProcessed[streamIndex] - rem;
+ return S_OK;
+}
+
}}
diff --git a/CPP/7zip/Compress/Bcj2Coder.h b/CPP/7zip/Compress/Bcj2Coder.h
index ec58dab..666bf8c 100644
--- a/CPP/7zip/Compress/Bcj2Coder.h
+++ b/CPP/7zip/Compress/Bcj2Coder.h
@@ -62,6 +62,7 @@ public:
class CDecoder:
public ICompressCoder2,
public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize2,
public ICompressSetInStream2,
public ISequentialInStream,
public ICompressSetOutStreamSize,
@@ -84,9 +85,10 @@ class CDecoder:
// HRESULT ReadSpec();
public:
- MY_UNKNOWN_IMP6(
+ MY_UNKNOWN_IMP7(
ICompressCoder2,
ICompressSetFinishMode,
+ ICompressGetInStreamProcessedSize2,
ICompressSetInStream2,
ISequentialInStream,
ICompressSetOutStreamSize,
@@ -98,6 +100,7 @@ public:
ICompressProgressInfo *progress);
STDMETHOD(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize2)(UInt32 streamIndex, UInt64 *value);
STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream2)(UInt32 streamIndex);
diff --git a/CPP/7zip/Compress/CopyCoder.cpp b/CPP/7zip/Compress/CopyCoder.cpp
index 925493f..89b5237 100644
--- a/CPP/7zip/Compress/CopyCoder.cpp
+++ b/CPP/7zip/Compress/CopyCoder.cpp
@@ -15,6 +15,11 @@ CCopyCoder::~CCopyCoder()
::MidFree(_buf);
}
+STDMETHODIMP CCopyCoder::SetFinishMode(UInt32 /* finishMode */)
+{
+ return S_OK;
+}
+
STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize,
diff --git a/CPP/7zip/Compress/CopyCoder.h b/CPP/7zip/Compress/CopyCoder.h
index f2620f1..b2fa491 100644
--- a/CPP/7zip/Compress/CopyCoder.h
+++ b/CPP/7zip/Compress/CopyCoder.h
@@ -13,6 +13,7 @@ class CCopyCoder:
public ICompressCoder,
public ICompressSetInStream,
public ISequentialInStream,
+ public ICompressSetFinishMode,
public ICompressGetInStreamProcessedSize,
public CMyUnknownImp
{
@@ -24,10 +25,11 @@ public:
CCopyCoder(): _buf(0), TotalSize(0) {};
~CCopyCoder();
- MY_UNKNOWN_IMP4(
+ MY_UNKNOWN_IMP5(
ICompressCoder,
ICompressSetInStream,
ISequentialInStream,
+ ICompressSetFinishMode,
ICompressGetInStreamProcessedSize)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
@@ -35,6 +37,7 @@ public:
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(SetFinishMode)(UInt32 finishMode);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
};
diff --git a/CPP/7zip/Compress/Lzma2Decoder.cpp b/CPP/7zip/Compress/Lzma2Decoder.cpp
index 8b4afe2..bb631c5 100644
--- a/CPP/7zip/Compress/Lzma2Decoder.cpp
+++ b/CPP/7zip/Compress/Lzma2Decoder.cpp
@@ -2,263 +2,262 @@
#include "StdAfx.h"
+// #include <stdio.h>
+
#include "../../../C/Alloc.h"
+// #include "../../../C/CpuTicks.h"
#include "../Common/StreamUtils.h"
#include "Lzma2Decoder.h"
-static HRESULT SResToHRESULT(SRes res)
-{
- switch (res)
- {
- case SZ_OK: return S_OK;
- case SZ_ERROR_MEM: return E_OUTOFMEMORY;
- case SZ_ERROR_PARAM: return E_INVALIDARG;
- // case SZ_ERROR_PROGRESS: return E_ABORT;
- case SZ_ERROR_DATA: return S_FALSE;
- }
- return E_FAIL;
-}
-
namespace NCompress {
namespace NLzma2 {
CDecoder::CDecoder():
- _inBuf(NULL),
- _inBufSize(0),
- _inBufSizeNew(1 << 20),
- _outStepSize(1 << 22),
- _outSizeDefined(false),
- _finishMode(false)
-{
- Lzma2Dec_Construct(&_state);
-}
-
-STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; }
-STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStepSize = size; return S_OK; }
+ _dec(NULL)
+ , _inProcessed(0)
+ , _prop(0xFF)
+ , _finishMode(false)
+ , _inBufSize(1 << 20)
+ , _outStep(1 << 20)
+ #ifndef _7ZIP_ST
+ , _tryMt(1)
+ , _numThreads(1)
+ , _memUsage((UInt64)(sizeof(size_t)) << 28)
+ #endif
+{}
CDecoder::~CDecoder()
{
- Lzma2Dec_Free(&_state, &g_Alloc);
- MidFree(_inBuf);
+ if (_dec)
+ Lzma2DecMt_Destroy(_dec);
}
+STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; }
+STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStep = size; return S_OK; }
+
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
{
if (size != 1)
return E_NOTIMPL;
-
- RINOK(SResToHRESULT(Lzma2Dec_Allocate(&_state, prop[0], &g_Alloc)));
- if (!_inBuf || _inBufSize != _inBufSizeNew)
- {
- MidFree(_inBuf);
- _inBufSize = 0;
- _inBuf = (Byte *)MidAlloc(_inBufSizeNew);
- if (!_inBuf)
- return E_OUTOFMEMORY;
- _inBufSize = _inBufSizeNew;
- }
-
+ if (prop[0] > 40)
+ return E_NOTIMPL;
+ _prop = prop[0];
return S_OK;
}
-STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) { *value = _inSizeProcessed; return S_OK; }
-STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
-STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
-STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
{
- _outSizeDefined = (outSize != NULL);
- _outSize = 0;
- if (_outSizeDefined)
- _outSize = *outSize;
-
- Lzma2Dec_Init(&_state);
-
- _inPos = _inSize = 0;
- _inSizeProcessed = _outSizeProcessed = 0;
+ _finishMode = (finishMode != 0);
return S_OK;
}
-STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
+
+
+#ifndef _7ZIP_ST
+
+static UInt64 Get_ExpectedBlockSize_From_Dict(UInt32 dictSize)
{
- _finishMode = (finishMode != 0);
- return S_OK;
+ const UInt32 kMinSize = (UInt32)1 << 20;
+ const UInt32 kMaxSize = (UInt32)1 << 28;
+ UInt64 blockSize = (UInt64)dictSize << 2;
+ if (blockSize < kMinSize) blockSize = kMinSize;
+ if (blockSize > kMaxSize) blockSize = kMaxSize;
+ if (blockSize < dictSize) blockSize = dictSize;
+ blockSize += (kMinSize - 1);
+ blockSize &= ~(UInt64)(kMinSize - 1);
+ return blockSize;
}
-STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize,
- const UInt64 *outSize, ICompressProgressInfo *progress)
+#define LZMA2_DIC_SIZE_FROM_PROP_FULL(p) ((p) == 40 ? 0xFFFFFFFF : (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)))
+
+#endif
+
+#define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes;
+
+#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
- if (!_inBuf)
- return S_FALSE;
- SetOutStreamSize(outSize);
-
- UInt32 step = _outStepSize;
- const UInt32 kOutStepSize_Min = 1 << 12;
- if (step < kOutStepSize_Min)
- step = kOutStepSize_Min;
-
- SizeT wrPos = _state.decoder.dicPos;
+ _inProcessed = 0;
+
+ if (!_dec)
+ {
+ _dec = Lzma2DecMt_Create(
+ // &g_AlignedAlloc,
+ &g_Alloc,
+ &g_MidAlloc);
+ if (!_dec)
+ return E_OUTOFMEMORY;
+ }
- SizeT next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ?
- _state.decoder.dicBufSize :
- _state.decoder.dicPos + step;
+ CLzma2DecMtProps props;
+ Lzma2DecMtProps_Init(&props);
- HRESULT hres = S_OK;
+ props.inBufSize_ST = _inBufSize;
+ props.outStep_ST = _outStep;
- for (;;)
+ #ifndef _7ZIP_ST
{
- if (_inPos == _inSize)
- {
- _inPos = _inSize = 0;
- hres = inStream->Read(_inBuf, _inBufSize, &_inSize);
- if (hres != S_OK)
- break;
- }
+ props.numThreads = 1;
+ UInt32 numThreads = _numThreads;
- SizeT dicPos = _state.decoder.dicPos;
- SizeT curSize = next - dicPos;
-
- ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
- if (_outSizeDefined)
+ if (_tryMt && numThreads >= 1)
{
- const UInt64 rem = _outSize - _outSizeProcessed;
- if (curSize >= rem)
+ UInt64 useLimit = _memUsage;
+ UInt32 dictSize = LZMA2_DIC_SIZE_FROM_PROP_FULL(_prop);
+ UInt64 expectedBlockSize64 = Get_ExpectedBlockSize_From_Dict(dictSize);
+ size_t expectedBlockSize = (size_t)expectedBlockSize64;
+ size_t inBlockMax = expectedBlockSize + expectedBlockSize / 16;
+ if (expectedBlockSize == expectedBlockSize64 && inBlockMax >= expectedBlockSize)
{
- curSize = (SizeT)rem;
- if (_finishMode)
- finishMode = LZMA_FINISH_END;
+ props.outBlockMax = expectedBlockSize;
+ props.inBlockMax = inBlockMax;
+ const size_t kOverheadSize = props.inBufSize_MT + (1 << 16);
+ UInt64 okThreads = useLimit / (props.outBlockMax + props.inBlockMax + kOverheadSize);
+ if (numThreads > okThreads)
+ numThreads = (UInt32)okThreads;
+ if (numThreads == 0)
+ numThreads = 1;
+ props.numThreads = numThreads;
}
}
+ }
+ #endif
- SizeT inSizeProcessed = _inSize - _inPos;
- ELzmaStatus status;
- SRes res = Lzma2Dec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status);
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
- _inPos += (UInt32)inSizeProcessed;
- _inSizeProcessed += inSizeProcessed;
- SizeT outSizeProcessed = _state.decoder.dicPos - dicPos;
- _outSizeProcessed += outSizeProcessed;
+ inWrap.Init(inStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
- bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0
- || status == LZMA_STATUS_FINISHED_WITH_MARK);
- bool outFinished = (_outSizeDefined && _outSizeProcessed >= _outSize);
+ SRes res;
- if (res != 0
- || _state.decoder.dicPos >= next
- || finished
- || outFinished)
- {
- HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos);
+ UInt64 inProcessed = 0;
+ int isMT = False;
- if (_state.decoder.dicPos == _state.decoder.dicBufSize)
- _state.decoder.dicPos = 0;
-
- wrPos = _state.decoder.dicPos;
+ #ifndef _7ZIP_ST
+ isMT = _tryMt;
+ #endif
- next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ?
- _state.decoder.dicBufSize :
- _state.decoder.dicPos + step;
+ // UInt64 cpuTicks = GetCpuTicks();
- if (res != 0)
- return S_FALSE;
- RINOK(res2);
+ res = Lzma2DecMt_Decode(_dec, _prop, &props,
+ &outWrap.vt, outSize, _finishMode,
+ &inWrap.vt,
+ &inProcessed,
+ &isMT,
+ progress ? &progressWrap.vt : NULL);
- if (finished)
- {
- if (status == LZMA_STATUS_FINISHED_WITH_MARK)
- {
- if (_finishMode && inSize && *inSize != _inSizeProcessed)
- return S_FALSE;
- if (finishMode == LZMA_FINISH_END && !outFinished)
- return S_FALSE;
- return S_OK;
- }
- return (finishMode == LZMA_FINISH_END) ? S_FALSE : S_OK;
- }
+ /*
+ cpuTicks = GetCpuTicks() - cpuTicks;
+ printf("\n ticks = %10I64u\n", cpuTicks / 1000000);
+ */
- if (outFinished && finishMode == LZMA_FINISH_ANY)
- return S_OK;
- }
-
- if (progress)
- {
- RINOK(progress->SetRatioInfo(&_inSizeProcessed, &_outSizeProcessed));
- }
+
+ #ifndef _7ZIP_ST
+ /* we reset _tryMt, only if p->props.numThreads was changed */
+ if (props.numThreads > 1)
+ _tryMt = isMT;
+ #endif
+
+ _inProcessed = inProcessed;
+
+ RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
+ RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
+ RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ)
+
+ if (res == SZ_OK && _finishMode)
+ {
+ if (inSize && *inSize != inProcessed)
+ res = SZ_ERROR_DATA;
+ if (outSize && *outSize != outWrap.Processed)
+ res = SZ_ERROR_DATA;
}
- HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos);
- if (hres != S_OK)
- return hres;
- return res2;
+ return SResToHRESULT(res);
}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _inProcessed;
+ return S_OK;
+}
+
+
+#ifndef _7ZIP_ST
+
+STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)
+{
+ _numThreads = numThreads;
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetMemLimit(UInt64 memUsage)
+{
+ _memUsage = memUsage;
+ return S_OK;
+}
+
+#endif
+
+
#ifndef NO_READ_FROM_CODER
-STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
- UInt32 totalProcessed = 0;
+ CLzma2DecMtProps props;
+ Lzma2DecMtProps_Init(&props);
+ props.inBufSize_ST = _inBufSize;
+ props.outStep_ST = _outStep;
+
+ _inProcessed = 0;
+
+ if (!_dec)
+ {
+ _dec = Lzma2DecMt_Create(&g_AlignedAlloc, &g_MidAlloc);
+ if (!_dec)
+ return E_OUTOFMEMORY;
+ }
+
+ _inWrap.Init(_inStream);
+ SRes res = Lzma2DecMt_Init(_dec, _prop, &props, outSize, _finishMode, &_inWrap.vt);
+
+ if (res != SZ_OK)
+ return SResToHRESULT(res);
+ return S_OK;
+}
+
+
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
+STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
+
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
if (processedSize)
*processedSize = 0;
- for (;;)
- {
- if (_inPos == _inSize)
- {
- _inPos = _inSize = 0;
- RINOK(_inStream->Read(_inBuf, _inBufSize, &_inSize));
- }
- {
- ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
- if (_outSizeDefined)
- {
- const UInt64 rem = _outSize - _outSizeProcessed;
- if (rem <= size)
- {
- size = (UInt32)rem;
- if (_finishMode)
- finishMode = LZMA_FINISH_END;
- }
- }
+ size_t size2 = size;
+ UInt64 inProcessed = 0;
- SizeT outProcessed = size;
- SizeT inProcessed = _inSize - _inPos;
-
- ELzmaStatus status;
- SRes res = Lzma2Dec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,
- _inBuf + _inPos, &inProcessed, finishMode, &status);
-
- _inPos += (UInt32)inProcessed;
- _inSizeProcessed += inProcessed;
- _outSizeProcessed += outProcessed;
- size -= (UInt32)outProcessed;
- data = (Byte *)data + outProcessed;
-
- totalProcessed += (UInt32)outProcessed;
- if (processedSize)
- *processedSize = totalProcessed;
-
- if (res != SZ_OK)
- {
- if (totalProcessed != 0)
- return S_OK;
- return SResToHRESULT(res);
- }
-
- if (inProcessed == 0 && outProcessed == 0)
- return S_OK;
- if (status == LZMA_STATUS_FINISHED_WITH_MARK)
- return S_OK;
- if (outProcessed != 0)
- {
- if (finishMode != LZMA_FINISH_END || _outSize != _outSizeProcessed)
- return S_OK;
- }
- }
- }
+ SRes res = Lzma2DecMt_Read(_dec, (Byte *)data, &size2, &inProcessed);
+
+ _inProcessed += inProcessed;
+ if (processedSize)
+ *processedSize = (UInt32)size2;
+ if (res != SZ_OK)
+ return SResToHRESULT(res);
+ return S_OK;
}
#endif
diff --git a/CPP/7zip/Compress/Lzma2Decoder.h b/CPP/7zip/Compress/Lzma2Decoder.h
index 0ae43b0..b56488e 100644
--- a/CPP/7zip/Compress/Lzma2Decoder.h
+++ b/CPP/7zip/Compress/Lzma2Decoder.h
@@ -3,11 +3,9 @@
#ifndef __LZMA2_DECODER_H
#define __LZMA2_DECODER_H
-#include "../../../C/Lzma2Dec.h"
+#include "../../../C/Lzma2DecMt.h"
-#include "../../Common/MyCom.h"
-
-#include "../ICoder.h"
+#include "../Common/CWrappers.h"
namespace NCompress {
namespace NLzma2 {
@@ -18,69 +16,79 @@ class CDecoder:
public ICompressSetFinishMode,
public ICompressGetInStreamProcessedSize,
public ICompressSetBufSize,
+
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
public ICompressSetOutStreamSize,
public ISequentialInStream,
#endif
- public CMyUnknownImp
-{
- CMyComPtr<ISequentialInStream> _inStream;
- Byte *_inBuf;
- UInt32 _inPos;
- UInt32 _inSize;
- bool _finishMode;
- bool _outSizeDefined;
- UInt64 _outSize;
+ #ifndef _7ZIP_ST
+ public ICompressSetCoderMt,
+ public ICompressSetMemLimit,
+ #endif
- UInt64 _inSizeProcessed;
- UInt64 _outSizeProcessed;
-
+ public CMyUnknownImp
+{
+ CLzma2DecMtHandle _dec;
+ UInt64 _inProcessed;
+ Byte _prop;
+ int _finishMode;
UInt32 _inBufSize;
- UInt32 _inBufSizeNew;
- UInt32 _outStepSize;
+ UInt32 _outStep;
- CLzma2Dec _state;
public:
-
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize)
+
#ifndef NO_READ_FROM_CODER
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
#endif
+
+ #ifndef _7ZIP_ST
+ MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetMemLimit)
+ #endif
+
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
-
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
-
STDMETHOD(SetFinishMode)(UInt32 finishMode);
-
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
-
STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
- STDMETHOD(SetInStream)(ISequentialInStream *inStream);
- STDMETHOD(ReleaseInStream)();
-
- STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+ #ifndef _7ZIP_ST
+private:
+ int _tryMt;
+ UInt32 _numThreads;
+ UInt64 _memUsage;
+public:
+ STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
+ STDMETHOD(SetMemLimit)(UInt64 memUsage);
+ #endif
#ifndef NO_READ_FROM_CODER
+private:
+ CMyComPtr<ISequentialInStream> _inStream;
+ CSeqInStreamWrap _inWrap;
+public:
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream)();
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
#endif
CDecoder();
virtual ~CDecoder();
-
};
}}
diff --git a/CPP/7zip/Compress/Lzma2Encoder.cpp b/CPP/7zip/Compress/Lzma2Encoder.cpp
index 7fea9cc..18f7d02 100644
--- a/CPP/7zip/Compress/Lzma2Encoder.cpp
+++ b/CPP/7zip/Compress/Lzma2Encoder.cpp
@@ -21,18 +21,19 @@ namespace NLzma2 {
CEncoder::CEncoder()
{
- _encoder = 0;
- _encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc);
- if (_encoder == 0)
+ _encoder = NULL;
+ _encoder = Lzma2Enc_Create(&g_AlignedAlloc, &g_BigAlloc);
+ if (!_encoder)
throw 1;
}
CEncoder::~CEncoder()
{
- if (_encoder != 0)
+ if (_encoder)
Lzma2Enc_Destroy(_encoder);
}
+
HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props)
{
switch (propID)
@@ -42,12 +43,7 @@ HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzm
if (prop.vt == VT_UI4)
lzma2Props.blockSize = prop.ulVal;
else if (prop.vt == VT_UI8)
- {
- size_t v = (size_t)prop.uhVal.QuadPart;
- if (v != prop.uhVal.QuadPart)
- return E_INVALIDARG;
- lzma2Props.blockSize = v;
- }
+ lzma2Props.blockSize = prop.uhVal.QuadPart;
else
return E_INVALIDARG;
break;
@@ -60,6 +56,7 @@ HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzm
return S_OK;
}
+
STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
const PROPVARIANT *coderProps, UInt32 numProps)
{
@@ -73,26 +70,52 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props));
}
+
+STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID == NCoderPropID::kExpectedDataSize)
+ if (prop.vt == VT_UI8)
+ Lzma2Enc_SetDataSize(_encoder, prop.uhVal.QuadPart);
+ }
+ return S_OK;
+}
+
+
STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
{
Byte prop = Lzma2Enc_WriteProperties(_encoder);
return WriteStream(outStream, &prop, 1);
}
+
+#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
+
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
- CSeqInStreamWrap inWrap(inStream);
- CSeqOutStreamWrap outWrap(outStream);
- CCompressProgressWrap progressWrap(progress);
-
- SRes res = Lzma2Enc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL);
- if (res == SZ_ERROR_READ && inWrap.Res != S_OK)
- return inWrap.Res;
- if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK)
- return outWrap.Res;
- if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK)
- return progressWrap.Res;
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
+
+ inWrap.Init(inStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
+
+ SRes res = Lzma2Enc_Encode2(_encoder,
+ &outWrap.vt, NULL, NULL,
+ &inWrap.vt, NULL, 0,
+ progress ? &progressWrap.vt : NULL);
+
+ RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
+ RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
+ RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
+
return SResToHRESULT(res);
}
diff --git a/CPP/7zip/Compress/Lzma2Encoder.h b/CPP/7zip/Compress/Lzma2Encoder.h
index 3b3d218..6539e73 100644
--- a/CPP/7zip/Compress/Lzma2Encoder.h
+++ b/CPP/7zip/Compress/Lzma2Encoder.h
@@ -16,16 +16,22 @@ class CEncoder:
public ICompressCoder,
public ICompressSetCoderProperties,
public ICompressWriteCoderProperties,
+ public ICompressSetCoderPropertiesOpt,
public CMyUnknownImp
{
CLzma2EncHandle _encoder;
public:
- MY_UNKNOWN_IMP3(ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties)
+ MY_UNKNOWN_IMP4(
+ ICompressCoder,
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties,
+ ICompressSetCoderPropertiesOpt)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
CEncoder();
virtual ~CEncoder();
diff --git a/CPP/7zip/Compress/LzmaDecoder.cpp b/CPP/7zip/Compress/LzmaDecoder.cpp
index 20e409e..b6a8d3f 100644
--- a/CPP/7zip/Compress/LzmaDecoder.cpp
+++ b/CPP/7zip/Compress/LzmaDecoder.cpp
@@ -24,243 +24,318 @@ static HRESULT SResToHRESULT(SRes res)
namespace NCompress {
namespace NLzma {
-CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false),
- _inBufSize(1 << 20),
- _outBufSize(1 << 22),
+CDecoder::CDecoder():
+ _inBuf(NULL),
+ _lzmaStatus(LZMA_STATUS_NOT_SPECIFIED),
FinishStream(false),
- NeedMoreInput(false)
+ _propsWereSet(false),
+ _outSizeDefined(false),
+ _outStep(1 << 20),
+ _inBufSize(0),
+ _inBufSizeNew(1 << 20)
{
- _inSizeProcessed = 0;
- _inPos = _inSize = 0;
+ _inProcessed = 0;
+ _inPos = _inLim = 0;
+
+ /*
+ AlignOffsetAlloc_CreateVTable(&_alloc);
+ _alloc.numAlignBits = 7;
+ _alloc.offset = 0;
+ */
LzmaDec_Construct(&_state);
}
CDecoder::~CDecoder()
{
- LzmaDec_Free(&_state, &g_Alloc);
+ LzmaDec_Free(&_state, &g_AlignedAlloc); // &_alloc.vt
MyFree(_inBuf);
}
-STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; }
-STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; }
+STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; }
+STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStep = size; return S_OK; }
HRESULT CDecoder::CreateInputBuffer()
{
- if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated)
+ if (!_inBuf || _inBufSizeNew != _inBufSize)
{
MyFree(_inBuf);
- _inBuf = (Byte *)MyAlloc(_inBufSize);
- if (_inBuf == 0)
+ _inBufSize = 0;
+ _inBuf = (Byte *)MyAlloc(_inBufSizeNew);
+ if (!_inBuf)
return E_OUTOFMEMORY;
- _inBufSizeAllocated = _inBufSize;
+ _inBufSize = _inBufSizeNew;
}
return S_OK;
}
+
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
{
- RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_Alloc)));
+ RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_AlignedAlloc))) // &_alloc.vt
_propsWereSet = true;
return CreateInputBuffer();
}
+
void CDecoder::SetOutStreamSizeResume(const UInt64 *outSize)
{
_outSizeDefined = (outSize != NULL);
+ _outSize = 0;
if (_outSizeDefined)
_outSize = *outSize;
- _outSizeProcessed = 0;
- _wrPos = 0;
+ _outProcessed = 0;
+ _lzmaStatus = LZMA_STATUS_NOT_SPECIFIED;
+
LzmaDec_Init(&_state);
}
+
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
- _inSizeProcessed = 0;
- _inPos = _inSize = 0;
- NeedMoreInput = false;
+ _inProcessed = 0;
+ _inPos = _inLim = 0;
SetOutStreamSizeResume(outSize);
return S_OK;
}
+
STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode)
{
FinishStream = (finishMode != 0);
return S_OK;
}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _inProcessed;
+ return S_OK;
+}
+
+
HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
{
- if (_inBuf == 0 || !_propsWereSet)
+ if (!_inBuf || !_propsWereSet)
return S_FALSE;
+
+ const UInt64 startInProgress = _inProcessed;
+ SizeT wrPos = _state.dicPos;
+ HRESULT readRes = S_OK;
- UInt64 startInProgress = _inSizeProcessed;
-
- SizeT next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize);
for (;;)
{
- if (_inPos == _inSize)
+ if (_inPos == _inLim && readRes == S_OK)
{
- _inPos = _inSize = 0;
- RINOK(inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));
+ _inPos = _inLim = 0;
+ readRes = inStream->Read(_inBuf, _inBufSize, &_inLim);
+ }
+
+ const SizeT dicPos = _state.dicPos;
+ SizeT size;
+ {
+ SizeT next = _state.dicBufSize;
+ if (next - wrPos > _outStep)
+ next = wrPos + _outStep;
+ size = next - dicPos;
}
- SizeT dicPos = _state.dicPos;
- SizeT curSize = next - dicPos;
-
ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
if (_outSizeDefined)
{
- const UInt64 rem = _outSize - _outSizeProcessed;
- if (rem <= curSize)
+ const UInt64 rem = _outSize - _outProcessed;
+ if (size >= rem)
{
- curSize = (SizeT)rem;
+ size = (SizeT)rem;
if (FinishStream)
finishMode = LZMA_FINISH_END;
}
}
- SizeT inSizeProcessed = _inSize - _inPos;
+ SizeT inProcessed = _inLim - _inPos;
ELzmaStatus status;
- SRes res = LzmaDec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status);
+
+ SRes res = LzmaDec_DecodeToDic(&_state, dicPos + size, _inBuf + _inPos, &inProcessed, finishMode, &status);
+
+ _lzmaStatus = status;
+ _inPos += (UInt32)inProcessed;
+ _inProcessed += inProcessed;
+ const SizeT outProcessed = _state.dicPos - dicPos;
+ _outProcessed += outProcessed;
- _inPos += (UInt32)inSizeProcessed;
- _inSizeProcessed += inSizeProcessed;
- SizeT outSizeProcessed = _state.dicPos - dicPos;
- _outSizeProcessed += outSizeProcessed;
+ // we check for LZMA_STATUS_NEEDS_MORE_INPUT to allow RangeCoder initialization, if (_outSizeDefined && _outSize == 0)
+ bool outFinished = (_outSizeDefined && _outProcessed >= _outSize);
- bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0);
- bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize);
+ bool needStop = (res != 0
+ || (inProcessed == 0 && outProcessed == 0)
+ || status == LZMA_STATUS_FINISHED_WITH_MARK
+ || (outFinished && status != LZMA_STATUS_NEEDS_MORE_INPUT));
- if (res != 0 || _state.dicPos == next || finished || stopDecoding)
+ if (needStop || outProcessed >= size)
{
- HRESULT res2 = WriteStream(outStream, _state.dic + _wrPos, _state.dicPos - _wrPos);
+ HRESULT res2 = WriteStream(outStream, _state.dic + wrPos, _state.dicPos - wrPos);
- _wrPos = _state.dicPos;
if (_state.dicPos == _state.dicBufSize)
- {
_state.dicPos = 0;
- _wrPos = 0;
- }
- next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize);
-
- if (res != 0)
- return S_FALSE;
+ wrPos = _state.dicPos;
+
RINOK(res2);
- if (stopDecoding)
+
+ if (needStop)
{
- if (status == LZMA_STATUS_NEEDS_MORE_INPUT)
- NeedMoreInput = true;
- if (FinishStream &&
- status != LZMA_STATUS_FINISHED_WITH_MARK &&
- status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
+ if (res != 0)
return S_FALSE;
- return S_OK;
- }
- if (finished)
- {
- if (status == LZMA_STATUS_NEEDS_MORE_INPUT)
- NeedMoreInput = true;
- return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE);
+
+ if (status == LZMA_STATUS_FINISHED_WITH_MARK)
+ {
+ if (FinishStream)
+ if (_outSizeDefined && _outSize != _outProcessed)
+ return S_FALSE;
+ return readRes;
+ }
+
+ if (outFinished && status != LZMA_STATUS_NEEDS_MORE_INPUT)
+ if (!FinishStream || status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
+ return readRes;
+
+ return S_FALSE;
}
}
+
if (progress)
{
- UInt64 inSize = _inSizeProcessed - startInProgress;
- RINOK(progress->SetRatioInfo(&inSize, &_outSizeProcessed));
+ const UInt64 inSize = _inProcessed - startInProgress;
+ RINOK(progress->SetRatioInfo(&inSize, &_outProcessed));
}
}
}
+
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
- const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
- if (_inBuf == 0)
+ if (!_inBuf)
return E_INVALIDARG;
SetOutStreamSize(outSize);
- return CodeSpec(inStream, outStream, progress);
+ HRESULT res = CodeSpec(inStream, outStream, progress);
+ if (res == S_OK)
+ if (FinishStream && inSize && *inSize != _inProcessed)
+ res = S_FALSE;
+ return res;
}
+
#ifndef NO_READ_FROM_CODER
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
+
STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
- do
+
+ ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
+ if (_outSizeDefined)
{
- if (_inPos == _inSize)
+ const UInt64 rem = _outSize - _outProcessed;
+ if (size >= rem)
{
- _inPos = _inSize = 0;
- RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));
+ size = (UInt32)rem;
+ if (FinishStream)
+ finishMode = LZMA_FINISH_END;
}
+ }
+
+ HRESULT readRes = S_OK;
+
+ for (;;)
+ {
+ if (_inPos == _inLim && readRes == S_OK)
{
- SizeT inProcessed = _inSize - _inPos;
+ _inPos = _inLim = 0;
+ readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim);
+ }
- if (_outSizeDefined)
- {
- const UInt64 rem = _outSize - _outSizeProcessed;
- if (rem < size)
- size = (UInt32)rem;
- }
+ SizeT inProcessed = _inLim - _inPos;
+ SizeT outProcessed = size;
+ ELzmaStatus status;
+
+ SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,
+ _inBuf + _inPos, &inProcessed, finishMode, &status);
+
+ _lzmaStatus = status;
+ _inPos += (UInt32)inProcessed;
+ _inProcessed += inProcessed;
+ _outProcessed += outProcessed;
+ size -= (UInt32)outProcessed;
+ data = (Byte *)data + outProcessed;
+ if (processedSize)
+ *processedSize += (UInt32)outProcessed;
+
+ if (res != 0)
+ return S_FALSE;
+
+ /*
+ if (status == LZMA_STATUS_FINISHED_WITH_MARK)
+ return readRes;
- SizeT outProcessed = size;
- ELzmaStatus status;
- SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,
- _inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status);
- _inPos += (UInt32)inProcessed;
- _inSizeProcessed += inProcessed;
- _outSizeProcessed += outProcessed;
- size -= (UInt32)outProcessed;
- data = (Byte *)data + outProcessed;
- if (processedSize)
- *processedSize += (UInt32)outProcessed;
- RINOK(SResToHRESULT(res));
- if (inProcessed == 0 && outProcessed == 0)
- return S_OK;
+ if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT)
+ {
+ if (FinishStream
+ && _outSizeDefined && _outProcessed >= _outSize
+ && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
+ return S_FALSE;
+ return readRes;
}
+ */
+
+ if (inProcessed == 0 && outProcessed == 0)
+ return readRes;
}
- while (size != 0);
- return S_OK;
}
+
HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress)
{
SetOutStreamSizeResume(outSize);
return CodeSpec(_inStream, outStream, progress);
}
+
HRESULT CDecoder::ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize)
{
RINOK(CreateInputBuffer());
+
if (processedSize)
*processedSize = 0;
- while (size > 0)
+
+ HRESULT readRes = S_OK;
+
+ while (size != 0)
{
- if (_inPos == _inSize)
+ if (_inPos == _inLim)
{
- _inPos = _inSize = 0;
- RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize));
- if (_inSize == 0)
+ _inPos = _inLim = 0;
+ if (readRes == S_OK)
+ readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim);
+ if (_inLim == 0)
break;
}
- {
- UInt32 curSize = _inSize - _inPos;
- if (curSize > size)
- curSize = size;
- memcpy(data, _inBuf + _inPos, curSize);
- _inPos += curSize;
- _inSizeProcessed += curSize;
- size -= curSize;
- data = (Byte *)data + curSize;
- if (processedSize)
- *processedSize += curSize;
- }
+
+ UInt32 cur = _inLim - _inPos;
+ if (cur > size)
+ cur = size;
+ memcpy(data, _inBuf + _inPos, cur);
+ _inPos += cur;
+ _inProcessed += cur;
+ size -= cur;
+ data = (Byte *)data + cur;
+ if (processedSize)
+ *processedSize += cur;
}
- return S_OK;
+
+ return readRes;
}
#endif
diff --git a/CPP/7zip/Compress/LzmaDecoder.h b/CPP/7zip/Compress/LzmaDecoder.h
index a4d7206..08b7c1b 100644
--- a/CPP/7zip/Compress/LzmaDecoder.h
+++ b/CPP/7zip/Compress/LzmaDecoder.h
@@ -3,6 +3,7 @@
#ifndef __LZMA_DECODER_H
#define __LZMA_DECODER_H
+// #include "../../../C/Alloc.h"
#include "../../../C/LzmaDec.h"
#include "../../Common/MyCom.h"
@@ -15,6 +16,7 @@ class CDecoder:
public ICompressCoder,
public ICompressSetDecoderProperties2,
public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
public ICompressSetBufSize,
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
@@ -23,21 +25,29 @@ class CDecoder:
#endif
public CMyUnknownImp
{
- CMyComPtr<ISequentialInStream> _inStream;
Byte *_inBuf;
UInt32 _inPos;
- UInt32 _inSize;
- CLzmaDec _state;
+ UInt32 _inLim;
+
+ ELzmaStatus _lzmaStatus;
+
+public:
+ bool FinishStream; // set it before decoding, if you need to decode full LZMA stream
+
+private:
bool _propsWereSet;
bool _outSizeDefined;
UInt64 _outSize;
- UInt64 _inSizeProcessed;
- UInt64 _outSizeProcessed;
+ UInt64 _inProcessed;
+ UInt64 _outProcessed;
- UInt32 _inBufSizeAllocated;
+ UInt32 _outStep;
UInt32 _inBufSize;
- UInt32 _outBufSize;
- SizeT _wrPos;
+ UInt32 _inBufSizeNew;
+
+ // CAlignOffsetAlloc _alloc;
+
+ CLzmaDec _state;
HRESULT CreateInputBuffer();
HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
@@ -47,6 +57,7 @@ public:
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
+ MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize)
#ifndef NO_READ_FROM_CODER
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
@@ -60,11 +71,16 @@ public:
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
STDMETHOD(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size);
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size);
#ifndef NO_READ_FROM_CODER
+
+private:
+ CMyComPtr<ISequentialInStream> _inStream;
+public:
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
@@ -72,18 +88,24 @@ public:
HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
HRESULT ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize);
- UInt64 GetInputProcessedSize() const { return _inSizeProcessed; }
-
+
#endif
- bool FinishStream; // set it before decoding, if you need to decode full LZMA stream
-
- bool NeedMoreInput; // it's set by decoder, if it needs more input data to decode stream
+ UInt64 GetInputProcessedSize() const { return _inProcessed; }
CDecoder();
virtual ~CDecoder();
- UInt64 GetOutputProcessedSize() const { return _outSizeProcessed; }
+ UInt64 GetOutputProcessedSize() const { return _outProcessed; }
+
+ bool NeedsMoreInput() const { return _lzmaStatus == LZMA_STATUS_NEEDS_MORE_INPUT; }
+
+ bool CheckFinishStatus(bool withEndMark) const
+ {
+ return _lzmaStatus == (withEndMark ?
+ LZMA_STATUS_FINISHED_WITH_MARK :
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK);
+ }
};
}}
diff --git a/CPP/7zip/Compress/LzmaEncoder.cpp b/CPP/7zip/Compress/LzmaEncoder.cpp
index 10af8c5..3151c3d 100644
--- a/CPP/7zip/Compress/LzmaEncoder.cpp
+++ b/CPP/7zip/Compress/LzmaEncoder.cpp
@@ -15,7 +15,7 @@ namespace NLzma {
CEncoder::CEncoder()
{
_encoder = NULL;
- _encoder = LzmaEnc_Create(&g_Alloc);
+ _encoder = LzmaEnc_Create(&g_AlignedAlloc);
if (!_encoder)
throw 1;
}
@@ -23,7 +23,7 @@ CEncoder::CEncoder()
CEncoder::~CEncoder()
{
if (_encoder)
- LzmaEnc_Destroy(_encoder, &g_Alloc, &g_BigAlloc);
+ LzmaEnc_Destroy(_encoder, &g_AlignedAlloc, &g_BigAlloc);
}
static inline wchar_t GetUpperChar(wchar_t c)
@@ -74,14 +74,19 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
return E_INVALIDARG;
return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG;
}
+
if (propID > NCoderPropID::kReduceSize)
return S_OK;
+
if (propID == NCoderPropID::kReduceSize)
{
if (prop.vt == VT_UI8)
ep.reduceSize = prop.uhVal.QuadPart;
+ else
+ return E_INVALIDARG;
return S_OK;
}
+
if (prop.vt != VT_UI4)
return E_INVALIDARG;
UInt32 v = prop.ulVal;
@@ -123,6 +128,22 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
return SResToHRESULT(LzmaEnc_SetProps(_encoder, &props));
}
+
+STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID == NCoderPropID::kExpectedDataSize)
+ if (prop.vt == VT_UI8)
+ LzmaEnc_SetDataSize(_encoder, prop.uhVal.QuadPart);
+ }
+ return S_OK;
+}
+
+
STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
{
Byte props[LZMA_PROPS_SIZE];
@@ -131,21 +152,30 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
return WriteStream(outStream, props, size);
}
+
+#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
+
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
- CSeqInStreamWrap inWrap(inStream);
- CSeqOutStreamWrap outWrap(outStream);
- CCompressProgressWrap progressWrap(progress);
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
+
+ inWrap.Init(inStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
+
+ SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt,
+ progress ? &progressWrap.vt : NULL, &g_AlignedAlloc, &g_BigAlloc);
- SRes res = LzmaEnc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL, &g_Alloc, &g_BigAlloc);
_inputProcessed = inWrap.Processed;
- if (res == SZ_ERROR_READ && inWrap.Res != S_OK)
- return inWrap.Res;
- if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK)
- return outWrap.Res;
- if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK)
- return progressWrap.Res;
+
+ RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
+ RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
+ RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
+
return SResToHRESULT(res);
}
diff --git a/CPP/7zip/Compress/LzmaEncoder.h b/CPP/7zip/Compress/LzmaEncoder.h
index 7feafc2..7b31c66 100644
--- a/CPP/7zip/Compress/LzmaEncoder.h
+++ b/CPP/7zip/Compress/LzmaEncoder.h
@@ -16,21 +16,29 @@ class CEncoder:
public ICompressCoder,
public ICompressSetCoderProperties,
public ICompressWriteCoderProperties,
+ public ICompressSetCoderPropertiesOpt,
public CMyUnknownImp
{
CLzmaEncHandle _encoder;
UInt64 _inputProcessed;
public:
- MY_UNKNOWN_IMP3(ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties)
+ MY_UNKNOWN_IMP4(
+ ICompressCoder,
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties,
+ ICompressSetCoderPropertiesOpt)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
CEncoder();
virtual ~CEncoder();
+
UInt64 GetInputProcessedSize() const { return _inputProcessed; }
+ bool IsWriteEndMark() const { return LzmaEnc_IsWriteEndMark(_encoder) != 0; }
};
}}
diff --git a/CPP/7zip/Compress/PpmdDecoder.cpp b/CPP/7zip/Compress/PpmdDecoder.cpp
index f86005b..4820c0a 100644
--- a/CPP/7zip/Compress/PpmdDecoder.cpp
+++ b/CPP/7zip/Compress/PpmdDecoder.cpp
@@ -75,7 +75,7 @@ HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size)
int sym = 0;
for (i = 0; i != size; i++)
{
- sym = Ppmd7_DecodeSymbol(&_ppmd, &_rangeDec.p);
+ sym = Ppmd7_DecodeSymbol(&_ppmd, &_rangeDec.vt);
if (_inStream.Extra || sym < 0)
break;
memStream[i] = (Byte)sym;
@@ -134,6 +134,13 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
return S_OK;
}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _inStream.GetProcessed();
+ return S_OK;
+}
+
#ifndef NO_READ_FROM_CODER
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
diff --git a/CPP/7zip/Compress/PpmdDecoder.h b/CPP/7zip/Compress/PpmdDecoder.h
index c61d1d0..3c2f493 100644
--- a/CPP/7zip/Compress/PpmdDecoder.h
+++ b/CPP/7zip/Compress/PpmdDecoder.h
@@ -18,6 +18,7 @@ namespace NPpmd {
class CDecoder :
public ICompressCoder,
public ICompressSetDecoderProperties2,
+ public ICompressGetInStreamProcessedSize,
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
public ICompressSetOutStreamSize,
@@ -42,19 +43,26 @@ public:
#ifndef NO_READ_FROM_CODER
CMyComPtr<ISequentialInStream> InSeqStream;
- MY_UNKNOWN_IMP4(
- ICompressSetDecoderProperties2,
- ICompressSetInStream,
- ICompressSetOutStreamSize,
- ISequentialInStream)
- #else
- MY_UNKNOWN_IMP1(
- ICompressSetDecoderProperties2)
#endif
+ MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
+ // MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
+ MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
+ #ifndef NO_READ_FROM_CODER
+ MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
+ MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
+ #endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
#ifndef NO_READ_FROM_CODER
@@ -66,7 +74,7 @@ public:
CDecoder(): _outBuf(NULL), _outSizeDefined(false)
{
Ppmd7z_RangeDec_CreateVTable(&_rangeDec);
- _rangeDec.Stream = &_inStream.p;
+ _rangeDec.Stream = &_inStream.vt;
Ppmd7_Construct(&_ppmd);
}
diff --git a/CPP/7zip/Compress/PpmdEncoder.cpp b/CPP/7zip/Compress/PpmdEncoder.cpp
index 49d6508..0aef701 100644
--- a/CPP/7zip/Compress/PpmdEncoder.cpp
+++ b/CPP/7zip/Compress/PpmdEncoder.cpp
@@ -43,7 +43,7 @@ CEncoder::CEncoder():
_inBuf(NULL)
{
_props.Normalize(-1);
- _rangeEnc.Stream = &_outStream.p;
+ _rangeEnc.Stream = &_outStream.vt;
Ppmd7_Construct(&_ppmd);
}
diff --git a/CPP/7zip/Compress/XzDecoder.cpp b/CPP/7zip/Compress/XzDecoder.cpp
new file mode 100644
index 0000000..4fcd09f
--- /dev/null
+++ b/CPP/7zip/Compress/XzDecoder.cpp
@@ -0,0 +1,150 @@
+// XzDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+
+#include "../Common/CWrappers.h"
+
+#include "XzDecoder.h"
+
+namespace NCompress {
+namespace NXz {
+
+#define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes;
+
+#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
+
+static HRESULT SResToHRESULT_Code(SRes res) throw()
+{
+ if (res < 0)
+ return res;
+ switch (res)
+ {
+ case SZ_OK: return S_OK;
+ case SZ_ERROR_MEM: return E_OUTOFMEMORY;
+ case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
+ }
+ return S_FALSE;
+}
+
+
+HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream,
+ const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress)
+{
+ MainDecodeSRes = S_OK;
+ MainDecodeSRes_wasUsed = false;
+ XzStatInfo_Clear(&Stat);
+
+ if (!xz)
+ {
+ xz = XzDecMt_Create(&g_Alloc, &g_MidAlloc);
+ if (!xz)
+ return E_OUTOFMEMORY;
+ }
+
+ CXzDecMtProps props;
+ XzDecMtProps_Init(&props);
+
+ int isMT = False;
+
+ #ifndef _7ZIP_ST
+ {
+ props.numThreads = 1;
+ UInt32 numThreads = _numThreads;
+
+ if (_tryMt && numThreads > 1)
+ {
+ size_t memUsage = (size_t)_memUsage;
+ if (memUsage != _memUsage)
+ memUsage = (size_t)0 - 1;
+ props.memUseMax = memUsage;
+ isMT = (numThreads > 1);
+ }
+
+ props.numThreads = numThreads;
+ }
+ #endif
+
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
+
+ inWrap.Init(seqInStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
+
+ SRes res = XzDecMt_Decode(xz,
+ &props,
+ outSizeLimit, finishStream,
+ &outWrap.vt,
+ &inWrap.vt,
+ &Stat,
+ &isMT,
+ progress ? &progressWrap.vt : NULL);
+
+ MainDecodeSRes = res;
+
+ #ifndef _7ZIP_ST
+ // _tryMt = isMT;
+ #endif
+
+ RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
+ RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
+ RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ)
+
+ // return E_OUTOFMEMORY;
+
+ MainDecodeSRes_wasUsed = true;
+
+ if (res == SZ_OK && finishStream)
+ {
+ /*
+ if (inSize && *inSize != Stat.PhySize)
+ res = SZ_ERROR_DATA;
+ */
+ if (outSizeLimit && *outSizeLimit != outWrap.Processed)
+ res = SZ_ERROR_DATA;
+ }
+
+ return SResToHRESULT_Code(res);
+}
+
+
+HRESULT CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
+{
+ return Decode(inStream, outStream, outSize, _finishStream, progress);
+}
+
+STDMETHODIMP CComDecoder::SetFinishMode(UInt32 finishMode)
+{
+ _finishStream = (finishMode != 0);
+ return S_OK;
+}
+
+STDMETHODIMP CComDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = Stat.InSize;
+ return S_OK;
+}
+
+#ifndef _7ZIP_ST
+
+STDMETHODIMP CComDecoder::SetNumberOfThreads(UInt32 numThreads)
+{
+ _numThreads = numThreads;
+ return S_OK;
+}
+
+STDMETHODIMP CComDecoder::SetMemLimit(UInt64 memUsage)
+{
+ _memUsage = memUsage;
+ return S_OK;
+}
+
+#endif
+
+}}
diff --git a/CPP/7zip/Compress/XzDecoder.h b/CPP/7zip/Compress/XzDecoder.h
new file mode 100644
index 0000000..76694ee
--- /dev/null
+++ b/CPP/7zip/Compress/XzDecoder.h
@@ -0,0 +1,92 @@
+// XzDecoder.h
+
+#ifndef __XZ_DECODER_H
+#define __XZ_DECODER_H
+
+#include "../../../C/Xz.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+namespace NCompress {
+namespace NXz {
+
+struct CDecoder
+{
+ CXzDecMtHandle xz;
+ int _tryMt;
+ UInt32 _numThreads;
+ UInt64 _memUsage;
+
+ SRes MainDecodeSRes; // it's not HRESULT
+ bool MainDecodeSRes_wasUsed;
+ CXzStatInfo Stat;
+
+ CDecoder():
+ xz(NULL),
+ _tryMt(True),
+ _numThreads(1),
+ _memUsage((UInt64)(sizeof(size_t)) << 28),
+ MainDecodeSRes(SZ_OK),
+ MainDecodeSRes_wasUsed(false)
+ {}
+
+ ~CDecoder()
+ {
+ if (xz)
+ XzDecMt_Destroy(xz);
+ }
+
+ /* 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,
+ const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *compressProgress);
+};
+
+
+class CComDecoder:
+ public ICompressCoder,
+ public ICompressSetFinishMode,
+ public ICompressGetInStreamProcessedSize,
+
+ #ifndef _7ZIP_ST
+ public ICompressSetCoderMt,
+ public ICompressSetMemLimit,
+ #endif
+
+ public CMyUnknownImp,
+ public CDecoder
+{
+ bool _finishStream;
+
+public:
+ MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
+
+ MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
+ MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
+
+ #ifndef _7ZIP_ST
+ MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)
+ MY_QUERYINTERFACE_ENTRY(ICompressSetMemLimit)
+ #endif
+
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetFinishMode)(UInt32 finishMode);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+ #ifndef _7ZIP_ST
+ STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
+ STDMETHOD(SetMemLimit)(UInt64 memUsage);
+ #endif
+
+ CComDecoder(): _finishStream(false) {}
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/XzEncoder.cpp b/CPP/7zip/Compress/XzEncoder.cpp
new file mode 100644
index 0000000..458a928
--- /dev/null
+++ b/CPP/7zip/Compress/XzEncoder.cpp
@@ -0,0 +1,245 @@
+// XzEncoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+
+#include "../../Common/MyString.h"
+#include "../../Common/StringToInt.h"
+
+#include "../Common/CWrappers.h"
+#include "../Common/StreamUtils.h"
+
+#include "XzEncoder.h"
+
+namespace NCompress {
+
+namespace NLzma2 {
+
+HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props);
+
+}
+
+namespace NXz {
+
+void CEncoder::InitCoderProps()
+{
+ XzProps_Init(&xzProps);
+}
+
+CEncoder::CEncoder()
+{
+ XzProps_Init(&xzProps);
+ _encoder = NULL;
+ _encoder = XzEnc_Create(&g_Alloc, &g_BigAlloc);
+ if (!_encoder)
+ throw 1;
+}
+
+CEncoder::~CEncoder()
+{
+ if (_encoder)
+ XzEnc_Destroy(_encoder);
+}
+
+
+struct CMethodNamePair
+{
+ UInt32 Id;
+ const char *Name;
+};
+
+static const CMethodNamePair g_NamePairs[] =
+{
+ { XZ_ID_Delta, "Delta" },
+ { XZ_ID_X86, "BCJ" },
+ { XZ_ID_PPC, "PPC" },
+ { XZ_ID_IA64, "IA64" },
+ { XZ_ID_ARM, "ARM" },
+ { XZ_ID_ARMT, "ARMT" },
+ { XZ_ID_SPARC, "SPARC" }
+ // { XZ_ID_LZMA2, "LZMA2" }
+};
+
+static int FilterIdFromName(const wchar_t *name)
+{
+ for (unsigned i = 0; i < ARRAY_SIZE(g_NamePairs); i++)
+ {
+ const CMethodNamePair &pair = g_NamePairs[i];
+ if (StringsAreEqualNoCase_Ascii(name, pair.Name))
+ return (int)pair.Id;
+ }
+ return -1;
+}
+
+
+HRESULT CEncoder::SetCheckSize(UInt32 checkSizeInBytes)
+{
+ unsigned id;
+ switch (checkSizeInBytes)
+ {
+ case 0: id = XZ_CHECK_NO; break;
+ case 4: id = XZ_CHECK_CRC32; break;
+ case 8: id = XZ_CHECK_CRC64; break;
+ case 32: id = XZ_CHECK_SHA256; break;
+ default: return E_INVALIDARG;
+ }
+ xzProps.checkId = id;
+ return S_OK;
+}
+
+
+HRESULT CEncoder::SetCoderProp(PROPID propID, const PROPVARIANT &prop)
+{
+ if (propID == NCoderPropID::kNumThreads)
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ xzProps.numTotalThreads = (int)(prop.ulVal);
+ return S_OK;
+ }
+
+ if (propID == NCoderPropID::kCheckSize)
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ return SetCheckSize(prop.ulVal);
+ }
+
+ if (propID == NCoderPropID::kBlockSize2)
+ {
+ if (prop.vt == VT_UI4)
+ xzProps.blockSize = prop.ulVal;
+ else if (prop.vt == VT_UI8)
+ xzProps.blockSize = prop.uhVal.QuadPart;
+ else
+ return E_INVALIDARG;
+ return S_OK;
+ }
+
+ if (propID == NCoderPropID::kReduceSize)
+ {
+ if (prop.vt == VT_UI8)
+ xzProps.reduceSize = prop.uhVal.QuadPart;
+ else
+ return E_INVALIDARG;
+ return S_OK;
+ }
+
+ if (propID == NCoderPropID::kFilter)
+ {
+ if (prop.vt == VT_UI4)
+ {
+ UInt32 id32 = prop.ulVal;
+ if (id32 == XZ_ID_Delta)
+ return E_INVALIDARG;
+ xzProps.filterProps.id = prop.ulVal;
+ }
+ else
+ {
+ if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
+
+ const wchar_t *name = prop.bstrVal;
+ const wchar_t *end;
+
+ UInt32 id32 = ConvertStringToUInt32(name, &end);
+
+ if (end != name)
+ name = end;
+ else
+ {
+ if (IsString1PrefixedByString2_NoCase_Ascii(name, "Delta"))
+ {
+ name += 5; // strlen("Delta");
+ id32 = XZ_ID_Delta;
+ }
+ else
+ {
+ int filterId = FilterIdFromName(prop.bstrVal);
+ if (filterId < 0 /* || filterId == XZ_ID_LZMA2 */)
+ return E_INVALIDARG;
+ id32 = filterId;
+ }
+ }
+
+ if (id32 == XZ_ID_Delta)
+ {
+ wchar_t c = *name;
+ if (c != '-' && c != ':')
+ return E_INVALIDARG;
+ name++;
+ UInt32 delta = ConvertStringToUInt32(name, &end);
+ if (end == name || *end != 0 || delta == 0 || delta > 256)
+ return E_INVALIDARG;
+ xzProps.filterProps.delta = delta;
+ }
+
+ xzProps.filterProps.id = id32;
+ }
+
+ return S_OK;
+ }
+
+ return NLzma2::SetLzma2Prop(propID, prop, xzProps.lzma2Props);
+}
+
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ XzProps_Init(&xzProps);
+
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ RINOK(SetCoderProp(propIDs[i], coderProps[i]));
+ }
+
+ return S_OK;
+ // return SResToHRESULT(XzEnc_SetProps(_encoder, &xzProps));
+}
+
+
+STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID == NCoderPropID::kExpectedDataSize)
+ if (prop.vt == VT_UI8)
+ XzEnc_SetDataSize(_encoder, prop.uhVal.QuadPart);
+ }
+ return S_OK;
+}
+
+
+#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
+{
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
+
+ inWrap.Init(inStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
+
+ SRes res = XzEnc_SetProps(_encoder, &xzProps);
+ if (res == SZ_OK)
+ res = XzEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, progress ? &progressWrap.vt : NULL);
+
+ // SRes res = Xz_Encode(&outWrap.vt, &inWrap.vt, &xzProps, progress ? &progressWrap.vt : NULL);
+
+ RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
+ RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
+ RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
+
+ return SResToHRESULT(res);
+}
+
+}}
diff --git a/CPP/7zip/Compress/XzEncoder.h b/CPP/7zip/Compress/XzEncoder.h
new file mode 100644
index 0000000..79d81f7
--- /dev/null
+++ b/CPP/7zip/Compress/XzEncoder.h
@@ -0,0 +1,46 @@
+// XzEncoder.h
+
+#ifndef __XZ_ENCODER_H
+#define __XZ_ENCODER_H
+
+#include "../../../C/XzEnc.h"
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+
+namespace NCompress {
+namespace NXz {
+
+
+class CEncoder:
+ public ICompressCoder,
+ public ICompressSetCoderProperties,
+ public ICompressSetCoderPropertiesOpt,
+ public CMyUnknownImp
+{
+ CXzEncHandle _encoder;
+public:
+ CXzProps xzProps;
+
+ MY_UNKNOWN_IMP3(
+ ICompressCoder,
+ ICompressSetCoderProperties,
+ ICompressSetCoderPropertiesOpt)
+
+ void InitCoderProps();
+ HRESULT SetCheckSize(UInt32 checkSizeInBytes);
+ HRESULT SetCoderProp(PROPID propID, const PROPVARIANT &prop);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+ STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+
+ CEncoder();
+ virtual ~CEncoder();
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crc.mak b/CPP/7zip/Crc.mak
index 1da536a..19a7f7b 100644
--- a/CPP/7zip/Crc.mak
+++ b/CPP/7zip/Crc.mak
@@ -1,6 +1,6 @@
C_OBJS = $(C_OBJS) \
$O\7zCrc.obj
-!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM"
+!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM" || "$(CPU)" == "ARM64"
C_OBJS = $(C_OBJS) \
!ELSE
ASM_OBJS = $(ASM_OBJS) \
diff --git a/CPP/7zip/Crc64.mak b/CPP/7zip/Crc64.mak
index 08e56f9..1ac6a0c 100644
--- a/CPP/7zip/Crc64.mak
+++ b/CPP/7zip/Crc64.mak
@@ -1,6 +1,6 @@
C_OBJS = $(C_OBJS) \
$O\XzCrc64.obj
-!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM"
+!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM" || "$(CPU)" == "ARM64"
C_OBJS = $(C_OBJS) \
!ELSE
ASM_OBJS = $(ASM_OBJS) \
diff --git a/CPP/7zip/Crypto/MyAes.h b/CPP/7zip/Crypto/MyAes.h
index 2c10048..8d5ed98 100644
--- a/CPP/7zip/Crypto/MyAes.h
+++ b/CPP/7zip/Crypto/MyAes.h
@@ -30,6 +30,8 @@ class CAesCbcCoder:
public:
CAesCbcCoder(bool encodeMode, unsigned keySize);
+ virtual ~CAesCbcCoder() {}; // we need virtual destructor for derived classes
+
MY_UNKNOWN_IMP3(ICompressFilter, ICryptoProperties, ICompressSetCoderProperties)
INTERFACE_ICompressFilter(;)
diff --git a/CPP/7zip/GuiCommon.rc b/CPP/7zip/GuiCommon.rc
index c11017b..565ee70 100644
--- a/CPP/7zip/GuiCommon.rc
+++ b/CPP/7zip/GuiCommon.rc
@@ -71,6 +71,9 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
DEFPUSHBUTTON "OK", IDOK, bx2, by, bxs, bys \
PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
+#define MY_BUTTON__CLOSE \
+ DEFPUSHBUTTON "&Close", IDCLOSE, bx1, by, bxs, bys
+
#define MY_COMBO CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
#define MY_COMBO_SORTED MY_COMBO | CBS_SORT
diff --git a/CPP/7zip/Guid.txt b/CPP/7zip/Guid.txt
index c746316..e5e0612 100644
--- a/CPP/7zip/Guid.txt
+++ b/CPP/7zip/Guid.txt
@@ -40,6 +40,7 @@
04 ICompressProgressInfo
05 ICompressCoder
18 ICompressCoder2
+ 1F ICompressSetCoderPropertiesOpt
20 ICompressSetCoderProperties
21 ICompressSetDecoderProperties //
22 ICompressSetDecoderProperties2
@@ -47,6 +48,8 @@
24 ICompressGetInStreamProcessedSize
25 ICompressSetCoderMt
26 ICompressSetFinishMode
+ 27 ICompressGetInStreamProcessedSize2
+ 28 ICompressSetMemLimit
30 ICompressGetSubStreamSize
31 ICompressSetInStream
@@ -163,6 +166,7 @@ Handler GUIDs:
0C xz
0D ppmd
+ C6 COFF
C7 Ext
C8 VMDK
C9 VDI
diff --git a/CPP/7zip/ICoder.h b/CPP/7zip/ICoder.h
index 454240d..54b2476 100644
--- a/CPP/7zip/ICoder.h
+++ b/CPP/7zip/ICoder.h
@@ -43,6 +43,7 @@ CODER_INTERFACE(ICompressCoder2, 0x18)
S_OK : OK
S_FALSE : data error (for decoders)
E_OUTOFMEMORY : memory allocation error
+ E_NOTIMPL : unsupported encoding method (for decoders)
another error code : some error. For example, it can be error code received from inStream or outStream function.
Parameters:
@@ -104,25 +105,41 @@ namespace NCoderPropID
enum EEnum
{
kDefaultProp = 0,
- kDictionarySize,
- kUsedMemorySize,
- kOrder,
- kBlockSize,
- kPosStateBits,
- kLitContextBits,
- kLitPosBits,
- kNumFastBytes,
- kMatchFinder,
- kMatchFinderCycles,
- kNumPasses,
- kAlgorithm,
- kNumThreads,
- kEndMarker,
- kLevel,
- kReduceSize // estimated size of data that will be compressed. Encoder can use this value to reduce dictionary size.
+ kDictionarySize, // VT_UI4
+ kUsedMemorySize, // VT_UI4
+ kOrder, // VT_UI4
+ kBlockSize, // VT_UI4 or VT_UI8
+ kPosStateBits, // VT_UI4
+ kLitContextBits, // VT_UI4
+ kLitPosBits, // VT_UI4
+ kNumFastBytes, // VT_UI4
+ kMatchFinder, // VT_BSTR
+ kMatchFinderCycles, // VT_UI4
+ kNumPasses, // VT_UI4
+ kAlgorithm, // VT_UI4
+ kNumThreads, // VT_UI4
+ kEndMarker, // VT_BOOL
+ kLevel, // VT_UI4
+ kReduceSize, // VT_UI8 : it's estimated size of largest data stream that will be compressed
+ // encoder can use this value to reduce dictionary size and allocate data buffers
+
+ kExpectedDataSize, // VT_UI8 : for ICompressSetCoderPropertiesOpt :
+ // it's estimated size of current data stream
+ // real data size can differ from that size
+ // encoder can use this value to optimize encoder initialization
+
+ kBlockSize2, // VT_UI4 or VT_UI8
+ kCheckSize, // VT_UI4 : size of digest in bytes
+ kFilter, // VT_BSTR
+ kMemUse // VT_UI8
};
}
+CODER_INTERFACE(ICompressSetCoderPropertiesOpt, 0x1F)
+{
+ STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) PURE;
+};
+
CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
{
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) PURE;
@@ -170,6 +187,17 @@ CODER_INTERFACE(ICompressSetFinishMode, 0x26)
1 : full decoding. The stream must be finished at the end of decoding. */
};
+CODER_INTERFACE(ICompressGetInStreamProcessedSize2, 0x27)
+{
+ STDMETHOD(GetInStreamProcessedSize2)(UInt32 streamIndex, UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressSetMemLimit, 0x28)
+{
+ STDMETHOD(SetMemLimit)(UInt64 memUsage) PURE;
+};
+
+
CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
{
diff --git a/CPP/7zip/LzmaDec.mak b/CPP/7zip/LzmaDec.mak
new file mode 100644
index 0000000..3c0e7c5
--- /dev/null
+++ b/CPP/7zip/LzmaDec.mak
@@ -0,0 +1,5 @@
+!IF "$(CPU)" == "AMD64"
+CFLAGS_C_SPEC = -D_LZMA_DEC_OPT
+ASM_OBJS = $(ASM_OBJS) \
+ $O\LzmaDecOpt.obj
+!ENDIF
diff --git a/CPP/7zip/UI/Client7z/Client7z.cpp b/CPP/7zip/UI/Client7z/Client7z.cpp
index 5f25f19..9a06cdc 100644
--- a/CPP/7zip/UI/Client7z/Client7z.cpp
+++ b/CPP/7zip/UI/Client7z/Client7z.cpp
@@ -49,21 +49,35 @@ using namespace NDir;
#define kDllName "7z.dll"
-static const char *kCopyrightString = "\n7-Zip " MY_VERSION
-" (" kDllName " client) "
-MY_COPYRIGHT " " MY_DATE "\n";
-
-static const char *kHelpString =
-"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n"
+static const char * const kCopyrightString =
+ "\n"
+ "7-Zip"
+ " (" kDllName " client)"
+ " " MY_VERSION
+ " : " MY_COPYRIGHT_DATE
+ "\n";
+
+static const char * const kHelpString =
+"Usage: 7zcl.exe [a | l | x] archive.7z [fileName ...]\n"
"Examples:\n"
-" Client7z.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n"
-" Client7z.exe l archive.7z : List contents of archive.7z\n"
-" Client7z.exe x archive.7z : eXtract files from archive.7z\n";
+" 7zcl.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n"
+" 7zcl.exe l archive.7z : List contents of archive.7z\n"
+" 7zcl.exe x archive.7z : eXtract files from archive.7z\n";
-static AString FStringToConsoleString(const FString &s)
+static void Convert_UString_to_AString(const UString &s, AString &temp)
{
- return GetOemString(fs2us(s));
+ int codePage = CP_OEMCP;
+ /*
+ int g_CodePage = -1;
+ int codePage = g_CodePage;
+ if (codePage == -1)
+ codePage = CP_OEMCP;
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8(s, temp);
+ else
+ */
+ UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
}
static FString CmdStringToFString(const char *s)
@@ -71,42 +85,54 @@ static FString CmdStringToFString(const char *s)
return us2fs(GetUnicodeString(s));
}
-static void PrintString(const UString &s)
+static void Print(const char *s)
+{
+ fputs(s, stdout);
+}
+
+static void Print(const AString &s)
{
- printf("%s", (LPCSTR)GetOemString(s));
+ Print(s.Ptr());
}
-static void PrintString(const AString &s)
+static void Print(const UString &s)
{
- printf("%s", (LPCSTR)s);
+ AString as;
+ Convert_UString_to_AString(s, as);
+ Print(as);
+}
+
+static void Print(const wchar_t *s)
+{
+ Print(UString(s));
}
static void PrintNewLine()
{
- PrintString("\n");
+ Print("\n");
}
-static void PrintStringLn(const AString &s)
+static void PrintStringLn(const char *s)
{
- PrintString(s);
+ Print(s);
PrintNewLine();
}
-static void PrintError(const char *message, const FString &name)
+static void PrintError(const char *message)
{
- printf("Error: %s", (LPCSTR)message);
+ Print("Error: ");
PrintNewLine();
- PrintString(FStringToConsoleString(name));
+ Print(message);
PrintNewLine();
}
-static void PrintError(const AString &s)
+static void PrintError(const char *message, const FString &name)
{
- PrintNewLine();
- PrintString(s);
- PrintNewLine();
+ PrintError(message);
+ Print(name);
}
+
static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
{
NCOM::CPropVariant prop;
@@ -126,7 +152,7 @@ static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &resu
}
-static const wchar_t *kEmptyFileAlias = L"[Content]";
+static const wchar_t * const kEmptyFileAlias = L"[Content]";
//////////////////////////////////////////////////////////////
@@ -176,21 +202,25 @@ STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)
}
+
+static const char * const kIncorrectCommand = "incorrect command";
+
//////////////////////////////////////////////////////////////
// Archive Extracting callback class
-static const char *kTestingString = "Testing ";
-static const char *kExtractingString = "Extracting ";
-static const char *kSkippingString = "Skipping ";
+static const char * const kTestingString = "Testing ";
+static const char * const kExtractingString = "Extracting ";
+static const char * const kSkippingString = "Skipping ";
+
+static const char * const kUnsupportedMethod = "Unsupported Method";
+static const char * const kCRCFailed = "CRC Failed";
+static const char * const kDataError = "Data Error";
+static const char * const kUnavailableData = "Unavailable data";
+static const char * const kUnexpectedEnd = "Unexpected end of data";
+static const char * const kDataAfterEnd = "There are some data after the end of the payload data";
+static const char * const kIsNotArc = "Is not archive";
+static const char * const kHeadersError = "Headers Error";
-static const char *kUnsupportedMethod = "Unsupported Method";
-static const char *kCRCFailed = "CRC Failed";
-static const char *kDataError = "Data Error";
-static const char *kUnavailableData = "Unavailable data";
-static const char *kUnexpectedEnd = "Unexpected end of data";
-static const char *kDataAfterEnd = "There are some data after the end of the payload data";
-static const char *kIsNotArc = "Is not archive";
-static const char *kHeadersError = "Headers Error";
class CArchiveExtractCallback:
public IArchiveExtractCallback,
@@ -380,11 +410,11 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
};
switch (askExtractMode)
{
- case NArchive::NExtract::NAskMode::kExtract: PrintString(kExtractingString); break;
- case NArchive::NExtract::NAskMode::kTest: PrintString(kTestingString); break;
- case NArchive::NExtract::NAskMode::kSkip: PrintString(kSkippingString); break;
+ case NArchive::NExtract::NAskMode::kExtract: Print(kExtractingString); break;
+ case NArchive::NExtract::NAskMode::kTest: Print(kTestingString); break;
+ case NArchive::NExtract::NAskMode::kSkip: Print(kSkippingString); break;
};
- PrintString(_filePath);
+ Print(_filePath);
return S_OK;
}
@@ -397,7 +427,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
default:
{
NumErrors++;
- PrintString(" : ");
+ Print(" : ");
const char *s = NULL;
switch (operationResult)
{
@@ -428,15 +458,15 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
}
if (s)
{
- PrintString("Error : ");
- PrintString(s);
+ Print("Error : ");
+ Print(s);
}
else
{
char temp[16];
ConvertUInt32ToString(operationResult, temp);
- PrintString("Error #");
- PrintString(temp);
+ Print("Error #");
+ Print(temp);
}
}
}
@@ -449,7 +479,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
}
_outFileStream.Release();
if (_extractMode && _processedFileInfo.AttribDefined)
- SetFileAttrib(_diskFilePath, _processedFileInfo.Attrib);
+ SetFileAttrib_PosixHighDetect(_diskFilePath, _processedFileInfo.Attrib);
PrintNewLine();
return S_OK;
}
@@ -602,10 +632,10 @@ HRESULT CArchiveUpdateCallback::Finilize()
static void GetStream2(const wchar_t *name)
{
- PrintString("Compressing ");
+ Print("Compressing ");
if (name[0] == 0)
name = kEmptyFileAlias;
- PrintString(name);
+ Print(name);
}
STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
@@ -631,7 +661,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream
{
PrintNewLine();
PrintError("WARNING: can't open file");
- // PrintString(NError::MyFormatMessageW(systemError));
+ // Print(NError::MyFormatMessageW(systemError));
return S_FALSE;
}
// return sysError;
@@ -665,7 +695,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOu
while (res.Len() < 2)
res.InsertAtFront(L'0');
UString fileName = VolName;
- fileName += L'.';
+ fileName += '.';
fileName += res;
fileName += VolExt;
COutFileStream *streamSpec = new COutFileStream;
@@ -704,11 +734,18 @@ int MY_CDECL main(int numArgs, const char *args[])
PrintStringLn(kCopyrightString);
- if (numArgs < 3)
+ if (numArgs < 2)
{
PrintStringLn(kHelpString);
+ return 0;
+ }
+
+ if (numArgs < 3)
+ {
+ PrintError(kIncorrectCommand);
return 1;
}
+
NDLL::CLibrary lib;
if (!lib.Load(NDLL::GetModuleDirPrefix() + FTEXT(kDllName)))
@@ -726,10 +763,10 @@ int MY_CDECL main(int numArgs, const char *args[])
char c;
{
- AString command = args[1];
+ AString command (args[1]);
if (command.Len() != 1)
{
- PrintError("incorrect command");
+ PrintError(kIncorrectCommand);
return 1;
}
c = (char)MyCharLower_Ascii(command[0]);
@@ -742,7 +779,7 @@ int MY_CDECL main(int numArgs, const char *args[])
// create archive command
if (numArgs < 4)
{
- PrintStringLn(kHelpString);
+ PrintError(kIncorrectCommand);
return 1;
}
CObjectVector<CDirItem> dirItems;
@@ -839,7 +876,7 @@ int MY_CDECL main(int numArgs, const char *args[])
{
if (numArgs != 3)
{
- PrintStringLn(kHelpString);
+ PrintError(kIncorrectCommand);
return 1;
}
@@ -851,7 +888,7 @@ int MY_CDECL main(int numArgs, const char *args[])
listCommand = false;
else
{
- PrintError("incorrect command");
+ PrintError(kIncorrectCommand);
return 1;
}
@@ -899,17 +936,17 @@ int MY_CDECL main(int numArgs, const char *args[])
archive->GetProperty(i, kpidSize, &prop);
char s[32];
ConvertPropVariantToShortString(prop, s);
- PrintString(s);
- PrintString(" ");
+ Print(s);
+ Print(" ");
}
{
// Get name of file
NCOM::CPropVariant prop;
archive->GetProperty(i, kpidPath, &prop);
if (prop.vt == VT_BSTR)
- PrintString(prop.bstrVal);
+ Print(prop.bstrVal);
else if (prop.vt != VT_EMPTY)
- PrintString("ERROR!");
+ Print("ERROR!");
}
PrintNewLine();
}
@@ -919,10 +956,10 @@ int MY_CDECL main(int numArgs, const char *args[])
// Extract command
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
- extractCallbackSpec->Init(archive, FTEXT("")); // second parameter is output folder path
+ extractCallbackSpec->Init(archive, FString()); // second parameter is output folder path
extractCallbackSpec->PasswordIsDefined = false;
// extractCallbackSpec->PasswordIsDefined = true;
- // extractCallbackSpec->Password = L"1";
+ // extractCallbackSpec->Password = "1";
/*
const wchar_t *names[] =
diff --git a/CPP/7zip/UI/Client7z/Client7z.dsp b/CPP/7zip/UI/Client7z/Client7z.dsp
index 4a4711c..d9ec4ca 100644
--- a/CPP/7zip/UI/Client7z/Client7z.dsp
+++ b/CPP/7zip/UI/Client7z/Client7z.dsp
@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
-# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /MDd /W4 /WX /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
diff --git a/CPP/7zip/UI/Client7z/resource.rc b/CPP/7zip/UI/Client7z/resource.rc
index 0ca293c..701a783 100644
--- a/CPP/7zip/UI/Client7z/resource.rc
+++ b/CPP/7zip/UI/Client7z/resource.rc
@@ -1,3 +1,3 @@
#include "../../MyVersionInfo.rc"
-MY_VERSION_INFO_APP("7-Zip client", "7zcl")
+MY_VERSION_INFO_APP("7-Zip client" , "7zcl")
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
index ad48b5e..f14aafb 100644
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -8,9 +8,17 @@
#ifndef UNDER_CE
#include <io.h>
#endif
+#else
+// for isatty()
+#include <unistd.h>
#endif
+
#include <stdio.h>
+#ifdef _7ZIP_LARGE_PAGES
+#include "../../../../C/Alloc.h"
+#endif
+
#include "../../../Common/ListFileUtils.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
@@ -19,16 +27,19 @@
#include "../../../Windows/FileName.h"
#ifdef _WIN32
#include "../../../Windows/FileMapping.h"
+#include "../../../Windows/MemoryLock.h"
#include "../../../Windows/Synchronization.h"
#endif
#include "ArchiveCommandLine.h"
#include "EnumDirItems.h"
-#include "SortUtils.h"
#include "Update.h"
#include "UpdateAction.h"
extern bool g_CaseSensitive;
+extern bool g_PathTrailReplaceMode;
+
+bool g_LargePagesMode = false;
#ifdef UNDER_CE
@@ -59,15 +70,6 @@ static bool StringToUInt32(const wchar_t *s, UInt32 &v)
return *end == 0;
}
-CArcCmdLineException::CArcCmdLineException(const char *a, const wchar_t *u)
-{
- (*this) += MultiByteToUnicodeString(a);
- if (u)
- {
- this->Add_LF();
- (*this) += u;
- }
-}
int g_CodePage = -1;
@@ -123,6 +125,7 @@ enum Enum
kTechMode,
kShareForWrite,
+ kStopAfterOpenError,
kCaseSensitive,
kArcNameMode,
@@ -133,10 +136,13 @@ enum Enum
kHardLinks,
kSymLinks,
kNtSecurity,
+
kAltStreams,
kReplaceColonForAltStream,
kWriteToAltStreamIfColon,
+ kNameTrailReplace,
+
kDeleteAfterCompressing,
kSetArcMTime
@@ -149,11 +155,11 @@ enum Enum
static const wchar_t kRecursedIDChar = 'r';
-static const char *kRecursedPostCharSet = "0-";
+static const char * const kRecursedPostCharSet = "0-";
-static const char *k_ArcNameMode_PostCharSet = "sea";
+static const char * const k_ArcNameMode_PostCharSet = "sea";
-static const char *k_Stream_PostCharSet = "012";
+static const char * const k_Stream_PostCharSet = "012";
static inline const EArcNameMode ParseArcNameMode(int postCharIndex)
{
@@ -180,7 +186,7 @@ static const char kFileListID = '@';
static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
-static const char *kOverwritePostCharSet = "asut";
+static const char * const kOverwritePostCharSet = "asut";
static const NExtract::NOverwriteMode::EEnum k_OverwriteModes[] =
{
@@ -235,12 +241,13 @@ static const CSwitchForm kSwitchForms[] =
{ "si", NSwitchType::kString },
{ "so" },
- { "slp", NSwitchType::kMinus },
+ { "slp", NSwitchType::kString },
{ "scs", NSwitchType::kString },
{ "scc", NSwitchType::kString },
{ "slt" },
{ "ssw" },
+ { "sse" },
{ "ssc", NSwitchType::kMinus },
{ "sa", NSwitchType::kChar, false, 1, k_ArcNameMode_PostCharSet },
@@ -251,10 +258,13 @@ static const CSwitchForm kSwitchForms[] =
{ "snh", NSwitchType::kMinus },
{ "snl", NSwitchType::kMinus },
{ "sni" },
+
{ "sns", NSwitchType::kMinus },
{ "snr" },
{ "snc" },
+ { "snt", NSwitchType::kMinus },
+
{ "sdel" },
{ "stl" }
@@ -263,17 +273,16 @@ static const CSwitchForm kSwitchForms[] =
#endif
};
-static const wchar_t *kUniversalWildcard = L"*";
+static const char * const kUniversalWildcard = "*";
static const unsigned kMinNonSwitchWords = 1;
static const unsigned kCommandIndex = 0;
-// static const char *kUserErrorMessage = "Incorrect command line";
-static const char *kCannotFindListFile = "Cannot find listfile";
-static const char *kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch.";
-static const char *kTerminalOutError = "I won't write compressed data to a terminal";
-static const char *kSameTerminalError = "I won't write data and program's messages to same stream";
-static const char *kEmptyFilePath = "Empty file path";
-static const char *kCannotFindArchive = "Cannot find archive";
+// static const char * const kUserErrorMessage = "Incorrect command line";
+static const char * const kCannotFindListFile = "Cannot find listfile";
+static const char * const kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch.";
+static const char * const kTerminalOutError = "I won't write compressed data to a terminal";
+static const char * const kSameTerminalError = "I won't write data and program's messages to same stream";
+static const char * const kEmptyFilePath = "Empty file path";
bool CArcCommand::IsFromExtractGroup() const
{
@@ -328,7 +337,7 @@ static const char *g_Commands = "audtexlbih";
static bool ParseArchiveCommand(const UString &commandString, CArcCommand &command)
{
- UString s = commandString;
+ UString s (commandString);
s.MakeLower_Ascii();
if (s.Len() == 1)
{
@@ -386,9 +395,9 @@ static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs,
val += pair.NewName;
val.Add_LF();
if (type == NRecursedType::kRecursed)
- val.AddAscii("-r");
+ val += "-r";
else if (type == NRecursedType::kWildcardOnlyRecursed)
- val.AddAscii("-r0");
+ val += "-r0";
throw CArcCmdLineException("Unsupported rename command:", val);
}
}
@@ -422,23 +431,28 @@ static void AddToCensorFromNonSwitchesStrings(
CObjectVector<CRenamePair> *renamePairs,
unsigned startIndex,
NWildcard::CCensor &censor,
- const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,
+ const UStringVector &nonSwitchStrings,
+ int stopSwitchIndex,
+ NRecursedType::EEnum type,
bool wildcardMatching,
bool thereAreSwitchIncludes, Int32 codePage)
{
if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes)
- AddNameToCensor(censor, kUniversalWildcard, true, type,
+ AddNameToCensor(censor, UString(kUniversalWildcard), true, type,
true // wildcardMatching
);
int oldIndex = -1;
+ if (stopSwitchIndex < 0)
+ stopSwitchIndex = nonSwitchStrings.Size();
+
for (unsigned i = startIndex; i < nonSwitchStrings.Size(); i++)
{
const UString &s = nonSwitchStrings[i];
if (s.IsEmpty())
throw CArcCmdLineException(kEmptyFilePath);
- if (s[0] == kFileListID)
+ if (i < (unsigned)stopSwitchIndex && s[0] == kFileListID)
AddToCensorFromListFile(renamePairs, censor, s.Ptr(1), true, type, wildcardMatching, codePage);
else if (renamePairs)
{
@@ -477,7 +491,7 @@ struct CEventSetEnd
}
};
-const char *k_IncorrectMapCommand = "Incorrect Map command";
+static const char * const k_IncorrectMapCommand = "Incorrect Map command";
static const char *ParseMapWithPaths(
NWildcard::CCensor &censor,
@@ -485,7 +499,7 @@ static const char *ParseMapWithPaths(
NRecursedType::EEnum commonRecursedType,
bool wildcardMatching)
{
- UString s = s2;
+ UString s (s2);
int pos = s.Find(L':');
if (pos < 0)
return k_IncorrectMapCommand;
@@ -577,7 +591,7 @@ static void AddSwitchWildcardsToCensor(
break;
}
- UString tail = name.Ptr(pos + 1);
+ const UString tail = name.Ptr(pos + 1);
if (name[pos] == kImmediateNameID)
AddNameToCensor(censor, tail, include, recursedType, wildcardMatching);
@@ -601,84 +615,6 @@ static void AddSwitchWildcardsToCensor(
throw CArcCmdLineException(errorMessage, strings[i]);
}
-#ifdef _WIN32
-
-// This code converts all short file names to long file names.
-
-static void ConvertToLongName(const UString &prefix, UString &name)
-{
- if (name.IsEmpty() || DoesNameContainWildcard(name))
- return;
- NFind::CFileInfo fi;
- const FString path = us2fs(prefix + name);
- #ifndef UNDER_CE
- if (NFile::NName::IsDevicePath(path))
- return;
- #endif
- if (fi.Find(path))
- name = fs2us(fi.Name);
-}
-
-static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
-{
- FOR_VECTOR (i, items)
- {
- NWildcard::CItem &item = items[i];
- if (item.Recursive || item.PathParts.Size() != 1)
- continue;
- if (prefix.IsEmpty() && item.IsDriveItem())
- continue;
- ConvertToLongName(prefix, item.PathParts.Front());
- }
-}
-
-static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)
-{
- ConvertToLongNames(prefix, node.IncludeItems);
- ConvertToLongNames(prefix, node.ExcludeItems);
- unsigned i;
- for (i = 0; i < node.SubNodes.Size(); i++)
- {
- UString &name = node.SubNodes[i].Name;
- if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name))
- continue;
- ConvertToLongName(prefix, name);
- }
- // mix folders with same name
- for (i = 0; i < node.SubNodes.Size(); i++)
- {
- NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
- for (unsigned j = i + 1; j < node.SubNodes.Size();)
- {
- const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
- if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name))
- {
- nextNode1.IncludeItems += nextNode2.IncludeItems;
- nextNode1.ExcludeItems += nextNode2.ExcludeItems;
- node.SubNodes.Delete(j);
- }
- else
- j++;
- }
- }
- for (i = 0; i < node.SubNodes.Size(); i++)
- {
- NWildcard::CCensorNode &nextNode = node.SubNodes[i];
- ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode);
- }
-}
-
-void ConvertToLongNames(NWildcard::CCensor &censor)
-{
- FOR_VECTOR (i, censor.Pairs)
- {
- NWildcard::CPair &pair = censor.Pairs[i];
- ConvertToLongNames(pair.Prefix, pair.Head);
- }
-}
-
-#endif
-
/*
static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
{
@@ -693,11 +629,11 @@ static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
}
*/
-static const wchar_t *kUpdatePairStateIDSet = L"pqrxyzw";
+static const char * const kUpdatePairStateIDSet = "pqrxyzw";
static const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
static const unsigned kNumUpdatePairActions = 4;
-static const char *kUpdateIgnoreItselfPostStringID = "-";
+static const char * const kUpdateIgnoreItselfPostStringID = "-";
static const wchar_t kUpdateNewArchivePostCharID = '!';
@@ -707,8 +643,8 @@ static bool ParseUpdateCommandString2(const UString &command,
for (unsigned i = 0; i < command.Len();)
{
wchar_t c = MyCharLower_Ascii(command[i]);
- int statePos = FindCharPosInString(kUpdatePairStateIDSet, c);
- if (statePos < 0)
+ int statePos = FindCharPosInString(kUpdatePairStateIDSet, (char)c);
+ if (c > 0x7F || statePos < 0)
{
postString = command.Ptr(i);
return true;
@@ -849,7 +785,6 @@ static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &pr
}
}
-CArcCmdLineParser::CArcCmdLineParser(): parser(ARRAY_SIZE(kSwitchForms)) {}
static inline void SetStreamMode(const CSwitchResult &sw, unsigned &res)
{
@@ -857,10 +792,11 @@ static inline void SetStreamMode(const CSwitchResult &sw, unsigned &res)
res = sw.PostCharIndex;
}
+
void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
CArcCmdLineOptions &options)
{
- if (!parser.ParseStrings(kSwitchForms, commandStrings))
+ if (!parser.ParseStrings(kSwitchForms, ARRAY_SIZE(kSwitchForms), commandStrings))
throw CArcCmdLineException(parser.ErrorMessage, parser.ErrorLine);
options.IsInTerminal = MY_IS_TERMINAL(stdin);
@@ -908,9 +844,45 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
options.CaseSensitive = g_CaseSensitive;
}
- options.LargePages = false;
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ NSecurity::EnablePrivilege_SymLink();
+ #endif
+
+ // options.LargePages = false;
+
if (parser[NKey::kLargePages].ThereIs)
- options.LargePages = !parser[NKey::kLargePages].WithMinus;
+ {
+ unsigned slp = 0;
+ const UString &s = parser[NKey::kLargePages].PostStrings[0];
+ if (s.IsEmpty())
+ slp = 1;
+ else if (s != L"-")
+ {
+ if (!StringToUInt32(s, slp))
+ throw CArcCmdLineException("Unsupported switch postfix for -slp", s);
+ }
+
+ #ifdef _7ZIP_LARGE_PAGES
+ if (slp >
+ #ifndef UNDER_CE
+ (unsigned)NSecurity::Get_LargePages_RiskLevel()
+ #else
+ 0
+ #endif
+ )
+ {
+ SetLargePageSize();
+ // note: this process also can inherit that Privilege from parent process
+ g_LargePagesMode =
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ NSecurity::EnablePrivilege_LockMemory();
+ #else
+ true;
+ #endif
+ }
+ #endif
+ }
#ifndef UNDER_CE
@@ -965,7 +937,7 @@ static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned key
if (!parser[keyIndex].ThereIs)
return defaultVal;
- UString name = parser[keyIndex].PostStrings.Back();
+ UString name (parser[keyIndex].PostStrings.Back());
UInt32 v;
if (StringToUInt32(name, v))
if (v < ((UInt32)1 << 16))
@@ -982,64 +954,6 @@ static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned key
}
}
-HRESULT EnumerateDirItemsAndSort(
- NWildcard::CCensor &censor,
- NWildcard::ECensorPathMode censorPathMode,
- const UString &addPathPrefix,
- UStringVector &sortedPaths,
- UStringVector &sortedFullPaths,
- CDirItemsStat &st,
- IDirItemsCallback *callback)
-{
- FStringVector paths;
-
- {
- CDirItems dirItems;
- dirItems.Callback = callback;
- {
- HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems);
- st = dirItems.Stat;
- RINOK(res);
- }
-
- FOR_VECTOR (i, dirItems.Items)
- {
- const CDirItem &dirItem = dirItems.Items[i];
- if (!dirItem.IsDir())
- paths.Add(dirItems.GetPhyPath(i));
- }
- }
-
- if (paths.Size() == 0)
- throw CArcCmdLineException(kCannotFindArchive);
-
- UStringVector fullPaths;
-
- unsigned i;
-
- for (i = 0; i < paths.Size(); i++)
- {
- FString fullPath;
- NFile::NDir::MyGetFullPathName(paths[i], fullPath);
- fullPaths.Add(fs2us(fullPath));
- }
-
- CUIntVector indices;
- SortFileNames(fullPaths, indices);
- sortedPaths.ClearAndReserve(indices.Size());
- sortedFullPaths.ClearAndReserve(indices.Size());
-
- for (i = 0; i < indices.Size(); i++)
- {
- unsigned index = indices[i];
- sortedPaths.AddInReserved(fs2us(paths[index]));
- sortedFullPaths.AddInReserved(fullPaths[index]);
- if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0)
- throw CArcCmdLineException("Duplicate archive path:", sortedFullPaths[i]);
- }
-
- return S_OK;
-}
static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp)
{
@@ -1051,7 +965,7 @@ static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID,
void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
{
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
- unsigned numNonSwitchStrings = nonSwitchStrings.Size();
+ const unsigned numNonSwitchStrings = nonSwitchStrings.Size();
if (numNonSwitchStrings < kMinNonSwitchWords)
throw CArcCmdLineException("The command must be specified");
@@ -1082,6 +996,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
}
}
+ if (parser[NKey::kNameTrailReplace].ThereIs)
+ g_PathTrailReplaceMode = !parser[NKey::kNameTrailReplace].WithMinus;
+
NRecursedType::EEnum recursedType;
if (parser[NKey::kRecursed].ThereIs)
recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
@@ -1138,7 +1055,8 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
AddToCensorFromNonSwitchesStrings(isRename ? &options.UpdateOptions.RenamePairs : NULL,
curCommandIndex, options.Censor,
- nonSwitchStrings, recursedType, wildcardMatching,
+ nonSwitchStrings, parser.StopSwitchIndex,
+ recursedType, wildcardMatching,
thereAreSwitchIncludes, codePage);
options.YesToAll = parser[NKey::kYes].ThereIs;
@@ -1283,6 +1201,8 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
if (parser[NKey::kShareForWrite].ThereIs)
updateOptions.OpenShareForWrite = true;
+ if (parser[NKey::kStopAfterOpenError].ThereIs)
+ updateOptions.StopAfterOpenError = true;
updateOptions.PathMode = censorPathMode;
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h
index a91df0c..bba3c98 100644
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.h
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h
@@ -6,14 +6,13 @@
#include "../../../Common/CommandLineParser.h"
#include "../../../Common/Wildcard.h"
+#include "EnumDirItems.h"
+
#include "Extract.h"
#include "HashCalc.h"
#include "Update.h"
-struct CArcCmdLineException: public UString
-{
- CArcCmdLineException(const char *a, const wchar_t *u = NULL);
-};
+typedef CMessagePathException CArcCmdLineException;
namespace NCommandType { enum EEnum
{
@@ -51,7 +50,7 @@ struct CArcCmdLineOptions
{
bool HelpMode;
- bool LargePages;
+ // bool LargePages;
bool CaseSensitiveChange;
bool CaseSensitive;
@@ -110,7 +109,7 @@ struct CArcCmdLineOptions
UInt32 NumIterations;
CArcCmdLineOptions():
- LargePages(false),
+ // LargePages(false),
CaseSensitiveChange(false),
CaseSensitive(false),
@@ -130,18 +129,8 @@ class CArcCmdLineParser
{
NCommandLineParser::CParser parser;
public:
- CArcCmdLineParser();
void Parse1(const UStringVector &commandStrings, CArcCmdLineOptions &options);
void Parse2(CArcCmdLineOptions &options);
};
-HRESULT EnumerateDirItemsAndSort(
- NWildcard::CCensor &censor,
- NWildcard::ECensorPathMode pathMode,
- const UString &addPathPrefix,
- UStringVector &sortedPaths,
- UStringVector &sortedFullPaths,
- CDirItemsStat &st,
- IDirItemsCallback *callback);
-
#endif
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
index 39e9653..1119d1b 100644
--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
@@ -5,7 +5,12 @@
#undef sprintf
#undef printf
+// #include <stdio.h>
+// #include "../../../../C/CpuTicks.h"
+
#include "../../../../C/Alloc.h"
+#include "../../../../C/CpuArch.h"
+
#include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h"
@@ -36,10 +41,14 @@ using namespace NWindows;
using namespace NFile;
using namespace NDir;
-static const char *kCantAutoRename = "Can not create file with auto name";
-static const char *kCantRenameFile = "Can not rename existing file";
-static const char *kCantDeleteOutputFile = "Can not delete output file";
-static const char *kCantDeleteOutputDir = "Can not delete output folder";
+static const char * const kCantAutoRename = "Can not create file with auto name";
+static const char * const kCantRenameFile = "Can not rename existing file";
+static const char * const kCantDeleteOutputFile = "Can not delete output file";
+static const char * const kCantDeleteOutputDir = "Can not delete output folder";
+static const char * const kCantCreateHardLink = "Can not create hard link";
+static const char * const kCantCreateSymLink = "Can not create symbolic link";
+static const char * const kCantOpenOutFile = "Can not open output file";
+static const char * const kCantSetFileLen = "Can not set length for output file";
#ifndef _SFX
@@ -173,6 +182,7 @@ HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *r
#endif
CArchiveExtractCallback::CArchiveExtractCallback():
+ _arc(NULL),
WriteCTime(true),
WriteATime(true),
WriteMTime(true),
@@ -196,8 +206,8 @@ void CArchiveExtractCallback::Init(
const UStringVector &removePathParts, bool removePartsForAltStreams,
UInt64 packSize)
{
- _extractedFolderPaths.Clear();
- _extractedFolderIndices.Clear();
+ ClearExtractedDirsInfo();
+ _outFileStream.Release();
#ifdef SUPPORT_LINKS
_hardLinks.Clear();
@@ -359,9 +369,11 @@ void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPat
}
}
-HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)
+HRESULT CArchiveExtractCallback::GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)
{
filetimeIsDefined = false;
+ filetime.dwLowDateTime = 0;
+ filetime.dwHighDateTime = 0;
NCOM::CPropVariant prop;
RINOK(_arc->Archive->GetProperty(index, propID, &prop));
if (prop.vt == VT_FILETIME)
@@ -381,14 +393,13 @@ HRESULT CArchiveExtractCallback::GetUnpackSize()
static void AddPathToMessage(UString &s, const FString &path)
{
- s.AddAscii(" : ");
+ s += " : ";
s += fs2us(path);
}
HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FString &path)
{
- UString s;
- s.AddAscii(message);
+ UString s (message);
AddPathToMessage(s, path);
return _extractCallback2->MessageError(s);
}
@@ -396,11 +407,10 @@ HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FSt
HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path)
{
DWORD errorCode = GetLastError();
- UString s;
- s.AddAscii(message);
+ UString s (message);
if (errorCode != 0)
{
- s.AddAscii(" : ");
+ s += " : ";
s += NError::MyFormatMessage(errorCode);
}
AddPathToMessage(s, path);
@@ -409,8 +419,7 @@ HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *mes
HRESULT CArchiveExtractCallback::SendMessageError2(const char *message, const FString &path1, const FString &path2)
{
- UString s;
- s.AddAscii(message);
+ UString s (message);
AddPathToMessage(s, path1);
AddPathToMessage(s, path2);
return _extractCallback2->MessageError(s);
@@ -440,7 +449,7 @@ STDMETHODIMP CGetProp::GetProp(PROPID propID, PROPVARIANT *value)
static UString GetDirPrefixOf(const UString &src)
{
- UString s = src;
+ UString s (src);
if (!s.IsEmpty())
{
if (IsPathSepar(s.Back()))
@@ -514,7 +523,7 @@ bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcIte
if (pathParts2.IsEmpty())
pathParts2.AddNew();
UString &back = pathParts2.Back();
- back += L':';
+ back += ':';
back += item.AltStreamName;
bool include2;
@@ -541,7 +550,7 @@ bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem
static FString MakePath_from_2_Parts(const FString &prefix, const FString &path)
{
- FString s = prefix;
+ FString s (prefix);
#if defined(_WIN32) && !defined(UNDER_CE)
if (!path.IsEmpty() && path[0] == ':' && !prefix.IsEmpty() && IsPathSepar(prefix.Back()))
{
@@ -596,6 +605,7 @@ HRESULT CArchiveExtractCallback::MyCopyFile(ISequentialOutStream *outStream)
#endif
*/
+
STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
{
COM_TRY_BEGIN
@@ -616,6 +626,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
_curSize = 0;
_curSizeDefined = false;
+ _fileLengthWasSet = false;
_index = index;
_diskFilePath.Empty();
@@ -726,7 +737,8 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
return E_FAIL;
UString s;
CReparseAttr reparse;
- isOkReparse = reparse.Parse((const Byte *)data, dataSize);
+ DWORD errorCode = 0;
+ isOkReparse = reparse.Parse((const Byte *)data, dataSize, errorCode);
if (isOkReparse)
{
isHardLink = false;
@@ -928,13 +940,13 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
}
GetProp_Spec->Arc = _arc;
GetProp_Spec->IndexInArc = index;
- UString name = MakePathFromParts(pathParts);
+ UString name (MakePathFromParts(pathParts));
#ifdef SUPPORT_ALT_STREAMS
if (_item.IsAltStream)
{
if (!pathParts.IsEmpty() || (!_removePartsForAltStreams && _pathMode != NExtract::NPathMode::kNoPathsAlt))
- name += L':';
+ name += ':';
name += _item.AltStreamName;
}
#endif
@@ -980,13 +992,13 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
|| !pathParts.IsEmpty()
|| !(_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt))
#endif
- Correct_FsPath(_pathMode == NExtract::NPathMode::kAbsPaths, pathParts, _item.MainIsDir);
+ Correct_FsPath(_pathMode == NExtract::NPathMode::kAbsPaths, _keepAndReplaceEmptyDirPrefixes, pathParts, _item.MainIsDir);
#ifdef SUPPORT_ALT_STREAMS
if (_item.IsAltStream)
{
- UString s = _item.AltStreamName;
+ UString s (_item.AltStreamName);
Correct_AltStream_Name(s);
bool needColon = true;
@@ -1002,13 +1014,13 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
UString &name = pathParts.Back();
if (needColon)
- name += (wchar_t)(_ntOptions.ReplaceColonForAltStream ? L'_' : L':');
+ name += (char)(_ntOptions.ReplaceColonForAltStream ? '_' : ':');
name += s;
}
#endif
- UString processedPath = MakePathFromParts(pathParts);
+ UString processedPath (MakePathFromParts(pathParts));
if (!isAnti)
{
@@ -1022,20 +1034,42 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
{
FString fullPathNew;
CreateComplexDirectory(pathParts, fullPathNew);
+
if (_item.IsDir)
{
- _extractedFolderPaths.Add(fullPathNew);
- _extractedFolderIndices.Add(index);
- SetDirTime(fullPathNew,
- (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
- (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
- (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
+ CDirPathTime &pt = _extractedFolders.AddNew();
+
+ pt.CTime = _fi.CTime;
+ pt.CTimeDefined = (WriteCTime && _fi.CTimeDefined);
+
+ pt.ATime = _fi.ATime;
+ pt.ATimeDefined = (WriteATime && _fi.ATimeDefined);
+
+ pt.MTimeDefined = false;
+
+ if (WriteMTime)
+ {
+ if (_fi.MTimeDefined)
+ {
+ pt.MTime = _fi.MTime;
+ pt.MTimeDefined = true;
+ }
+ else if (_arc->MTimeDefined)
+ {
+ pt.MTime = _arc->MTime;
+ pt.MTimeDefined = true;
+ }
+ }
+
+ pt.Path = fullPathNew;
+
+ pt.SetDirTime();
}
}
}
- FString fullProcessedPath = us2fs(processedPath);
+ FString fullProcessedPath (us2fs(processedPath));
if (_pathMode != NExtract::NPathMode::kAbsPaths
|| !NName::IsAbsolutePath(processedPath))
{
@@ -1051,8 +1085,8 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
{
const CIndexToPathPair &pair = _renamedFiles[renIndex];
fullProcessedPath = pair.Path;
- fullProcessedPath += (FChar)':';
- UString s = _item.AltStreamName;
+ fullProcessedPath += ':';
+ UString s (_item.AltStreamName);
Correct_AltStream_Name(s);
fullProcessedPath += us2fs(s);
}
@@ -1086,7 +1120,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
case NExtract::NOverwriteMode::kAsk:
{
int slashPos = fullProcessedPath.ReverseFind_PathSepar();
- FString realFullProcessedPath = fullProcessedPath.Left(slashPos + 1) + fileInfo.Name;
+ FString realFullProcessedPath (fullProcessedPath.Left(slashPos + 1) + fileInfo.Name);
Int32 overwriteResult;
RINOK(_extractCallback2->AskOverwrite(
@@ -1119,7 +1153,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
}
else if (_overwriteMode == NExtract::NOverwriteMode::kRenameExisting)
{
- FString existPath = fullProcessedPath;
+ FString existPath (fullProcessedPath);
if (!AutoRenamePath(existPath))
{
RINOK(SendMessageError(kCantAutoRename, fullProcessedPath));
@@ -1165,7 +1199,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
int colonPos = NName::FindAltStreamColon(fullProcessedPath);
if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0)
{
- FString parentFsPath = fullProcessedPath;
+ FString parentFsPath (fullProcessedPath);
parentFsPath.DeleteFrom(colonPos);
NFind::CFileInfo parentFi;
if (parentFi.Find(parentFsPath))
@@ -1222,7 +1256,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
{
if (!MyCreateHardLink(fullProcessedPath, existPath))
{
- RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, existPath));
+ RINOK(SendMessageError2(kCantCreateHardLink, fullProcessedPath, existPath));
// return S_OK;
}
}
@@ -1262,7 +1296,8 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
if (FillLinkData(data, fs2us(existPath), !isJunction))
{
CReparseAttr attr;
- if (!attr.Parse(data, data.Size()))
+ DWORD errorCode = 0;
+ if (!attr.Parse(data, data.Size(), errorCode))
{
RINOK(SendMessageError("Internal error for symbolic link file", us2fs(_item.Path)));
// return E_FAIL;
@@ -1270,7 +1305,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
else
if (!NFile::NIO::SetReparseData(fullProcessedPath, _item.IsDir, data, (DWORD)data.Size()))
{
- RINOK(SendMessageError_with_LastError("Can not create symbolic link", fullProcessedPath));
+ RINOK(SendMessageError_with_LastError(kCantCreateSymLink, fullProcessedPath));
}
}
}
@@ -1304,7 +1339,7 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
{
if (!MyCreateHardLink(fullProcessedPath, hl))
{
- RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, hl));
+ RINOK(SendMessageError2(kCantCreateHardLink, fullProcessedPath, hl));
return S_OK;
}
needWriteFile = false;
@@ -1323,11 +1358,24 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
{
// if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
{
- RINOK(SendMessageError_with_LastError("Can not open output file", fullProcessedPath));
+ RINOK(SendMessageError_with_LastError(kCantOpenOutFile, fullProcessedPath));
return S_OK;
}
}
+ if (_ntOptions.PreAllocateOutFile && !_isSplit && _curSizeDefined && _curSize > (1 << 12))
+ {
+ // UInt64 ticks = GetCpuTicks();
+ bool res = _outFileStreamSpec->File.SetLength(_curSize);
+ _fileLengthWasSet = res;
+ _outFileStreamSpec->File.SeekToBegin();
+ // ticks = GetCpuTicks() - ticks;
+ // printf("\nticks = %10d\n", (unsigned)ticks);
+ if (!res)
+ {
+ RINOK(SendMessageError_with_LastError(kCantSetFileLen, fullProcessedPath));
+ }
+ }
#ifdef SUPPORT_ALT_STREAMS
if (isRenamed && !_item.IsAltStream)
@@ -1426,6 +1474,33 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
}
+HRESULT CArchiveExtractCallback::CloseFile()
+{
+ if (!_outFileStream)
+ return S_OK;
+
+ HRESULT hres = S_OK;
+ _outFileStreamSpec->SetTime(
+ (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
+ (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
+ (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
+
+ const UInt64 processedSize = _outFileStreamSpec->ProcessedSize;
+ if (_fileLengthWasSet && _curSize > processedSize)
+ {
+ bool res = _outFileStreamSpec->File.SetLength(processedSize);
+ _fileLengthWasSet = res;
+ if (!res)
+ hres = SendMessageError_with_LastError(kCantSetFileLen, us2fs(_item.Path));
+ }
+ _curSize = processedSize;
+ _curSizeDefined = true;
+ RINOK(_outFileStreamSpec->Close());
+ _outFileStream.Release();
+ return hres;
+}
+
+
STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes)
{
COM_TRY_BEGIN
@@ -1454,17 +1529,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes)
#endif
- if (_outFileStream)
- {
- _outFileStreamSpec->SetTime(
- (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
- (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
- (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
- _curSize = _outFileStreamSpec->ProcessedSize;
- _curSizeDefined = true;
- RINOK(_outFileStreamSpec->Close());
- _outFileStream.Release();
- }
+ RINOK(CloseFile());
#ifdef _USE_SECURITY_CODE
if (!_stdOutMode && _extractMode && _ntOptions.NtSecurity.Val && _arc->GetRawProps)
@@ -1511,7 +1576,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes)
NumFiles++;
if (!_stdOutMode && _extractMode && _fi.AttribDefined)
- SetFileAttrib(_diskFilePath, _fi.Attrib);
+ SetFileAttrib_PosixHighDetect(_diskFilePath, _fi.Attrib);
RINOK(_extractCallback2->SetOperationResult(opRes, BoolToInt(_encrypted)));
@@ -1525,23 +1590,19 @@ STDMETHODIMP CArchiveExtractCallback::ReportExtractResult(UInt32 indexType, UInt
if (_folderArchiveExtractCallback2)
{
bool isEncrypted = false;
- wchar_t temp[16];
- UString s2;
- const wchar_t *s = NULL;
+ UString s;
if (indexType == NArchive::NEventIndexType::kInArcIndex && index != (UInt32)(Int32)-1)
{
CReadArcItem item;
RINOK(_arc->GetItem(index, item));
- s2 = item.Path;
- s = s2;
+ s = item.Path;
RINOK(Archive_GetItemBoolProp(_arc->Archive, index, kpidEncrypted, isEncrypted));
}
else
{
- temp[0] = '#';
- ConvertUInt32ToString(index, temp + 1);
- s = temp;
+ s = '#';
+ s.Add_UInt32(index);
// if (indexType == NArchive::NEventIndexType::kBlockIndex) {}
}
@@ -1565,71 +1626,66 @@ STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
}
-struct CExtrRefSortPair
-{
- unsigned Len;
- unsigned Index;
-
- int Compare(const CExtrRefSortPair &a) const;
-};
-
-#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
-
-int CExtrRefSortPair::Compare(const CExtrRefSortPair &a) const
-{
- RINOZ(-MyCompare(Len, a.Len));
- return MyCompare(Index, a.Index);
-}
-
-static unsigned GetNumSlashes(const FChar *s)
+void CDirPathSortPair::SetNumSlashes(const FChar *s)
{
for (unsigned numSlashes = 0;;)
{
FChar c = *s++;
if (c == 0)
- return numSlashes;
+ {
+ Len = numSlashes;
+ return;
+ }
if (IS_PATH_SEPAR(c))
numSlashes++;
}
}
+
+bool CDirPathTime::SetDirTime()
+{
+ return NDir::SetDirTime(Path,
+ CTimeDefined ? &CTime : NULL,
+ ATimeDefined ? &ATime : NULL,
+ MTimeDefined ? &MTime : NULL);
+}
+
+
HRESULT CArchiveExtractCallback::SetDirsTimes()
{
- CRecordVector<CExtrRefSortPair> pairs;
- pairs.ClearAndSetSize(_extractedFolderPaths.Size());
+ if (!_arc)
+ return S_OK;
+
+ CRecordVector<CDirPathSortPair> pairs;
+ pairs.ClearAndSetSize(_extractedFolders.Size());
unsigned i;
- for (i = 0; i < _extractedFolderPaths.Size(); i++)
+ for (i = 0; i < _extractedFolders.Size(); i++)
{
- CExtrRefSortPair &pair = pairs[i];
+ CDirPathSortPair &pair = pairs[i];
pair.Index = i;
- pair.Len = GetNumSlashes(_extractedFolderPaths[i]);
+ pair.SetNumSlashes(_extractedFolders[i].Path);
}
pairs.Sort2();
for (i = 0; i < pairs.Size(); i++)
{
- int pairIndex = pairs[i].Index;
- int index = _extractedFolderIndices[pairIndex];
-
- FILETIME CTime;
- FILETIME ATime;
- FILETIME MTime;
-
- bool CTimeDefined;
- bool ATimeDefined;
- bool MTimeDefined;
-
- RINOK(GetTime(index, kpidCTime, CTime, CTimeDefined));
- RINOK(GetTime(index, kpidATime, ATime, ATimeDefined));
- RINOK(GetTime(index, kpidMTime, MTime, MTimeDefined));
-
- // printf("\n%S", _extractedFolderPaths[pairIndex]);
- SetDirTime(_extractedFolderPaths[pairIndex],
- (WriteCTime && CTimeDefined) ? &CTime : NULL,
- (WriteATime && ATimeDefined) ? &ATime : NULL,
- (WriteMTime && MTimeDefined) ? &MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
+ _extractedFolders[pairs[i].Index].SetDirTime();
+ // if (!) return GetLastError();
}
+
+ ClearExtractedDirsInfo();
return S_OK;
}
+
+
+HRESULT CArchiveExtractCallback::CloseArc()
+{
+ HRESULT res = CloseFile();
+ HRESULT res2 = SetDirsTimes();
+ if (res == S_OK)
+ res = res2;
+ _arc = NULL;
+ return res;
+}
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
index 37979f4..af38f13 100644
--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.h
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
@@ -57,6 +57,8 @@ struct CExtractNtOptions
bool ReplaceColonForAltStream;
bool WriteToAltStreamIfColon;
+ bool PreAllocateOutFile;
+
CExtractNtOptions():
ReplaceColonForAltStream(false),
WriteToAltStreamIfColon(false)
@@ -64,6 +66,13 @@ struct CExtractNtOptions
SymLinks.Val = true;
HardLinks.Val = true;
AltStreams.Val = true;
+
+ PreAllocateOutFile =
+ #ifdef _WIN32
+ true;
+ #else
+ false;
+ #endif
}
};
@@ -142,6 +151,25 @@ struct CIndexToPathPair
#endif
+
+
+struct CDirPathTime
+{
+ FILETIME CTime;
+ FILETIME ATime;
+ FILETIME MTime;
+
+ bool CTimeDefined;
+ bool ATimeDefined;
+ bool MTimeDefined;
+
+ FString Path;
+
+ bool SetDirTime();
+};
+
+
+
class CArchiveExtractCallback:
public IArchiveExtractCallback,
public IArchiveExtractCallbackMessage,
@@ -163,6 +191,7 @@ class CArchiveExtractCallback:
FString _dirPathPrefix_Full;
NExtract::NPathMode::EEnum _pathMode;
NExtract::NOverwriteMode::EEnum _overwriteMode;
+ bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_";
#ifndef _SFX
@@ -201,6 +230,7 @@ class CArchiveExtractCallback:
UInt32 _index;
UInt64 _curSize;
bool _curSizeDefined;
+ bool _fileLengthWasSet;
COutFileStream *_outFileStreamSpec;
CMyComPtr<ISequentialOutStream> _outFileStream;
@@ -230,15 +260,14 @@ class CArchiveExtractCallback:
UInt64 _progressTotal;
bool _progressTotal_Defined;
- FStringVector _extractedFolderPaths;
- CRecordVector<UInt32> _extractedFolderIndices;
+ CObjectVector<CDirPathTime> _extractedFolders;
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
bool _saclEnabled;
#endif
void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
- HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
+ HRESULT GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
HRESULT GetUnpackSize();
HRESULT SendMessageError(const char *message, const FString &path);
@@ -268,11 +297,13 @@ public:
void InitForMulti(bool multiArchives,
NExtract::NPathMode::EEnum pathMode,
- NExtract::NOverwriteMode::EEnum overwriteMode)
+ NExtract::NOverwriteMode::EEnum overwriteMode,
+ bool keepAndReplaceEmptyDirPrefixes)
{
_multiArchives = multiArchives;
_pathMode = pathMode;
_overwriteMode = overwriteMode;
+ _keepAndReplaceEmptyDirPrefixes = keepAndReplaceEmptyDirPrefixes;
NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0;
}
@@ -330,9 +361,43 @@ public:
}
#endif
+ HRESULT CloseArc();
+
+private:
+ void ClearExtractedDirsInfo()
+ {
+ _extractedFolders.Clear();
+ }
+
+ HRESULT CloseFile();
HRESULT SetDirsTimes();
};
+
+struct CArchiveExtractCallback_Closer
+{
+ CArchiveExtractCallback *_ref;
+
+ CArchiveExtractCallback_Closer(CArchiveExtractCallback *ref): _ref(ref) {}
+
+ HRESULT Close()
+ {
+ HRESULT res = S_OK;
+ if (_ref)
+ {
+ res = _ref->CloseArc();
+ _ref = NULL;
+ }
+ return res;
+ }
+
+ ~CArchiveExtractCallback_Closer()
+ {
+ Close();
+ }
+};
+
+
bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
#endif
diff --git a/CPP/7zip/UI/Common/ArchiveName.cpp b/CPP/7zip/UI/Common/ArchiveName.cpp
index c5dad2a..aa47f7a 100644
--- a/CPP/7zip/UI/Common/ArchiveName.cpp
+++ b/CPP/7zip/UI/Common/ArchiveName.cpp
@@ -29,7 +29,7 @@ UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepName)
{
- FString resultName = FTEXT("Archive");
+ FString resultName ("Archive");
if (fromPrev)
{
FString dirPrefix;
diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp
index 14aabcc..c0d0e54 100644
--- a/CPP/7zip/UI/Common/Bench.cpp
+++ b/CPP/7zip/UI/Common/Bench.cpp
@@ -32,8 +32,6 @@
#include "../../../../C/Alloc.h"
#include "../../../../C/CpuArch.h"
-#include "../../../Windows/System.h"
-
#ifndef _7ZIP_ST
#include "../../../Windows/Synchronization.h"
#include "../../../Windows/Thread.h"
@@ -1185,9 +1183,11 @@ static HRESULT MethodBench(
COneMethodInfo method = method2;
UInt64 methodId;
UInt32 numStreams;
- if (!FindMethod(
+ int codecIndex = FindMethod_Index(
EXTERNAL_CODECS_LOC_VARS
- method.MethodName, methodId, numStreams))
+ method.MethodName, true,
+ methodId, numStreams);
+ if (codecIndex < 0)
return E_NOTIMPL;
if (numStreams != 1)
return E_INVALIDARG;
@@ -1200,10 +1200,9 @@ static HRESULT MethodBench(
if (oldLzmaBenchMode && methodId == k_LZMA)
{
- bool fixedNumber;
- UInt32 numLzmaThreads = method.Get_Lzma_NumThreads(fixedNumber);
- if (!fixedNumber && numThreads == 1)
+ if (numThreads == 1 && method.Get_NumThreads() < 0)
method.AddProp_NumThreads(1);
+ const UInt32 numLzmaThreads = method.Get_Lzma_NumThreads();
if (numThreads > 1 && numLzmaThreads > 1)
{
numEncoderThreads = numThreads / 2;
@@ -1225,7 +1224,7 @@ static HRESULT MethodBench(
{
CCreatedCoder cod;
- RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, true, encoder._encoderFilter, cod));
+ RINOK(CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS codecIndex, true, encoder._encoderFilter, cod));
encoder._encoder = cod.Coder;
if (!encoder._encoder && !encoder._encoderFilter)
return E_NOTIMPL;
@@ -1242,7 +1241,7 @@ static HRESULT MethodBench(
{
CCreatedCoder cod;
CMyComPtr<ICompressCoder> &decoder = encoder._decoders[j];
- RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod));
+ RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod));
decoder = cod.Coder;
if (!encoder._decoderFilter && !decoder)
return E_NOTIMPL;
@@ -1858,6 +1857,37 @@ static void PrintTotals(IBenchPrintCallback &f, bool showFreq, UInt64 cpuFreq, c
PrintResults(f, res.Usage / numIterations2, res.RPU / numIterations2, res.Rating / numIterations2, showFreq, cpuFreq);
}
+
+static void PrintHex(AString &s, UInt64 v)
+{
+ char temp[32];
+ ConvertUInt64ToHex(v, temp);
+ s += temp;
+}
+
+AString GetProcessThreadsInfo(const NSystem::CProcessAffinity &ti)
+{
+ AString s;
+ // s.Add_UInt32(ti.numProcessThreads);
+ if (ti.processAffinityMask != ti.systemAffinityMask)
+ {
+ // if (ti.numProcessThreads != ti.numSysThreads)
+ {
+ s += " / ";
+ s.Add_UInt32(ti.GetNumSystemThreads());
+ }
+ s += " : ";
+ PrintHex(s, ti.processAffinityMask);
+ s += " / ";
+ PrintHex(s, ti.systemAffinityMask);
+ }
+ return s;
+}
+
+
+extern bool g_LargePagesMode;
+
+
static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads)
{
@@ -1867,12 +1897,16 @@ static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
PrintNumber(f, (size >> 20), 6);
else
f.Print(" ?");
- f.Print(" MB, # ");
+ f.Print(" MB");
+ if (g_LargePagesMode)
+ f.Print(" LP");
+ f.Print(", # ");
f.Print(threadsString);
PrintNumber(f, numThreads, 3);
- f.NewLine();
}
+
+
struct CBenchCallbackToPrint: public IBenchCallback
{
CBenchProps BenchProps;
@@ -1930,7 +1964,7 @@ HRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool fina
return S_OK;
}
-static const char *kSep = " | ";
+static const char * const kSep = " | ";
HRESULT CBenchCallbackToPrint::SetDecodeResult(const CBenchInfo &info, bool final)
{
@@ -2147,7 +2181,7 @@ static HRESULT CrcBench(
numThreads = 1;
#endif
- AString methodName = method.MethodName;
+ const AString &methodName = method.MethodName;
// methodName.RemoveChar(L'-');
CMethodId hashID;
if (!FindHashMethod(
@@ -2344,15 +2378,7 @@ static UInt32 GetNumThreadsNext(unsigned i, UInt32 numThreads)
static bool AreSameMethodNames(const char *fullName, const char *shortName)
{
- for (;;)
- {
- char c2 = *shortName++;
- if (c2 == 0)
- return true;
- char c1 = *fullName++;
- if (MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
- return false;
- }
+ return StringsAreEqualNoCase_Ascii(fullName, shortName);
}
@@ -2410,6 +2436,245 @@ static void x86cpuid_to_String(const Cx86cpuid &c, AString &s)
#endif
+
+static const char * const k_PROCESSOR_ARCHITECTURE[] =
+{
+ "x86" // "INTEL"
+ , "MIPS"
+ , "ALPHA"
+ , "PPC"
+ , "SHX"
+ , "ARM"
+ , "IA64"
+ , "ALPHA64"
+ , "MSIL"
+ , "x64" // "AMD64"
+ , "IA32_ON_WIN64"
+ , "NEUTRAL"
+ , "ARM64"
+ , "ARM32_ON_WIN64"
+};
+
+#define MY__PROCESSOR_ARCHITECTURE_INTEL 0
+#define MY__PROCESSOR_ARCHITECTURE_AMD64 9
+
+
+#define MY__PROCESSOR_INTEL_PENTIUM 586
+#define MY__PROCESSOR_AMD_X8664 8664
+
+/*
+static const CUInt32PCharPair k_PROCESSOR[] =
+{
+ { 2200, "IA64" },
+ { 8664, "x64" }
+};
+
+#define PROCESSOR_INTEL_386 386
+#define PROCESSOR_INTEL_486 486
+#define PROCESSOR_INTEL_PENTIUM 586
+#define PROCESSOR_INTEL_860 860
+#define PROCESSOR_INTEL_IA64 2200
+#define PROCESSOR_AMD_X8664 8664
+#define PROCESSOR_MIPS_R2000 2000
+#define PROCESSOR_MIPS_R3000 3000
+#define PROCESSOR_MIPS_R4000 4000
+#define PROCESSOR_ALPHA_21064 21064
+#define PROCESSOR_PPC_601 601
+#define PROCESSOR_PPC_603 603
+#define PROCESSOR_PPC_604 604
+#define PROCESSOR_PPC_620 620
+#define PROCESSOR_HITACHI_SH3 10003
+#define PROCESSOR_HITACHI_SH3E 10004
+#define PROCESSOR_HITACHI_SH4 10005
+#define PROCESSOR_MOTOROLA_821 821
+#define PROCESSOR_SHx_SH3 103
+#define PROCESSOR_SHx_SH4 104
+#define PROCESSOR_STRONGARM 2577 // 0xA11
+#define PROCESSOR_ARM720 1824 // 0x720
+#define PROCESSOR_ARM820 2080 // 0x820
+#define PROCESSOR_ARM920 2336 // 0x920
+#define PROCESSOR_ARM_7TDMI 70001
+#define PROCESSOR_OPTIL 18767 // 0x494f
+*/
+
+#ifdef _WIN32
+
+static const char * const k_PF[] =
+{
+ "FP_ERRATA"
+ , "FP_EMU"
+ , "CMPXCHG"
+ , "MMX"
+ , "PPC_MOVEMEM_64BIT"
+ , "ALPHA_BYTE"
+ , "SSE"
+ , "3DNOW"
+ , "RDTSC"
+ , "PAE"
+ , "SSE2"
+ , "SSE_DAZ"
+ , "NX"
+ , "SSE3"
+ , "CMPXCHG16B"
+ , "CMP8XCHG16"
+ , "CHANNELS"
+ , "XSAVE"
+ , "ARM_VFP_32"
+ , "ARM_NEON"
+ , "L2AT"
+ , "VIRT_FIRMWARE"
+ , "RDWRFSGSBASE"
+ , "FASTFAIL"
+ , "ARM_DIVIDE"
+ , "ARM_64BIT_LOADSTORE_ATOMIC"
+ , "ARM_EXTERNAL_CACHE"
+ , "ARM_FMAC"
+ , "RDRAND"
+ , "ARM_V8"
+ , "ARM_V8_CRYPTO"
+ , "ARM_V8_CRC32"
+ , "RDTSCP"
+};
+
+#endif
+
+
+static void PrintSize(AString &s, UInt64 v)
+{
+ char c = 0;
+ if ((v & 0x3FF) == 0) { v >>= 10; c = 'K';
+ if ((v & 0x3FF) == 0) { v >>= 10; c = 'M';
+ if ((v & 0x3FF) == 0) { v >>= 10; c = 'G';
+ if ((v & 0x3FF) == 0) { v >>= 10; c = 'T';
+ }}}}
+ else
+ {
+ PrintHex(s, v);
+ return;
+ }
+ char temp[32];
+ ConvertUInt64ToString(v, temp);
+ s += temp;
+ if (c)
+ s += c;
+}
+
+
+static void PrintPage(AString &s, UInt32 v)
+{
+ if ((v & 0x3FF) == 0)
+ {
+ s.Add_UInt32(v >> 10);
+ s += "K";
+ }
+ else
+ s.Add_UInt32(v >> 10);
+}
+
+static AString TypeToString2(const char * const table[], unsigned num, UInt32 value)
+{
+ char sz[16];
+ const char *p = NULL;
+ if (value < num)
+ p = table[value];
+ if (!p)
+ {
+ ConvertUInt32ToString(value, sz);
+ p = sz;
+ }
+ return (AString)p;
+}
+
+#ifdef _WIN32
+
+static void SysInfo_To_String(AString &s, const SYSTEM_INFO &si)
+{
+ s += TypeToString2(k_PROCESSOR_ARCHITECTURE, ARRAY_SIZE(k_PROCESSOR_ARCHITECTURE), si.wProcessorArchitecture);
+
+ if (!( si.wProcessorArchitecture == MY__PROCESSOR_ARCHITECTURE_INTEL && si.dwProcessorType == MY__PROCESSOR_INTEL_PENTIUM
+ || si.wProcessorArchitecture == MY__PROCESSOR_ARCHITECTURE_AMD64 && si.dwProcessorType == MY__PROCESSOR_AMD_X8664))
+ {
+ s += " ";
+ // s += TypePairToString(k_PROCESSOR, ARRAY_SIZE(k_PROCESSOR), si.dwProcessorType);
+ s.Add_UInt32(si.dwProcessorType);
+ }
+ s += " ";
+ PrintHex(s, si.wProcessorLevel);
+ s += ".";
+ PrintHex(s, si.wProcessorRevision);
+ if ((UInt64)si.dwActiveProcessorMask + 1 != ((UInt64)1 << si.dwNumberOfProcessors))
+ if ((UInt64)si.dwActiveProcessorMask + 1 != 0 || si.dwNumberOfProcessors != sizeof(UInt64) * 8)
+ {
+ s += " act:";
+ PrintHex(s, si.dwActiveProcessorMask);
+ }
+ s += " cpus:";
+ s.Add_UInt32(si.dwNumberOfProcessors);
+ if (si.dwPageSize != 1 << 12)
+ {
+ s += " page:";
+ PrintPage(s, si.dwPageSize);
+ }
+ if (si.dwAllocationGranularity != 1 << 16)
+ {
+ s += " gran:";
+ PrintPage(s, si.dwAllocationGranularity);
+ }
+ s += " ";
+
+ DWORD_PTR minAdd = (DWORD_PTR)si.lpMinimumApplicationAddress;
+ UInt64 maxSize = (UInt64)(DWORD_PTR)si.lpMaximumApplicationAddress + 1;
+ const UInt32 kReserveSize = ((UInt32)1 << 16);
+ if (minAdd != kReserveSize)
+ {
+ PrintSize(s, minAdd);
+ s += "-";
+ }
+ else
+ {
+ if ((maxSize & (kReserveSize - 1)) == 0)
+ maxSize += kReserveSize;
+ }
+ PrintSize(s, maxSize);
+}
+
+#ifndef _WIN64
+typedef VOID (WINAPI *Func_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo);
+#endif
+
+#endif
+
+void GetSysInfo(AString &s1, AString &s2)
+{
+ s1.Empty();
+ s2.Empty();
+
+ #ifdef _WIN32
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ {
+ SysInfo_To_String(s1, si);
+ // s += " : ";
+ }
+
+ #if !defined(_WIN64) && !defined(UNDER_CE)
+ Func_GetNativeSystemInfo fn_GetNativeSystemInfo = (Func_GetNativeSystemInfo)GetProcAddress(
+ GetModuleHandleA("kernel32.dll"), "GetNativeSystemInfo");
+ if (fn_GetNativeSystemInfo)
+ {
+ SYSTEM_INFO si2;
+ fn_GetNativeSystemInfo(&si2);
+ // if (memcmp(&si, &si2, sizeof(si)) != 0)
+ {
+ // s += " - ";
+ SysInfo_To_String(s2, si2);
+ }
+ }
+ #endif
+ #endif
+}
+
+
void GetCpuName(AString &s)
{
s.Empty();
@@ -2419,31 +2684,79 @@ void GetCpuName(AString &s)
Cx86cpuid cpuid;
if (x86cpuid_CheckAndRead(&cpuid))
{
- x86cpuid_to_String(cpuid, s);
- return;
+ AString s2;
+ x86cpuid_to_String(cpuid, s2);
+ s += s2;
}
+ else
+ {
#ifdef MY_CPU_AMD64
- s = "x64";
+ s += "x64";
#else
- s = "x86";
+ s += "x86";
#endif
+ }
}
#else
#ifdef MY_CPU_LE
- s = "LE";
+ s += "LE";
#elif defined(MY_CPU_BE)
- s = "BE";
+ s += "BE";
#endif
#endif
+
+ if (g_LargePagesMode)
+ s += " (LP)";
}
+void GetCpuFeatures(AString &s)
+{
+ s.Empty();
+
+ #ifdef _WIN32
+ const unsigned kNumFeatures_Extra = 32; // we check also for unknown features
+ const unsigned kNumFeatures = ARRAY_SIZE(k_PF) + kNumFeatures_Extra;
+ for (unsigned i = 0; i < kNumFeatures; i++)
+ {
+ if (IsProcessorFeaturePresent(i))
+ {
+ s.Add_Space_if_NotEmpty();
+ s += TypeToString2(k_PF, ARRAY_SIZE(k_PF), i);
+ }
+ }
+ #endif
+}
+
+
+#ifdef _WIN32
+#ifndef UNDER_CE
+
+typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *);
+
+static BOOL My_RtlGetVersion(OSVERSIONINFOEXW *vi)
+{
+ HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll");
+ if (!ntdll)
+ return FALSE;
+ Func_RtlGetVersion func = (Func_RtlGetVersion)GetProcAddress(ntdll, "RtlGetVersion");
+ if (!func)
+ return FALSE;
+ func(vi);
+ return TRUE;
+}
+
+#endif
+#endif
+
+
HRESULT Bench(
DECL_EXTERNAL_CODECS_LOC_VARS
IBenchPrintCallback *printCallback,
IBenchCallback *benchCallback,
+ // IBenchFreqCallback *freqCallback,
const CObjectVector<CProperty> &props,
UInt32 numIterations,
bool multiDict)
@@ -2454,8 +2767,16 @@ HRESULT Bench(
UInt32 numCPUs = 1;
UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29;
+ NSystem::CProcessAffinity threadsInfo;
+ threadsInfo.InitST();
+
#ifndef _7ZIP_ST
- numCPUs = NSystem::GetNumberOfProcessors();
+
+ if (threadsInfo.Get() && threadsInfo.processAffinityMask != 0)
+ numCPUs = threadsInfo.GetNumProcessThreads();
+ else
+ numCPUs = NSystem::GetNumberOfProcessors();
+
#endif
bool ramSize_Defined = NSystem::GetRamSize(ramSize);
@@ -2477,7 +2798,7 @@ HRESULT Bench(
for (i = 0; i < props.Size(); i++)
{
const CProperty &property = props[i];
- UString name = property.Name;
+ UString name (property.Name);
name.MakeLower_Ascii();
if (name.IsEqualTo("file"))
@@ -2504,7 +2825,6 @@ HRESULT Bench(
if (printCallback)
{
printCallback->Print("file size =");
- // printCallback->Print(GetOemString(property.Value));
PrintNumber(*printCallback, len, 0);
printCallback->NewLine();
}
@@ -2523,14 +2843,14 @@ HRESULT Bench(
if (name.IsEqualTo("time"))
{
- RINOK(ParsePropToUInt32(L"", propVariant, testTime));
+ RINOK(ParsePropToUInt32(UString(), propVariant, testTime));
continue;
}
if (name.IsEqualTo("freq"))
{
UInt32 freq32 = 0;
- RINOK(ParsePropToUInt32(L"", propVariant, freq32));
+ RINOK(ParsePropToUInt32(UString(), propVariant, freq32));
if (freq32 == 0)
return E_INVALIDARG;
specifiedFreq = (UInt64)freq32 * 1000000;
@@ -2548,19 +2868,12 @@ HRESULT Bench(
if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
UString s = name.Ptr(2);
- if (s == L"*")
+ if (s.IsEqualTo("*")
+ || s.IsEmpty() && propVariant.vt == VT_BSTR && StringsAreEqual_Ascii(propVariant.bstrVal, "*"))
{
multiThreadTests = true;
continue;
}
- if (s.IsEmpty() && propVariant.vt == VT_BSTR)
- {
- if (wcscmp(propVariant.bstrVal, L"*") == 0)
- {
- multiThreadTests = true;
- continue;
- }
- }
#ifndef _7ZIP_ST
RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified));
#endif
@@ -2573,10 +2886,62 @@ HRESULT Bench(
if (printCallback)
{
- AString s;
- GetCpuName(s);
- printCallback->Print(s);
- printCallback->NewLine();
+ #ifdef _WIN32
+ #ifndef UNDER_CE
+ {
+ AString s;
+ // OSVERSIONINFO vi;
+ OSVERSIONINFOEXW vi;
+ vi.dwOSVersionInfoSize = sizeof(vi);
+ // if (::GetVersionEx(&vi))
+ if (My_RtlGetVersion(&vi))
+ {
+ s += "Windows";
+ if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
+ s.Add_UInt32(vi.dwPlatformId);
+ s += " "; s.Add_UInt32(vi.dwMajorVersion);
+ s += "."; s.Add_UInt32(vi.dwMinorVersion);
+ s += " "; s.Add_UInt32(vi.dwBuildNumber);
+ // s += " "; s += GetAnsiString(vi.szCSDVersion);
+ }
+ printCallback->Print(s);
+ printCallback->NewLine();
+ }
+ #endif
+ #endif
+
+ {
+ AString s1, s2;
+ GetSysInfo(s1, s2);
+ if (!s1.IsEmpty() || !s2.IsEmpty())
+ {
+ printCallback->Print(s1);
+ if (s1 != s2 && !s2.IsEmpty())
+ {
+ printCallback->Print(" - ");
+ printCallback->Print(s2);
+ }
+ printCallback->NewLine();
+ }
+ }
+ {
+ AString s;
+ GetCpuFeatures(s);
+ if (!s.IsEmpty())
+ {
+ printCallback->Print(s);
+ printCallback->NewLine();
+ }
+ }
+ {
+ AString s;
+ GetCpuName(s);
+ if (!s.IsEmpty())
+ {
+ printCallback->Print(s);
+ printCallback->NewLine();
+ }
+ }
}
if (printCallback)
@@ -2586,7 +2951,7 @@ HRESULT Bench(
UInt64 complexInCommands = kComplexInCommands;
- if (printCallback /* || benchCallback */)
+ if (printCallback /* || freqCallback */)
{
UInt64 numMilCommands = 1 << 6;
if (specifiedFreq != 0)
@@ -2623,8 +2988,8 @@ HRESULT Bench(
}
}
/*
- if (benchCallback)
- benchCallback->AddCpuFreq(mipsVal);
+ if (freqCallback)
+ freqCallback->AddCpuFreq(mipsVal);
*/
if (jj >= 3)
@@ -2643,6 +3008,8 @@ HRESULT Bench(
printCallback->NewLine();
printCallback->NewLine();
PrintRequirements(*printCallback, "size: ", ramSize_Defined, ramSize, "CPU hardware threads:", numCPUs);
+ printCallback->Print(GetProcessThreadsInfo(threadsInfo));
+ printCallback->NewLine();
}
if (numThreadsSpecified < 1 || numThreadsSpecified > kNumThreadsMax)
@@ -2669,7 +3036,7 @@ HRESULT Bench(
kOldLzmaDictBits, printCallback, benchCallback, &benchProps);
}
- AString methodName = method.MethodName;
+ AString methodName (method.MethodName);
if (methodName.IsEqualTo_Ascii_NoCase("CRC"))
methodName = "crc32";
method.MethodName = methodName;
@@ -2688,26 +3055,34 @@ HRESULT Bench(
UInt32 complexity = 10000;
const UInt32 *checkSum = NULL;
{
- for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++)
+ unsigned i;
+ for (i = 0; i < ARRAY_SIZE(g_Hash); i++)
{
const CBenchHash &h = g_Hash[i];
- AString s = h.Name;
- AString hProp;
- int propPos = s.Find(':');
+ AString benchMethod (h.Name);
+ AString benchProps;
+ int propPos = benchMethod.Find(':');
if (propPos >= 0)
{
- hProp = s.Ptr(propPos + 1);
- s.DeleteFrom(propPos);
+ benchProps = benchMethod.Ptr(propPos + 1);
+ benchMethod.DeleteFrom(propPos);
}
- if (AreSameMethodNames(s, methodName))
+ if (AreSameMethodNames(benchMethod, methodName))
{
- complexity = h.Complex;
- checkSum = &h.CheckSum;
- if (method.PropsString.IsEqualTo_Ascii_NoCase(hProp))
- break;
+ if (benchProps.IsEmpty()
+ || benchMethod.IsEqualTo_Ascii_NoCase("crc32") && benchProps == "8" && method.PropsString.IsEmpty()
+ || method.PropsString.IsPrefixedBy_Ascii_NoCase(benchProps))
+ {
+ complexity = h.Complex;
+ checkSum = &h.CheckSum;
+ if (method.PropsString.IsEqualTo_Ascii_NoCase(benchProps))
+ break;
+ }
}
}
+ if (i == ARRAY_SIZE(g_Hash))
+ return E_NOTIMPL;
}
f.NewLine();
@@ -2852,6 +3227,7 @@ HRESULT Bench(
}
PrintRequirements(f, "usage:", true, GetBenchMemoryUsage(numThreads, dict, totalBenchMode), "Benchmark threads: ", numThreads);
+ f.NewLine();
f.NewLine();
@@ -2997,19 +3373,35 @@ HRESULT Bench(
bool needSetComplexity = true;
if (!methodName.IsEqualTo_Ascii_NoCase("LZMA"))
{
- for (unsigned i = 0; i < ARRAY_SIZE(g_Bench); i++)
+ unsigned i;
+ for (i = 0; i < ARRAY_SIZE(g_Bench); i++)
{
const CBenchMethod &h = g_Bench[i];
- AString s = h.Name;
- if (AreSameMethodNames(h.Name, methodName))
+ AString benchMethod (h.Name);
+ AString benchProps;
+ int propPos = benchMethod.Find(':');
+ if (propPos >= 0)
{
- callback.BenchProps.EncComplex = h.EncComplex;
- callback.BenchProps.DecComplexCompr = h.DecComplexCompr;
- callback.BenchProps.DecComplexUnc = h.DecComplexUnc;;
- needSetComplexity = false;
- break;
+ benchProps = benchMethod.Ptr(propPos + 1);
+ benchMethod.DeleteFrom(propPos);
+ }
+
+ if (AreSameMethodNames(benchMethod, methodName))
+ {
+ if (benchProps.IsEmpty()
+ || benchProps == "x5" && method.PropsString.IsEmpty()
+ || method.PropsString.IsPrefixedBy_Ascii_NoCase(benchProps))
+ {
+ callback.BenchProps.EncComplex = h.EncComplex;
+ callback.BenchProps.DecComplexCompr = h.DecComplexCompr;
+ callback.BenchProps.DecComplexUnc = h.DecComplexUnc;;
+ needSetComplexity = false;
+ break;
+ }
}
}
+ if (i == ARRAY_SIZE(g_Bench))
+ return E_NOTIMPL;
}
if (needSetComplexity)
callback.BenchProps.SetLzmaCompexity();
@@ -3040,7 +3432,7 @@ HRESULT Bench(
// method2 can have two different dictionary size properties.
// And last property is main.
NCOM::CPropVariant propVariant = (UInt32)pow;
- RINOK(method2.ParseMethodFromPROPVARIANT(L"d", propVariant));
+ RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant));
}
size_t uncompressedDataSize;
diff --git a/CPP/7zip/UI/Common/Bench.h b/CPP/7zip/UI/Common/Bench.h
index 7f9e05c..1990aab 100644
--- a/CPP/7zip/UI/Common/Bench.h
+++ b/CPP/7zip/UI/Common/Bench.h
@@ -3,6 +3,8 @@
#ifndef __7ZIP_BENCH_H
#define __7ZIP_BENCH_H
+#include "../../../Windows/System.h"
+
#include "../../Common/CreateCoder.h"
#include "../../UI/Common/Property.h"
@@ -43,13 +45,28 @@ struct IBenchPrintCallback
virtual HRESULT CheckBreak() = 0;
};
+/*
+struct IBenchFreqCallback
+{
+ virtual void AddCpuFreq(UInt64 freq) = 0;
+};
+*/
+
HRESULT Bench(
DECL_EXTERNAL_CODECS_LOC_VARS
IBenchPrintCallback *printCallback,
IBenchCallback *benchCallback,
+ // IBenchFreqCallback *freqCallback,
const CObjectVector<CProperty> &props,
UInt32 numIterations,
bool multiDict
);
+AString GetProcessThreadsInfo(const NWindows::NSystem::CProcessAffinity &ti);
+
+void GetSysInfo(AString &s1, AString &s2);
+void GetCpuName(AString &s);
+void GetCpuFeatures(AString &s);
+
+
#endif
diff --git a/CPP/7zip/UI/Common/DirItem.h b/CPP/7zip/UI/Common/DirItem.h
index 9e74cd1..47485be 100644
--- a/CPP/7zip/UI/Common/DirItem.h
+++ b/CPP/7zip/UI/Common/DirItem.h
@@ -20,9 +20,18 @@ struct CDirItemsStat
UInt64 AltStreamsSize;
UInt64 NumErrors;
- // UInt64 GetTotalItems() const { return NumDirs + NumFiles + NumAltStreams; }
+ // UInt64 Get_NumItems() const { return NumDirs + NumFiles + NumAltStreams; }
+ UInt64 Get_NumDataItems() const { return NumFiles + NumAltStreams; }
UInt64 GetTotalBytes() const { return FilesSize + AltStreamsSize; }
+
+ bool IsEmpty() const { return
+ 0 == NumDirs
+ && 0 == NumFiles
+ && 0 == NumAltStreams
+ && 0 == FilesSize
+ && 0 == AltStreamsSize
+ && 0 == NumErrors; }
CDirItemsStat():
NumDirs(0),
@@ -34,6 +43,30 @@ struct CDirItemsStat
{}
};
+
+struct CDirItemsStat2: public CDirItemsStat
+{
+ UInt64 Anti_NumDirs;
+ UInt64 Anti_NumFiles;
+ UInt64 Anti_NumAltStreams;
+
+ // UInt64 Get_NumItems() const { return Anti_NumDirs + Anti_NumFiles + Anti_NumAltStreams + CDirItemsStat::Get_NumItems(); }
+ UInt64 Get_NumDataItems2() const { return Anti_NumFiles + Anti_NumAltStreams + CDirItemsStat::Get_NumDataItems(); }
+
+ bool IsEmpty() const { return CDirItemsStat::IsEmpty()
+ && 0 == Anti_NumDirs
+ && 0 == Anti_NumFiles
+ && 0 == Anti_NumAltStreams; }
+
+ CDirItemsStat2():
+ Anti_NumDirs(0),
+ Anti_NumFiles(0),
+ Anti_NumAltStreams(0)
+ {}
+};
+
+
+
#define INTERFACE_IDirItemsCallback(x) \
virtual HRESULT ScanError(const FString &path, DWORD systemError) x; \
virtual HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) x; \
diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp
index c7dec1d..032e2ff 100644
--- a/CPP/7zip/UI/Common/EnumDirItems.cpp
+++ b/CPP/7zip/UI/Common/EnumDirItems.cpp
@@ -16,6 +16,7 @@
#endif
#include "EnumDirItems.h"
+#include "SortUtils.h"
using namespace NWindows;
using namespace NFile;
@@ -213,7 +214,8 @@ HRESULT CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phy
{
RINOK(ScanProgress(phyPrefix));
- NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
+ NFind::CEnumerator enumerator;
+ enumerator.SetDirPrefix(phyPrefix);
for (unsigned ttt = 0; ; ttt++)
{
NFind::CFileInfo fi;
@@ -342,6 +344,7 @@ static HRESULT EnumerateAltStreams(
const NWildcard::CCensorNode &curNode,
int phyParent, int logParent, const FString &fullPath,
const UStringVector &addArchivePrefix, // prefix from curNode
+ bool addAllItems,
CDirItems &dirItems)
{
NFind::CStreamEnumerator enumerator(fullPath);
@@ -362,6 +365,10 @@ static HRESULT EnumerateAltStreams(
addArchivePrefixNew.Back() += reducedName;
if (curNode.CheckPathToRoot(false, addArchivePrefixNew, true))
continue;
+ if (!addAllItems)
+ if (!curNode.CheckPathToRoot(true, addArchivePrefixNew, true))
+ continue;
+
NFind::CFileInfo fi2 = fi;
fi2.Name += us2fs(reducedName);
fi2.Size = si.Size;
@@ -380,15 +387,27 @@ HRESULT CDirItems::SetLinkInfo(CDirItem &dirItem, const NFind::CFileInfo &fi,
return S_OK;
const FString path = phyPrefix + fi.Name;
CByteBuffer &buf = dirItem.ReparseData;
+ DWORD res = 0;
if (NIO::GetReparseData(path, buf))
{
CReparseAttr attr;
- if (attr.Parse(buf, buf.Size()))
+ if (attr.Parse(buf, buf.Size(), res))
return S_OK;
+ // we ignore unknown reparse points
+ if (res != ERROR_INVALID_REPARSE_DATA)
+ res = 0;
+ }
+ else
+ {
+ res = ::GetLastError();
+ if (res == 0)
+ res = ERROR_INVALID_FUNCTION;
}
- DWORD res = ::GetLastError();
+
buf.Free();
- return AddError(path , res);
+ if (res == 0)
+ return S_OK;
+ return AddError(path, res);
}
#endif
@@ -412,6 +431,8 @@ static HRESULT EnumerateForItem(
}
int dirItemIndex = -1;
+ bool addAllSubStreams = false;
+
if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fi.IsDir()))
{
int secureIndex = -1;
@@ -426,6 +447,8 @@ static HRESULT EnumerateForItem(
dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi);
if (fi.IsDir())
enterToSubFolders2 = true;
+
+ addAllSubStreams = true;
}
#ifndef UNDER_CE
@@ -433,7 +456,9 @@ static HRESULT EnumerateForItem(
{
RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent,
phyPrefix + fi.Name,
- addArchivePrefixNew, dirItems));
+ addArchivePrefixNew,
+ addAllSubStreams,
+ dirItems));
}
if (dirItemIndex >= 0)
@@ -570,7 +595,7 @@ static HRESULT EnumerateDirItems(
#endif
*/
- fullPath = FCHAR_PATH_SEPARATOR;
+ fullPath = CHAR_PATH_SEPARATOR;
}
#if defined(_WIN32) && !defined(UNDER_CE)
else if (item.IsDriveItem())
@@ -642,7 +667,9 @@ static HRESULT EnumerateDirItems(
UStringVector pathParts;
pathParts.Add(fs2us(fi.Name));
RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent,
- fullPath, pathParts, dirItems));
+ fullPath, pathParts,
+ true, /* addAllSubStreams */
+ dirItems));
}
#endif
@@ -682,7 +709,7 @@ static HRESULT EnumerateDirItems(
{
{
if (nextNode.Name.IsEmpty())
- fullPath = FCHAR_PATH_SEPARATOR;
+ fullPath = CHAR_PATH_SEPARATOR;
#ifdef _WIN32
else if (NWildcard::IsDriveColonName(nextNode.Name))
fullPath.Add_PathSepar();
@@ -773,7 +800,9 @@ static HRESULT EnumerateDirItems(
#endif
#endif
- NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
+ NFind::CEnumerator enumerator;
+ enumerator.SetDirPrefix(phyPrefix);
+
for (unsigned ttt = 0; ; ttt++)
{
NFind::CFileInfo fi;
@@ -849,7 +878,8 @@ void CDirItems::FillFixedReparse()
continue;
CReparseAttr attr;
- if (!attr.Parse(item.ReparseData, item.ReparseData.Size()))
+ DWORD errorCode = 0;
+ if (!attr.Parse(item.ReparseData, item.ReparseData.Size(), errorCode))
continue;
if (attr.IsRelative())
continue;
@@ -896,3 +926,161 @@ void CDirItems::FillFixedReparse()
}
#endif
+
+
+
+static const char * const kCannotFindArchive = "Cannot find archive";
+
+HRESULT EnumerateDirItemsAndSort(
+ NWildcard::CCensor &censor,
+ NWildcard::ECensorPathMode censorPathMode,
+ const UString &addPathPrefix,
+ UStringVector &sortedPaths,
+ UStringVector &sortedFullPaths,
+ CDirItemsStat &st,
+ IDirItemsCallback *callback)
+{
+ FStringVector paths;
+
+ {
+ CDirItems dirItems;
+ dirItems.Callback = callback;
+ {
+ HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems);
+ st = dirItems.Stat;
+ RINOK(res);
+ }
+
+ FOR_VECTOR (i, dirItems.Items)
+ {
+ const CDirItem &dirItem = dirItems.Items[i];
+ if (!dirItem.IsDir())
+ paths.Add(dirItems.GetPhyPath(i));
+ }
+ }
+
+ if (paths.Size() == 0)
+ {
+ // return S_OK;
+ throw CMessagePathException(kCannotFindArchive);
+ }
+
+ UStringVector fullPaths;
+
+ unsigned i;
+
+ for (i = 0; i < paths.Size(); i++)
+ {
+ FString fullPath;
+ NFile::NDir::MyGetFullPathName(paths[i], fullPath);
+ fullPaths.Add(fs2us(fullPath));
+ }
+
+ CUIntVector indices;
+ SortFileNames(fullPaths, indices);
+ sortedPaths.ClearAndReserve(indices.Size());
+ sortedFullPaths.ClearAndReserve(indices.Size());
+
+ for (i = 0; i < indices.Size(); i++)
+ {
+ unsigned index = indices[i];
+ sortedPaths.AddInReserved(fs2us(paths[index]));
+ sortedFullPaths.AddInReserved(fullPaths[index]);
+ if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0)
+ throw CMessagePathException("Duplicate archive path:", sortedFullPaths[i]);
+ }
+
+ return S_OK;
+}
+
+
+
+
+#ifdef _WIN32
+
+// This code converts all short file names to long file names.
+
+static void ConvertToLongName(const UString &prefix, UString &name)
+{
+ if (name.IsEmpty() || DoesNameContainWildcard(name))
+ return;
+ NFind::CFileInfo fi;
+ const FString path (us2fs(prefix + name));
+ #ifndef UNDER_CE
+ if (NFile::NName::IsDevicePath(path))
+ return;
+ #endif
+ if (fi.Find(path))
+ name = fs2us(fi.Name);
+}
+
+static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
+{
+ FOR_VECTOR (i, items)
+ {
+ NWildcard::CItem &item = items[i];
+ if (item.Recursive || item.PathParts.Size() != 1)
+ continue;
+ if (prefix.IsEmpty() && item.IsDriveItem())
+ continue;
+ ConvertToLongName(prefix, item.PathParts.Front());
+ }
+}
+
+static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)
+{
+ ConvertToLongNames(prefix, node.IncludeItems);
+ ConvertToLongNames(prefix, node.ExcludeItems);
+ unsigned i;
+ for (i = 0; i < node.SubNodes.Size(); i++)
+ {
+ UString &name = node.SubNodes[i].Name;
+ if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name))
+ continue;
+ ConvertToLongName(prefix, name);
+ }
+ // mix folders with same name
+ for (i = 0; i < node.SubNodes.Size(); i++)
+ {
+ NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
+ for (unsigned j = i + 1; j < node.SubNodes.Size();)
+ {
+ const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
+ if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name))
+ {
+ nextNode1.IncludeItems += nextNode2.IncludeItems;
+ nextNode1.ExcludeItems += nextNode2.ExcludeItems;
+ node.SubNodes.Delete(j);
+ }
+ else
+ j++;
+ }
+ }
+ for (i = 0; i < node.SubNodes.Size(); i++)
+ {
+ NWildcard::CCensorNode &nextNode = node.SubNodes[i];
+ ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode);
+ }
+}
+
+void ConvertToLongNames(NWildcard::CCensor &censor)
+{
+ FOR_VECTOR (i, censor.Pairs)
+ {
+ NWildcard::CPair &pair = censor.Pairs[i];
+ ConvertToLongNames(pair.Prefix, pair.Head);
+ }
+}
+
+#endif
+
+
+CMessagePathException::CMessagePathException(const char *a, const wchar_t *u)
+{
+ (*this) += a;
+ if (u)
+ {
+ Add_LF();
+ (*this) += u;
+ }
+}
diff --git a/CPP/7zip/UI/Common/EnumDirItems.h b/CPP/7zip/UI/Common/EnumDirItems.h
index 15de340..6220500 100644
--- a/CPP/7zip/UI/Common/EnumDirItems.h
+++ b/CPP/7zip/UI/Common/EnumDirItems.h
@@ -18,4 +18,24 @@ HRESULT EnumerateItems(
const UString &addPathPrefix,
CDirItems &dirItems);
+
+struct CMessagePathException: public UString
+{
+ CMessagePathException(const char *a, const wchar_t *u = NULL);
+};
+
+
+HRESULT EnumerateDirItemsAndSort(
+ NWildcard::CCensor &censor,
+ NWildcard::ECensorPathMode pathMode,
+ const UString &addPathPrefix,
+ UStringVector &sortedPaths,
+ UStringVector &sortedFullPaths,
+ CDirItemsStat &st,
+ IDirItemsCallback *callback);
+
+#ifdef _WIN32
+void ConvertToLongNames(NWildcard::CCensor &censor);
+#endif
+
#endif
diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp
index a0d109e..2cb2c9b 100644
--- a/CPP/7zip/UI/Common/Extract.cpp
+++ b/CPP/7zip/UI/Common/Extract.cpp
@@ -51,7 +51,7 @@ static HRESULT DecompressArchive(
replaceName = arc0.DefaultName;
}
- outDir.Replace(FSTRING_ANY_MASK, us2fs(Get_Correct_FsFile_Name(replaceName)));
+ outDir.Replace(FString("*"), us2fs(Get_Correct_FsFile_Name(replaceName)));
bool elimIsPossible = false;
UString elimPrefix; // only pure name without dir delimiter
@@ -156,7 +156,7 @@ static HRESULT DecompressArchive(
#endif
if (outDir.IsEmpty())
- outDir = FTEXT(".") FSTRING_PATH_SEPARATOR;
+ outDir = "." STRING_PATH_SEPARATOR;
/*
#ifdef _WIN32
else if (NName::IsAltPathPrefix(outDir)) {}
@@ -167,7 +167,7 @@ static HRESULT DecompressArchive(
HRESULT res = ::GetLastError();
if (res == S_OK)
res = E_FAIL;
- errorMessage.SetFromAscii("Can not create output directory: ");
+ errorMessage = "Can not create output directory: ";
errorMessage += fs2us(outDir);
return res;
}
@@ -197,6 +197,9 @@ static HRESULT DecompressArchive(
HRESULT result;
Int32 testMode = (options.TestMode && !calcCrc) ? 1: 0;
+
+ CArchiveExtractCallback_Closer ecsCloser(ecs);
+
if (options.StdInMode)
{
result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, ecs);
@@ -206,8 +209,11 @@ static HRESULT DecompressArchive(
}
else
result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, ecs);
- if (result == S_OK && !options.StdInMode)
- result = ecs->SetDirsTimes();
+
+ HRESULT res2 = ecsCloser.Close();
+ if (result == S_OK)
+ result = res2;
+
return callback->ExtractResult(result);
}
@@ -279,7 +285,9 @@ HRESULT Extract(
CArchiveExtractCallback *ecs = new CArchiveExtractCallback;
CMyComPtr<IArchiveExtractCallback> ec(ecs);
bool multi = (numArcs > 1);
- ecs->InitForMulti(multi, options.PathMode, options.OverwriteMode);
+ ecs->InitForMulti(multi, options.PathMode, options.OverwriteMode,
+ false // keepEmptyDirParts
+ );
#ifndef _SFX
ecs->SetHashMethods(hash);
#endif
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
index d395232..13665de 100644
--- a/CPP/7zip/UI/Common/ExtractingFilePath.cpp
+++ b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
@@ -8,6 +8,15 @@
#include "ExtractingFilePath.h"
+bool g_PathTrailReplaceMode =
+ #ifdef _WIN32
+ true
+ #else
+ false
+ #endif
+ ;
+
+
static void ReplaceIncorrectChars(UString &s)
{
{
@@ -26,17 +35,42 @@ static void ReplaceIncorrectChars(UString &s)
}
}
- #ifdef _WIN32
+ if (g_PathTrailReplaceMode)
{
- for (unsigned i = s.Len(); i != 0;)
+ /*
+ // if (g_PathTrailReplaceMode == 1)
{
- wchar_t c = s[--i];
- if (c != '.' && c != ' ')
- break;
- s.ReplaceOneCharAtPos(i, '_');
+ if (!s.IsEmpty())
+ {
+ wchar_t c = s.Back();
+ if (c == '.' || c == ' ')
+ {
+ // s += (wchar_t)(0x9c); // STRING TERMINATOR
+ s += (wchar_t)'_';
+ }
+ }
+ }
+ else
+ */
+ {
+ unsigned i;
+ for (i = s.Len(); i != 0;)
+ {
+ wchar_t c = s[i - 1];
+ if (c != '.' && c != ' ')
+ break;
+ i--;
+ s.ReplaceOneCharAtPos(i, '_');
+ // s.ReplaceOneCharAtPos(i, (c == ' ' ? (wchar_t)(0x2423) : (wchar_t)0x00B7));
+ }
+ /*
+ if (g_PathTrailReplaceMode > 1 && i != s.Len())
+ {
+ s.DeleteFrom(i);
+ }
+ */
}
}
- #endif
}
#ifdef _WIN32
@@ -61,7 +95,7 @@ void Correct_AltStream_Name(UString &s)
s.ReplaceOneCharAtPos(i, '_');
}
if (s.IsEmpty())
- s = L'_';
+ s = '_';
}
static const unsigned g_ReservedWithNum_Index = 4;
@@ -112,6 +146,9 @@ static void CorrectUnsupportedName(UString &name)
static void Correct_PathPart(UString &s)
{
// "." and ".."
+ if (s.IsEmpty())
+ return;
+
if (s[0] == '.' && (s[1] == 0 || s[1] == '.' && s[2] == 0))
s.Empty();
#ifdef _WIN32
@@ -120,8 +157,8 @@ static void Correct_PathPart(UString &s)
#endif
}
-// static const wchar_t *k_EmptyReplaceName = L"[]";
-static const wchar_t k_EmptyReplaceName = L'_';
+// static const char * const k_EmptyReplaceName = "[]";
+static const char k_EmptyReplaceName = '_';
UString Get_Correct_FsFile_Name(const UString &name)
{
@@ -138,7 +175,7 @@ UString Get_Correct_FsFile_Name(const UString &name)
}
-void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir)
+void Correct_FsPath(bool absIsAllowed, bool keepAndReplaceEmptyPrefixes, UStringVector &parts, bool isDir)
{
unsigned i = 0;
@@ -147,6 +184,7 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir)
#if defined(_WIN32) && !defined(UNDER_CE)
bool isDrive = false;
#endif
+
if (parts[0].IsEmpty())
{
i = 1;
@@ -157,7 +195,7 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir)
if (parts.Size() > 2 && parts[2] == L"?")
{
i = 3;
- if (parts.Size() > 3 && NWindows::NFile::NName::IsDrivePath2(parts[3]))
+ if (parts.Size() > 3 && NWindows::NFile::NName::IsDrivePath2(parts[3]))
{
isDrive = true;
i = 4;
@@ -176,16 +214,19 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir)
if (isDrive)
{
// we convert "c:name" to "c:\name", if absIsAllowed path.
- const UString &ds = parts[i - 1];
- if (ds.Len() != 2)
+ UString &ds = parts[i - 1];
+ if (ds.Len() > 2)
{
- UString s = ds.Ptr(2);
- parts.Insert(i, s);
+ parts.Insert(i, ds.Ptr(2));
+ ds.DeleteFrom(2);
}
}
#endif
}
+ if (i != 0)
+ keepAndReplaceEmptyPrefixes = false;
+
for (; i < parts.Size();)
{
UString &s = parts[i];
@@ -194,15 +235,17 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir)
if (s.IsEmpty())
{
- if (isDir || i != parts.Size() - 1)
- {
- parts.Delete(i);
- continue;
- }
+ if (!keepAndReplaceEmptyPrefixes)
+ if (isDir || i != parts.Size() - 1)
+ {
+ parts.Delete(i);
+ continue;
+ }
s = k_EmptyReplaceName;
}
else
{
+ keepAndReplaceEmptyPrefixes = false;
#ifdef _WIN32
CorrectUnsupportedName(s);
#endif
@@ -214,7 +257,7 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir)
if (!isDir)
{
if (parts.IsEmpty())
- parts.Add(k_EmptyReplaceName);
+ parts.Add((UString)k_EmptyReplaceName);
else
{
UString &s = parts.Back();
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.h b/CPP/7zip/UI/Common/ExtractingFilePath.h
index ce200b8..12eb0ba 100644
--- a/CPP/7zip/UI/Common/ExtractingFilePath.h
+++ b/CPP/7zip/UI/Common/ExtractingFilePath.h
@@ -12,7 +12,19 @@ void Correct_AltStream_Name(UString &s);
// replaces unsuported characters, and replaces "." , ".." and "" to "[]"
UString Get_Correct_FsFile_Name(const UString &name);
-void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir);
+/*
+ Correct_FsPath() corrects path parts to prepare it for File System operations.
+ It also corrects empty path parts like "\\\\":
+ - frontal empty path parts : it removes them or changes them to "_"
+ - another empty path parts : it removes them
+ if (absIsAllowed && path is absolute) : it removes empty path parts after start absolute path prefix marker
+ else
+ {
+ if (!keepAndReplaceEmptyPrefixes) : it removes empty path parts
+ if ( keepAndReplaceEmptyPrefixes) : it changes each empty frontal path part to "_"
+ }
+*/
+void Correct_FsPath(bool absIsAllowed, bool keepAndReplaceEmptyPrefixes, UStringVector &parts, bool isDir);
UString MakePathFromParts(const UStringVector &parts);
diff --git a/CPP/7zip/UI/Common/HashCalc.cpp b/CPP/7zip/UI/Common/HashCalc.cpp
index 9d4747b..9c0a1d0 100644
--- a/CPP/7zip/UI/Common/HashCalc.cpp
+++ b/CPP/7zip/UI/Common/HashCalc.cpp
@@ -30,17 +30,13 @@ public:
~CHashMidBuf() { ::MidFree(_data); }
};
-static const char *k_DefaultHashMethod = "CRC32";
+static const char * const k_DefaultHashMethod = "CRC32";
HRESULT CHashBundle::SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &hashMethods)
{
UStringVector names = hashMethods;
if (names.IsEmpty())
- {
- UString s;
- s.SetFromAscii(k_DefaultHashMethod);
- names.Add(s);
- }
+ names.Add(UString(k_DefaultHashMethod));
CRecordVector<CMethodId> ids;
CObjectVector<COneMethodInfo> methods;
diff --git a/CPP/7zip/UI/Common/HashCalc.h b/CPP/7zip/UI/Common/HashCalc.h
index d98c577..77373b8 100644
--- a/CPP/7zip/UI/Common/HashCalc.h
+++ b/CPP/7zip/UI/Common/HashCalc.h
@@ -9,7 +9,6 @@
#include "../../Common/MethodProps.h"
#include "DirItem.h"
-#include "Property.h"
const unsigned k_HashCalc_DigestSize_Max = 64;
diff --git a/CPP/7zip/UI/Common/LoadCodecs.cpp b/CPP/7zip/UI/Common/LoadCodecs.cpp
index 9379152..d31e05f 100644
--- a/CPP/7zip/UI/Common/LoadCodecs.cpp
+++ b/CPP/7zip/UI/Common/LoadCodecs.cpp
@@ -81,7 +81,7 @@ using namespace NFile;
#define kFormatsFolderName FTEXT("Formats")
-static CFSTR kMainDll =
+static CFSTR const kMainDll =
// #ifdef _WIN32
FTEXT("7z.dll");
// #else
@@ -91,9 +91,9 @@ static CFSTR kMainDll =
#ifdef _WIN32
-static LPCTSTR kRegistryPath = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-zip");
-static LPCWSTR kProgramPathValue = L"Path";
-static LPCWSTR kProgramPath2Value = L"Path"
+static LPCTSTR const kRegistryPath = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-zip");
+static LPCWSTR const kProgramPathValue = L"Path";
+static LPCWSTR const kProgramPath2Value = L"Path"
#ifdef _WIN64
L"64";
#else
@@ -516,12 +516,11 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded
}
lib.CreateObject = (Func_CreateObject)lib.Lib.GetProc("CreateObject");
- if (lib.CreateObject)
{
unsigned startSize = Codecs.Size() + Hashers.Size();
res = LoadCodecs();
used = (startSize != Codecs.Size() + Hashers.Size());
- if (res == S_OK)
+ if (res == S_OK && lib.CreateObject)
{
startSize = Formats.Size();
res = LoadFormats();
@@ -539,7 +538,8 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded
HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPrefix)
{
- NFile::NFind::CEnumerator enumerator(folderPrefix + FCHAR_ANY_MASK);
+ NFile::NFind::CEnumerator enumerator;
+ enumerator.SetDirPrefix(folderPrefix);
NFile::NFind::CFileInfo fi;
while (enumerator.Next(fi))
{
@@ -595,7 +595,7 @@ HRESULT CCodecs::Load()
const CArcInfo &arc = *g_Arcs[i];
CArcInfoEx item;
- item.Name.SetFromAscii(arc.Name);
+ item.Name = arc.Name;
item.CreateInArchive = arc.CreateInArchive;
item.IsArcFunc = arc.IsArc;
item.Flags = arc.Flags;
@@ -603,9 +603,9 @@ HRESULT CCodecs::Load()
{
UString e, ae;
if (arc.Ext)
- e.SetFromAscii(arc.Ext);
+ e = arc.Ext;
if (arc.AddExt)
- ae.SetFromAscii(arc.AddExt);
+ ae = arc.AddExt;
item.AddExts(e, ae);
}
@@ -866,7 +866,8 @@ STDMETHODIMP CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder)
const CCodecLib &lib = Libs[ci.LibIndex];
if (lib.CreateDecoder)
return lib.CreateDecoder(ci.CodecIndex, iid, (void **)coder);
- return lib.CreateObject(&ci.Decoder, iid, (void **)coder);
+ if (lib.CreateObject)
+ return lib.CreateObject(&ci.Decoder, iid, (void **)coder);
}
return S_OK;
#else
@@ -888,7 +889,8 @@ STDMETHODIMP CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder)
const CCodecLib &lib = Libs[ci.LibIndex];
if (lib.CreateEncoder)
return lib.CreateEncoder(ci.CodecIndex, iid, (void **)coder);
- return lib.CreateObject(&ci.Encoder, iid, (void **)coder);
+ if (lib.CreateObject)
+ return lib.CreateObject(&ci.Encoder, iid, (void **)coder);
}
return S_OK;
#else
diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp
index 968f0ca..9549269 100644
--- a/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -330,17 +330,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath:
{
- wchar_t sz[32];
+ char sz[32];
ConvertUInt32ToString(index + 1, sz);
- UString s = sz;
+ UString s(sz);
if (!item.Name.IsEmpty())
{
- s += L'.';
+ s += '.';
s += item.Name;
}
if (!item.Extension.IsEmpty())
{
- s += L'.';
+ s += '.';
s += item.Extension;
}
prop = s; break;
@@ -583,7 +583,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
{
{
UString &s2 = parts[parts.Size() - 2];
- s2 += L':';
+ s2 += ':';
s2 += parts.Back();
}
parts.DeleteBack();
@@ -733,7 +733,7 @@ HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const
RINOK(Archive->GetProperty(index, kpidExtension, &prop));
if (prop.vt == VT_BSTR)
{
- result += L'.';
+ result += '.';
result += prop.bstrVal;
}
else if (prop.vt != VT_EMPTY)
@@ -857,7 +857,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
if (item.WriteToAltStreamIfColon || needFindAltStream)
{
- /* Good handler must support GetRawProps::GetParent for alt streams./
+ /* Good handler must support GetRawProps::GetParent for alt streams.
So the following code currently is not used */
int colon = FindAltStreamColon_in_Path(item.Path);
if (colon >= 0)
@@ -992,7 +992,7 @@ static void MakeCheckOrder(CCodecs *codecs,
int index = orderIndices[i];
if (index < 0)
continue;
- const CArcInfoEx &ai = codecs->Formats[index];
+ const CArcInfoEx &ai = codecs->Formats[(unsigned)index];
if (ai.SignatureOffset != 0)
{
orderIndices2.Add(index);
@@ -1020,10 +1020,11 @@ static void MakeCheckOrder(CCodecs *codecs,
#ifdef UNDER_CE
static const unsigned kNumHashBytes = 1;
- #define HASH_VAL(buf, pos) ((buf)[pos])
+ #define HASH_VAL(buf) ((buf)[0])
#else
static const unsigned kNumHashBytes = 2;
- #define HASH_VAL(buf, pos) ((buf)[pos] | ((UInt32)(buf)[pos + 1] << 8))
+ // #define HASH_VAL(buf) ((buf)[0] | ((UInt32)(buf)[1] << 8))
+ #define HASH_VAL(buf) GetUi16(buf)
#endif
@@ -2294,7 +2295,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
int index = orderIndices[i];
if (index < 0)
continue;
- const CArcInfoEx &ai = op.codecs->Formats[index];
+ const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index];
bool isDifficult = false;
// if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31)
if (!ai.NewInterface)
@@ -2317,7 +2318,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
continue;
}
thereAreHandlersForSearch = true;
- UInt32 v = HASH_VAL(sig, 0);
+ UInt32 v = HASH_VAL(sig);
unsigned sigIndex = arc2sig[(unsigned)index] + k;
prevs[sigIndex] = hash[v];
hash[v] = (Byte)sigIndex;
@@ -2326,7 +2327,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (isDifficult)
{
difficultFormats.Add(index);
- difficultBools[index] = true;
+ difficultBools[(unsigned)index] = true;
}
}
@@ -2440,6 +2441,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
}
+ if (bytesInBuf <= (size_t)posInBuf)
+ break;
+
bool useOffsetCallback = false;
if (openCallback_Offset)
{
@@ -2489,17 +2493,19 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
scanSize++;
const Byte *buf = byteBuffer + (size_t)posInBuf;
+ const Byte *bufLimit = buf + scanSize;
size_t ppp = 0;
if (!needCheckStartOpen)
{
- for (; ppp < scanSize && hash[HASH_VAL(buf, ppp)] == 0xFF; ppp++);
+ for (; buf < bufLimit && hash[HASH_VAL(buf)] == 0xFF; buf++);
+ ppp = buf - (byteBuffer + (size_t)posInBuf);
pos += ppp;
- if (ppp == scanSize)
+ if (buf == bufLimit)
continue;
}
- UInt32 v = HASH_VAL(buf, ppp);
+ UInt32 v = HASH_VAL(buf);
bool nextNeedCheckStartOpen = true;
unsigned i = hash[v];
unsigned indexOfDifficult = 0;
@@ -2539,7 +2545,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
const CByteBuffer &sig = ai.Signatures[sigIndex];
if (ppp + sig.Size() > availSize
- || !TestSignature(buf + ppp, sig, sig.Size()))
+ || !TestSignature(buf, sig, sig.Size()))
continue;
// printf("\nSignature OK: %10S %8x %5d", (const wchar_t *)ai.Name, (int)pos, (int)(pos - prevPos));
// prevPos = pos;
@@ -2946,10 +2952,10 @@ HRESULT CArc::OpenStream(const COpenOptions &op)
#ifdef _SFX
#ifdef _WIN32
- static const char *k_ExeExt = ".exe";
+ #define k_ExeExt ".exe"
static const unsigned k_ExeExt_Len = 4;
#else
- static const char *k_ExeExt = "";
+ #define k_ExeExt ""
static const unsigned k_ExeExt_Len = 0;
#endif
@@ -3012,10 +3018,10 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
if (ai.IsSplit())
continue;
UString path3 = path2;
- path3 += L'.';
+ path3 += '.';
path3 += ai.GetMainExt(); // "7z" for SFX.
Path = path3;
- Path.AddAscii(".001");
+ Path += ".001";
bool isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path));
if (!isOk)
{
diff --git a/CPP/7zip/UI/Common/OpenArchive.h b/CPP/7zip/UI/Common/OpenArchive.h
index 0395987..033cb96 100644
--- a/CPP/7zip/UI/Common/OpenArchive.h
+++ b/CPP/7zip/UI/Common/OpenArchive.h
@@ -414,4 +414,23 @@ struct CArchiveLink
bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types);
+
+struct CDirPathSortPair
+{
+ unsigned Len;
+ unsigned Index;
+
+ void SetNumSlashes(const FChar *s);
+
+ int Compare(const CDirPathSortPair &a) const
+ {
+ // We need sorting order where parent items will be after child items
+ if (Len < a.Len) return 1;
+ if (Len > a.Len) return -1;
+ if (Index < a.Index) return -1;
+ if (Index > a.Index) return 1;
+ return 0;
+ }
+};
+
#endif
diff --git a/CPP/7zip/UI/Common/PropIDUtils.cpp b/CPP/7zip/UI/Common/PropIDUtils.cpp
index 9633248..bb9c89f 100644
--- a/CPP/7zip/UI/Common/PropIDUtils.cpp
+++ b/CPP/7zip/UI/Common/PropIDUtils.cpp
@@ -19,12 +19,16 @@
using namespace NWindows;
-static const char g_WinAttribChars[16 + 1] = "RHS8DAdNTsLCOnE_";
+static const unsigned kNumWinAtrribFlags = 21;
+static const char g_WinAttribChars[kNumWinAtrribFlags + 1] = "RHS8DAdNTsLCOIEV.X.PU";
+
/*
+FILE_ATTRIBUTE_
+
0 READONLY
1 HIDDEN
2 SYSTEM
-
+3 (Volume label - obsolete)
4 DIRECTORY
5 ARCHIVE
6 DEVICE
@@ -34,12 +38,19 @@ static const char g_WinAttribChars[16 + 1] = "RHS8DAdNTsLCOnE_";
10 REPARSE_POINT
11 COMPRESSED
12 OFFLINE
-13 NOT_CONTENT_INDEXED
+13 NOT_CONTENT_INDEXED (I - Win10 attrib/Explorer)
14 ENCRYPTED
-
-16 VIRTUAL
+15 INTEGRITY_STREAM (V - ReFS Win8/Win2012)
+16 VIRTUAL (reserved)
+17 NO_SCRUB_DATA (X - ReFS Win8/Win2012 attrib)
+18 RECALL_ON_OPEN or EA
+19 PINNED
+20 UNPINNED
+21 STRICTLY_SEQUENTIAL
+22 RECALL_ON_DATA_ACCESS
*/
+
static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' };
#define MY_ATTR_CHAR(a, n, c) ((a) & (1 << (n))) ? c : '-';
@@ -65,36 +76,68 @@ static void ConvertPosixAttribToString(char *s, UInt32 a) throw()
}
}
+
void ConvertWinAttribToString(char *s, UInt32 wa) throw()
{
- for (int i = 0; i < 16; i++)
- if ((wa & (1 << i)) && i != 7)
- *s++ = g_WinAttribChars[i];
- *s = 0;
+ /*
+ some programs store posix attributes in high 16 bits.
+ p7zip - stores additional 0x8000 flag marker.
+ macos - stores additional 0x4000 flag marker.
+ info-zip - no additional marker.
+ */
+
+ bool isPosix = ((wa & 0xF0000000) != 0);
+
+ UInt32 posix = 0;
+ if (isPosix)
+ {
+ posix = wa >> 16;
+ wa &= (UInt32)0x3FFF;
+ }
- // we support p7zip trick that stores posix attributes in high 16 bits, and 0x8000 flag
- // we also support ZIP archives created in Unix, that store posix attributes in high 16 bits without 0x8000 flag
+ for (unsigned i = 0; i < kNumWinAtrribFlags; i++)
+ {
+ UInt32 flag = (1 << i);
+ if ((wa & flag) != 0)
+ {
+ char c = g_WinAttribChars[i];
+ if (c != '.')
+ {
+ wa &= ~flag;
+ // if (i != 7) // we can disable N (NORMAL) printing
+ *s++ = c;
+ }
+ }
+ }
- // if (wa & 0x8000)
- if ((wa >> 16) != 0)
+ if (wa != 0)
{
*s++ = ' ';
- ConvertPosixAttribToString(s, wa >> 16);
+ ConvertUInt32ToHex8Digits(wa, s);
+ s += strlen(s);
+ }
+
+ *s = 0;
+
+ if (isPosix)
+ {
+ *s++ = ' ';
+ ConvertPosixAttribToString(s, posix);
}
}
-void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID propID, bool full) throw()
+
+void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &prop, PROPID propID, int level) throw()
{
*dest = 0;
if (prop.vt == VT_FILETIME)
{
- FILETIME localFileTime;
- if ((prop.filetime.dwHighDateTime == 0 &&
- prop.filetime.dwLowDateTime == 0) ||
- !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
+ const FILETIME &ft = prop.filetime;
+ if ((ft.dwHighDateTime == 0 &&
+ ft.dwLowDateTime == 0))
return;
- ConvertFileTimeToString(localFileTime, dest, true, full);
+ ConvertUtcFileTimeToString(prop.filetime, dest, level);
return;
}
@@ -158,7 +201,7 @@ void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID pr
ConvertPropVariantToShortString(prop, dest);
}
-void ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID propID, bool full)
+void ConvertPropertyToString2(UString &dest, const PROPVARIANT &prop, PROPID propID, int level)
{
if (prop.vt == VT_BSTR)
{
@@ -166,8 +209,8 @@ void ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID prop
return;
}
char temp[64];
- ConvertPropertyToShortString(temp, prop, propID, full);
- dest.SetFromAscii(temp);
+ ConvertPropertyToShortString2(temp, prop, propID, level);
+ dest = temp;
}
static inline unsigned GetHex(unsigned v)
@@ -181,7 +224,6 @@ static inline void AddHexToString(AString &res, unsigned v)
{
res += (char)GetHex(v >> 4);
res += (char)GetHex(v & 0xF);
- res += ' ';
}
/*
@@ -226,6 +268,14 @@ struct CSecID2Name
const char *sz;
};
+static int FindPairIndex(const CSecID2Name * pairs, unsigned num, UInt32 id)
+{
+ for (unsigned i = 0; i < num; i++)
+ if (pairs[i].n == id)
+ return i;
+ return -1;
+}
+
static const CSecID2Name sid_32_Names[] =
{
{ 544, "Administrators" },
@@ -316,22 +366,22 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
if (v0 == 32 && num == 2)
{
UInt32 v1 = Get32(p + 12);
- for (unsigned i = 0; i < ARRAY_SIZE(sid_32_Names); i++)
- if (sid_32_Names[i].n == v1)
- {
- s += sid_32_Names[i].sz;
- return;
- }
+ int index = FindPairIndex(sid_32_Names, ARRAY_SIZE(sid_32_Names), v1);
+ if (index >= 0)
+ {
+ s += sid_32_Names[(unsigned)index].sz;
+ return;
+ }
}
if (v0 == 21 && num == 5)
{
UInt32 v4 = Get32(p + 8 + 4 * 4);
- for (unsigned i = 0; i < ARRAY_SIZE(sid_21_Names); i++)
- if (sid_21_Names[i].n == v4)
- {
- s += sid_21_Names[i].sz;
- return;
- }
+ int index = FindPairIndex(sid_21_Names, ARRAY_SIZE(sid_21_Names), v4);
+ if (index >= 0)
+ {
+ s += sid_21_Names[(unsigned)index].sz;
+ return;
+ }
}
if (v0 == 80 && num == 6)
{
@@ -349,13 +399,9 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
}
}
- char sz[16];
s += "S-1-";
if (p[2] == 0 && p[3] == 0)
- {
- ConvertUInt32ToString(authority, sz);
- s += sz;
- }
+ s.Add_UInt32(authority);
else
{
s += "0x";
@@ -365,8 +411,7 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
for (UInt32 i = 0; i < num; i++)
{
s += '-';
- ConvertUInt32ToString(Get32(p + 8 + i * 4), sz);
- s += sz;
+ s.Add_UInt32(Get32(p + 8 + i * 4));
}
}
@@ -381,20 +426,13 @@ static void ParseOwner(AString &s, const Byte *p, UInt32 size, UInt32 pos)
ParseSid(s, p + pos, size - pos, sidSize);
}
-static void AddUInt32ToString(AString &s, UInt32 val)
-{
- char sz[16];
- ConvertUInt32ToString(val, sz);
- s += sz;
-}
-
static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName, UInt32 flags, UInt32 offset)
{
UInt32 control = Get16(p + 2);
if ((flags & control) == 0)
return;
UInt32 pos = Get32(p + offset);
- s += ' ';
+ s.Add_Space();
s += strName;
if (pos >= size)
return;
@@ -405,7 +443,7 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName
if (Get16(p) != 2) // revision
return;
UInt32 num = Get32(p + 4);
- AddUInt32ToString(s, num);
+ s.Add_UInt32(num);
/*
UInt32 aclSize = Get16(p + 2);
@@ -428,7 +466,7 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName
size -= 8;
UInt32 sidSize = 0;
- s += ' ';
+ s.Add_Space();
ParseSid(s, p, size, sidSize);
if (sidSize == 0)
return;
@@ -470,12 +508,12 @@ void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s)
return;
}
ParseOwner(s, data, size, Get32(data + 4));
- s += ' ';
+ s.Add_Space();
ParseOwner(s, data, size, Get32(data + 8));
ParseAcl(s, data, size, "s:", MY_SE_SACL_PRESENT, 12);
ParseAcl(s, data, size, "d:", MY_SE_DACL_PRESENT, 16);
- s += ' ';
- AddUInt32ToString(s, size);
+ s.Add_Space();
+ s.Add_UInt32(size);
// s += '\n';
// s += Data_To_Hex(data, size);
}
@@ -529,18 +567,45 @@ bool CheckNtSecure(const Byte *data, UInt32 size) throw()
#endif
+
+
+// IO_REPARSE_TAG_*
+
+static const CSecID2Name k_ReparseTags[] =
+{
+ { 0xA0000003, "MOUNT_POINT" },
+ { 0xC0000004, "HSM" },
+ { 0x80000005, "DRIVE_EXTENDER" },
+ { 0x80000006, "HSM2" },
+ { 0x80000007, "SIS" },
+ { 0x80000008, "WIM" },
+ { 0x80000009, "CSV" },
+ { 0x8000000A, "DFS" },
+ { 0x8000000B, "FILTER_MANAGER" },
+ { 0xA000000C, "SYMLINK" },
+ { 0xA0000010, "IIS_CACHE" },
+ { 0x80000012, "DFSR" },
+ { 0x80000013, "DEDUP" },
+ { 0xC0000014, "APPXSTRM" },
+ { 0x80000014, "NFS" },
+ { 0x80000015, "FILE_PLACEHOLDER" },
+ { 0x80000016, "DFM" },
+ { 0x80000017, "WOF" }
+};
+
bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
{
s.Empty();
NFile::CReparseAttr attr;
- if (attr.Parse(data, size))
+ DWORD errorCode = 0;
+ if (attr.Parse(data, size, errorCode))
{
if (!attr.IsSymLink())
- s.AddAscii("Junction: ");
+ s += "Junction: ";
s += attr.GetPath();
if (!attr.IsOkNamePair())
{
- s.AddAscii(" : ");
+ s += " : ";
s += attr.PrintName;
}
return true;
@@ -555,19 +620,48 @@ bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
if (Get16(data + 6) != 0) // padding
return false;
- char hex[16];
- ConvertUInt32ToHex8Digits(tag, hex);
- s.AddAscii(hex);
- s.Add_Space();
+ /*
+ #define _my_IO_REPARSE_TAG_DEDUP (0x80000013L)
+ if (tag == _my_IO_REPARSE_TAG_DEDUP)
+ {
+ }
+ */
- data += 8;
+ {
+ int index = FindPairIndex(k_ReparseTags, ARRAY_SIZE(k_ReparseTags), tag);
+ if (index >= 0)
+ s += k_ReparseTags[(unsigned)index].sz;
+ else
+ {
+ s += "REPARSE:";
+ char hex[16];
+ ConvertUInt32ToHex8Digits(tag, hex);
+ s += hex;
+ }
+ }
+
+ s += ":";
+ s.Add_UInt32(len);
- for (UInt32 i = 0; i < len; i++)
+ if (len != 0)
{
- unsigned b = ((const Byte *)data)[i];
- s += (wchar_t)GetHex((b >> 4) & 0xF);
- s += (wchar_t)GetHex(b & 0xF);
+ s.Add_Space();
+
+ data += 8;
+
+ for (UInt32 i = 0; i < len; i++)
+ {
+ if (i >= 8)
+ {
+ s += "...";
+ break;
+ }
+ unsigned b = data[i];
+ s += (char)GetHex((b >> 4) & 0xF);
+ s += (char)GetHex(b & 0xF);
+ }
}
+
return true;
}
diff --git a/CPP/7zip/UI/Common/PropIDUtils.h b/CPP/7zip/UI/Common/PropIDUtils.h
index fef4b7d..e94e6d7 100644
--- a/CPP/7zip/UI/Common/PropIDUtils.h
+++ b/CPP/7zip/UI/Common/PropIDUtils.h
@@ -6,8 +6,8 @@
#include "../../../Common/MyString.h"
// provide at least 64 bytes for buffer including zero-end
-void ConvertPropertyToShortString(char *dest, const PROPVARIANT &propVariant, PROPID propID, bool full = true) throw();
-void ConvertPropertyToString(UString &dest, const PROPVARIANT &propVariant, PROPID propID, bool full = true);
+void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &propVariant, PROPID propID, int level = 0) throw();
+void ConvertPropertyToString2(UString &dest, const PROPVARIANT &propVariant, PROPID propID, int level = 0);
bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s);
void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s);
diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp
index 57723e4..fc1eede 100644
--- a/CPP/7zip/UI/Common/Update.cpp
+++ b/CPP/7zip/UI/Common/Update.cpp
@@ -4,7 +4,6 @@
#include "Update.h"
-#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/DLL.h"
@@ -30,16 +29,19 @@
#include "TempFiles.h"
#include "UpdateCallback.h"
-static const char *kUpdateIsNotSupoorted =
+static const char * const kUpdateIsNotSupoorted =
"update operations are not supported for this archive";
+static const char * const kUpdateIsNotSupoorted_MultiVol =
+ "Updating for multivolume archives is not implemented";
+
using namespace NWindows;
using namespace NCOM;
using namespace NFile;
using namespace NDir;
using namespace NName;
-static CFSTR kTempFolderPrefix = FTEXT("7zE");
+static CFSTR const kTempFolderPrefix = FTEXT("7zE");
void CUpdateErrorInfo::SetFromLastError(const char *message)
@@ -60,7 +62,8 @@ static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path)
NFind::CFileInfo fileInfo;
FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
{
- NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK);
+ NFind::CEnumerator enumerator;
+ enumerator.SetDirPrefix(pathPrefix);
while (enumerator.Next(fileInfo))
{
if (fileInfo.IsDir())
@@ -156,7 +159,7 @@ bool COutMultiVolStream::SetMTime(const FILETIME *mTime)
STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if (processedSize != NULL)
+ if (processedSize)
*processedSize = 0;
while (size > 0)
{
@@ -164,9 +167,8 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
{
CAltStreamInfo altStream;
- FChar temp[16];
- ConvertUInt32ToString(_streamIndex + 1, temp);
- FString name = temp;
+ FString name;
+ name.Add_UInt32(_streamIndex + 1);
while (name.Len() < 3)
name.InsertAtFront(FTEXT('0'));
name.Insert(0, Prefix);
@@ -218,7 +220,7 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
_length = _absPos;
if (_offsetPos > altStream.RealSize)
altStream.RealSize = _offsetPos;
- if (processedSize != NULL)
+ if (processedSize)
*processedSize += realProcessed;
if (altStream.Pos == volSize)
{
@@ -243,7 +245,7 @@ STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *n
case STREAM_SEEK_END: _absPos = _length + offset; break;
}
_offsetPos = _absPos;
- if (newPosition != NULL)
+ if (newPosition)
*newPosition = _absPos;
_streamIndex = 0;
return S_OK;
@@ -316,7 +318,7 @@ UString CArchivePath::GetFinalPath() const
UString path = GetPathWithoutExt();
if (!BaseExtension.IsEmpty())
{
- path += L'.';
+ path += '.';
path += BaseExtension;
}
return path;
@@ -327,7 +329,7 @@ UString CArchivePath::GetFinalVolPath() const
UString path = GetPathWithoutExt();
if (!BaseExtension.IsEmpty())
{
- path += L'.';
+ path += '.';
path += VolExtension;
}
return path;
@@ -339,17 +341,17 @@ FString CArchivePath::GetTempPath() const
path += us2fs(Name);
if (!BaseExtension.IsEmpty())
{
- path += FTEXT('.');
+ path += '.';
path += us2fs(BaseExtension);
}
- path.AddAscii(".tmp");
+ path += ".tmp";
path += TempPostfix;
return path;
}
-static const wchar_t *kDefaultArcType = L"7z";
-static const wchar_t *kDefaultArcExt = L"7z";
-static const char *kSFXExtension =
+static const char * const kDefaultArcType = "7z";
+static const char * const kDefaultArcExt = "7z";
+static const char * const kSFXExtension =
#ifdef _WIN32
"exe";
#else
@@ -398,7 +400,7 @@ bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath)
}
UString ext = typeExt;
if (SfxMode)
- ext.SetFromAscii(kSFXExtension);
+ ext = kSFXExtension;
ArchivePath.BaseExtension = ext;
ArchivePath.VolExtension = typeExt;
ArchivePath.ParseFromPath(arcPath, ArcNameMode);
@@ -412,19 +414,43 @@ bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath)
return true;
}
+
struct CUpdateProduceCallbackImp: public IUpdateProduceCallback
{
const CObjectVector<CArcItem> *_arcItems;
IUpdateCallbackUI *_callback;
+ CDirItemsStat *_stat;
+
+ CUpdateProduceCallbackImp(
+ const CObjectVector<CArcItem> *a,
+ CDirItemsStat *stat,
+ IUpdateCallbackUI *callback):
+ _arcItems(a),
+ _stat(stat),
+ _callback(callback) {}
- CUpdateProduceCallbackImp(const CObjectVector<CArcItem> *a,
- IUpdateCallbackUI *callback): _arcItems(a), _callback(callback) {}
virtual HRESULT ShowDeleteFile(unsigned arcIndex);
};
+
HRESULT CUpdateProduceCallbackImp::ShowDeleteFile(unsigned arcIndex)
{
const CArcItem &ai = (*_arcItems)[arcIndex];
+ {
+ CDirItemsStat &stat = *_stat;
+ if (ai.IsDir)
+ stat.NumDirs++;
+ else if (ai.IsAltStream)
+ {
+ stat.NumAltStreams++;
+ stat.AltStreamsSize += ai.Size;
+ }
+ else
+ {
+ stat.NumFiles++;
+ stat.FilesSize += ai.Size;
+ }
+ }
return _callback->ShowDeleteFile(ai.Name, ai.IsDir);
}
@@ -562,6 +588,8 @@ static HRESULT Compress(
UStringVector newNames;
+ CArcToDoStat stat2;
+
if (options.RenamePairs.Size() != 0)
{
FOR_VECTOR (i, arcItems)
@@ -595,7 +623,7 @@ static HRESULT Compress(
if (rp.GetNewPath(false, mainName, dest))
{
needRename = true;
- dest += L':';
+ dest += ':';
dest += ai.Name.Ptr(colonPos + 1);
break;
}
@@ -620,23 +648,94 @@ static HRESULT Compress(
{
CRecordVector<CUpdatePair> updatePairs;
GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!!
- CUpdateProduceCallbackImp upCallback(&arcItems, callback);
+ CUpdateProduceCallbackImp upCallback(&arcItems, &stat2.DeleteData, callback);
UpdateProduce(updatePairs, actionSet, updatePairs2, isUpdatingItself ? &upCallback : NULL);
}
{
- UInt32 numItems = 0;
FOR_VECTOR (i, updatePairs2)
- if (updatePairs2[i].NewData)
- numItems++;
- RINOK(callback->SetNumItems(numItems));
+ {
+ const CUpdatePair2 &up = updatePairs2[i];
+
+ // 17.01: anti-item is (up.NewData && (p.UseArcProps in most cases))
+
+ if (up.NewData && !up.UseArcProps)
+ {
+ if (up.ExistOnDisk())
+ {
+ CDirItemsStat2 &stat = stat2.NewData;
+ const CDirItem &di = dirItems.Items[up.DirIndex];
+ if (di.IsDir())
+ {
+ if (up.IsAnti)
+ stat.Anti_NumDirs++;
+ else
+ stat.NumDirs++;
+ }
+ else if (di.IsAltStream)
+ {
+ if (up.IsAnti)
+ stat.Anti_NumAltStreams++;
+ else
+ {
+ stat.NumAltStreams++;
+ stat.AltStreamsSize += di.Size;
+ }
+ }
+ else
+ {
+ if (up.IsAnti)
+ stat.Anti_NumFiles++;
+ else
+ {
+ stat.NumFiles++;
+ stat.FilesSize += di.Size;
+ }
+ }
+ }
+ }
+ else if (up.ArcIndex >= 0)
+ {
+ CDirItemsStat2 &stat = *(up.NewData ? &stat2.NewData : &stat2.OldData);
+ const CArcItem &ai = arcItems[up.ArcIndex];
+ if (ai.IsDir)
+ {
+ if (up.IsAnti)
+ stat.Anti_NumDirs++;
+ else
+ stat.NumDirs++;
+ }
+ else if (ai.IsAltStream)
+ {
+ if (up.IsAnti)
+ stat.Anti_NumAltStreams++;
+ else
+ {
+ stat.NumAltStreams++;
+ stat.AltStreamsSize += ai.Size;
+ }
+ }
+ else
+ {
+ if (up.IsAnti)
+ stat.Anti_NumFiles++;
+ else
+ {
+ stat.NumFiles++;
+ stat.FilesSize += ai.Size;
+ }
+ }
+ }
+ }
+ RINOK(callback->SetNumItems(stat2));
}
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
updateCallbackSpec->ShareForWrite = options.OpenShareForWrite;
+ updateCallbackSpec->StopAfterOpenError = options.StopAfterOpenError;
updateCallbackSpec->StdInMode = options.StdInMode;
updateCallbackSpec->Callback = callback;
@@ -698,9 +797,8 @@ static HRESULT Compress(
{
if (i > 0)
{
- FChar s[16];
- ConvertUInt32ToString(i, s);
- archivePath.TempPostfix = s;
+ archivePath.TempPostfix.Empty();
+ archivePath.TempPostfix.Add_UInt32(i);
}
realPath = archivePath.GetTempPath();
}
@@ -734,7 +832,7 @@ static HRESULT Compress(
outStream = outSeekStream;
volStreamSpec->Sizes = options.VolumesSizes;
volStreamSpec->Prefix = us2fs(archivePath.GetFinalVolPath());
- volStreamSpec->Prefix += FTEXT('.');
+ volStreamSpec->Prefix += '.';
volStreamSpec->TempFiles = &tempFiles;
volStreamSpec->Init();
@@ -742,7 +840,7 @@ static HRESULT Compress(
updateCallbackSpec->VolumesSizes = volumesSizes;
updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name;
if (!archivePath.VolExtension.IsEmpty())
- updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension;
+ updateCallbackSpec->VolExt = UString('.') + archivePath.VolExtension;
*/
}
@@ -948,36 +1046,6 @@ static HRESULT EnumerateInArchiveItems(
#endif
-struct CRefSortPair
-{
- unsigned Len;
- unsigned Index;
-};
-
-#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
-
-static int CompareRefSortPair(const CRefSortPair *a1, const CRefSortPair *a2, void *)
-{
- RINOZ(-MyCompare(a1->Len, a2->Len));
- return MyCompare(a1->Index, a2->Index);
-}
-
-static unsigned GetNumSlashes(const FChar *s)
-{
- for (unsigned numSlashes = 0;;)
- {
- FChar c = *s++;
- if (c == 0)
- return numSlashes;
- if (IS_PATH_SEPAR(c))
- numSlashes++;
- }
-}
-
-#ifdef _WIN32
-void ConvertToLongNames(NWildcard::CCensor &censor);
-#endif
-
HRESULT UpdateArchive(
CCodecs *codecs,
const CObjectVector<COpenType> &types,
@@ -1025,7 +1093,7 @@ HRESULT UpdateArchive(
if (options.SfxMode)
{
CProperty property;
- property.Name.SetFromAscii("rsfx");
+ property.Name = "rsfx";
options.MethodMode.Properties.Add(property);
if (options.SfxModule.IsEmpty())
{
@@ -1058,7 +1126,15 @@ HRESULT UpdateArchive(
!options.SetArcPath(codecs, cmdArcPath2))
return E_NOTIMPL;
}
- const UString arcPath = options.ArchivePath.GetFinalPath();
+
+ UString arcPath = options.ArchivePath.GetFinalPath();
+
+ if (!options.VolumesSizes.IsEmpty())
+ {
+ arcPath = options.ArchivePath.GetFinalVolPath();
+ arcPath += '.';
+ arcPath += "001";
+ }
if (cmdArcPath2.IsEmpty())
{
@@ -1084,8 +1160,23 @@ HRESULT UpdateArchive(
throw "there is no such archive";
if (fi.IsDevice)
return E_NOTIMPL;
+
+ if (!options.StdOutMode && options.UpdateArchiveItself)
+ if (fi.IsReadOnly())
+ {
+ errorInfo.SystemError = ERROR_ACCESS_DENIED;
+ errorInfo.Message = "The file is read-only";
+ errorInfo.FileNames.Add(arcPath);
+ return errorInfo.Get_HRESULT_Error();
+ }
+
if (options.VolumesSizes.Size() > 0)
+ {
+ errorInfo.FileNames.Add(us2fs(arcPath));
+ errorInfo.SystemError = (DWORD)E_NOTIMPL;
+ errorInfo.Message = kUpdateIsNotSupoorted_MultiVol;
return E_NOTIMPL;
+ }
CObjectVector<COpenType> types2;
// change it.
if (options.MethodMode.Type_Defined)
@@ -1122,7 +1213,7 @@ HRESULT UpdateArchive(
if (arcLink.VolumePaths.Size() > 1)
{
errorInfo.SystemError = (DWORD)E_NOTIMPL;
- errorInfo.Message = "Updating for multivolume archives is not implemented";
+ errorInfo.Message = kUpdateIsNotSupoorted_MultiVol;
return E_NOTIMPL;
}
@@ -1147,7 +1238,7 @@ HRESULT UpdateArchive(
if (options.MethodMode.Type.FormatIndex < 0)
{
- options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArcType);
+ options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType((UString)kDefaultArcType);
if (options.MethodMode.Type.FormatIndex < 0)
return E_NOTIMPL;
}
@@ -1218,7 +1309,7 @@ HRESULT UpdateArchive(
{
NFind::CFileInfo fi;
FString prefix = us2fs(censor.Pairs[0].Prefix);
- prefix += FTEXT('.');
+ prefix += '.';
// UString prefix = censor.Pairs[0].Prefix;
/*
if (prefix.Back() == WCHAR_PATH_SEPARATOR)
@@ -1353,7 +1444,7 @@ HRESULT UpdateArchive(
if (options.StdOutMode)
{
- name.SetFromAscii("stdout");
+ name = "stdout";
isUpdating = thereIsInArchive;
}
else
@@ -1399,9 +1490,13 @@ HRESULT UpdateArchive(
CArchivePath &ap = options.Commands[0].ArchivePath;
const FString &tempPath = ap.GetTempPath();
+ // DWORD attrib = 0;
if (thereIsInArchive)
+ {
+ // attrib = NFind::GetFileAttrib(us2fs(arcPath));
if (!DeleteFileAlways(us2fs(arcPath)))
return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath));
+ }
if (!MyMoveFile(tempPath, us2fs(arcPath)))
{
@@ -1409,6 +1504,15 @@ HRESULT UpdateArchive(
errorInfo.FileNames.Add(us2fs(arcPath));
return errorInfo.Get_HRESULT_Error();
}
+
+ /*
+ if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY))
+ {
+ DWORD attrib2 = NFind::GetFileAttrib(us2fs(arcPath));
+ if (attrib2 != INVALID_FILE_ATTRIBUTES)
+ NDir::SetFileAttrib(us2fs(arcPath), attrib2 | FILE_ATTRIBUTE_READONLY);
+ }
+ */
}
catch(...)
{
@@ -1461,10 +1565,10 @@ HRESULT UpdateArchive(
for (i = 0; i < fullPaths.Size(); i++)
{
- UString arcPath2 = fs2us(fullPaths[i]);
- UString fileName = ExtractFileNameFromPath(arcPath2);
- AString path = GetAnsiString(arcPath2);
- AString name = GetAnsiString(fileName);
+ const UString arcPath2 = fs2us(fullPaths[i]);
+ const UString fileName = ExtractFileNameFromPath(arcPath2);
+ const AString path (GetAnsiString(arcPath2));
+ const AString name (GetAnsiString(fileName));
// Warning!!! MAPISendDocuments function changes Current directory
// fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
@@ -1479,7 +1583,7 @@ HRESULT UpdateArchive(
m.nFileCount = 1;
m.lpFiles = &f;
- const AString addr = GetAnsiString(options.EMailAddress);
+ const AString addr (GetAnsiString(options.EMailAddress));
MapiRecipDesc rec;
if (!addr.IsEmpty())
{
@@ -1498,7 +1602,7 @@ HRESULT UpdateArchive(
if (options.DeleteAfterCompressing)
{
- CRecordVector<CRefSortPair> pairs;
+ CRecordVector<CDirPathSortPair> pairs;
FStringVector foldersNames;
unsigned i;
@@ -1506,20 +1610,30 @@ HRESULT UpdateArchive(
for (i = 0; i < dirItems.Items.Size(); i++)
{
const CDirItem &dirItem = dirItems.Items[i];
- FString phyPath = dirItems.GetPhyPath(i);
+ const FString phyPath = dirItems.GetPhyPath(i);
if (dirItem.IsDir())
{
- CRefSortPair pair;
+ CDirPathSortPair pair;
pair.Index = i;
- pair.Len = GetNumSlashes(phyPath);
+ pair.SetNumSlashes(phyPath);
pairs.Add(pair);
}
else
{
if (processedItems[i] != 0 || dirItem.Size == 0)
{
- RINOK(callback->DeletingAfterArchiving(phyPath, false));
- DeleteFileAlways(phyPath);
+ NFind::CFileInfo fileInfo;
+ if (fileInfo.Find(phyPath))
+ {
+ // maybe we must exclude also files with archive name: "a a.7z * -sdel"
+ if (fileInfo.Size == dirItem.Size
+ && CompareFileTime(&fileInfo.MTime, &dirItem.MTime) == 0
+ && CompareFileTime(&fileInfo.CTime, &dirItem.CTime) == 0)
+ {
+ RINOK(callback->DeletingAfterArchiving(phyPath, false));
+ DeleteFileAlways(phyPath);
+ }
+ }
}
else
{
@@ -1534,11 +1648,11 @@ HRESULT UpdateArchive(
}
}
- pairs.Sort(CompareRefSortPair, NULL);
+ pairs.Sort2();
for (i = 0; i < pairs.Size(); i++)
{
- FString phyPath = dirItems.GetPhyPath(pairs[i].Index);
+ const FString phyPath = dirItems.GetPhyPath(pairs[i].Index);
if (NFind::DoesDirExist(phyPath))
{
RINOK(callback->DeletingAfterArchiving(phyPath, true));
diff --git a/CPP/7zip/UI/Common/Update.h b/CPP/7zip/UI/Common/Update.h
index 4e3fb2a..45b02d7 100644
--- a/CPP/7zip/UI/Common/Update.h
+++ b/CPP/7zip/UI/Common/Update.h
@@ -92,6 +92,7 @@ struct CUpdateOptions
FString SfxModule;
bool OpenShareForWrite;
+ bool StopAfterOpenError;
bool StdInMode;
UString StdInFileName;
@@ -127,6 +128,7 @@ struct CUpdateOptions
EMailMode(false),
EMailRemoveAfter(false),
OpenShareForWrite(false),
+ StopAfterOpenError(false),
ArcNameMode(k_ArcNameMode_Smart),
PathMode(NWildcard::k_RelatPath),
diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp
index ab36f82..9c165fe 100644
--- a/CPP/7zip/UI/Common/UpdateCallback.cpp
+++ b/CPP/7zip/UI/Common/UpdateCallback.cpp
@@ -51,8 +51,11 @@ CArchiveUpdateCallback::CArchiveUpdateCallback():
ArcItems(NULL),
UpdatePairs(NULL),
NewNames(NULL),
+ CommentIndex(-1),
+ Comment(NULL),
ShareForWrite(false),
+ StopAfterOpenError(false),
StdInMode(false),
KeepOriginalItemNames(false),
@@ -300,7 +303,7 @@ static UString GetRelativePath(const UString &to, const UString &from)
unsigned k;
for (k = i + 1; k < partsFrom.Size(); k++)
- s += L".." WSTRING_PATH_SEPARATOR;
+ s += ".." STRING_PATH_SEPARATOR;
for (k = i; k < partsTo.Size(); k++)
{
@@ -344,7 +347,8 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
// if (di.IsDir())
{
CReparseAttr attr;
- if (attr.Parse(di.ReparseData, di.ReparseData.Size()))
+ DWORD errorCode = 0;
+ if (attr.Parse(di.ReparseData, di.ReparseData.Size(), errorCode))
{
UString simpleName = attr.GetPath();
if (attr.IsRelative())
@@ -396,6 +400,11 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
}
else if (propID == kpidPath && up.NewNameIndex >= 0)
prop = (*NewNames)[up.NewNameIndex];
+ else if (propID == kpidComment
+ && CommentIndex >= 0
+ && (unsigned)CommentIndex == index
+ && Comment)
+ prop = *Comment;
else if (propID == kpidShortName && up.NewNameIndex >= 0 && up.IsMainRenameItem)
{
// we can generate new ShortName here;
@@ -505,7 +514,12 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
#endif
if (!inStreamSpec->OpenShared(path, ShareForWrite))
{
- return Callback->OpenFileError(path, ::GetLastError());
+ DWORD error = ::GetLastError();
+ HRESULT hres = Callback->OpenFileError(path, error);
+ if (StopAfterOpenError)
+ if (hres == S_OK || hres == S_FALSE)
+ return HRESULT_FROM_WIN32(error);
+ return hres;
}
if (StoreHardLinks)
@@ -690,13 +704,13 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
{
COM_TRY_BEGIN
- FChar temp[16];
+ char temp[16];
ConvertUInt32ToString(index + 1, temp);
- FString res = temp;
+ FString res (temp);
while (res.Len() < 2)
res.InsertAtFront(FTEXT('0'));
FString fileName = VolName;
- fileName += FTEXT('.');
+ fileName += '.';
fileName += res;
fileName += VolExt;
COutFileStream *streamSpec = new COutFileStream;
diff --git a/CPP/7zip/UI/Common/UpdateCallback.h b/CPP/7zip/UI/Common/UpdateCallback.h
index 81f5ed6..1b5d1ee 100644
--- a/CPP/7zip/UI/Common/UpdateCallback.h
+++ b/CPP/7zip/UI/Common/UpdateCallback.h
@@ -15,6 +15,18 @@
#include "OpenArchive.h"
+struct CArcToDoStat
+{
+ CDirItemsStat2 NewData;
+ CDirItemsStat2 OldData;
+ CDirItemsStat2 DeleteData;
+
+ UInt64 Get_NumDataItems_Total() const
+ {
+ return NewData.Get_NumDataItems2() + OldData.Get_NumDataItems2();
+ }
+};
+
#define INTERFACE_IUpdateCallbackUI(x) \
virtual HRESULT WriteSfx(const wchar_t *name, UInt64 size) x; \
virtual HRESULT SetTotal(UInt64 size) x; \
@@ -22,7 +34,7 @@
virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) x; \
virtual HRESULT CheckBreak() x; \
/* virtual HRESULT Finalize() x; */ \
- virtual HRESULT SetNumItems(UInt64 numItems) x; \
+ virtual HRESULT SetNumItems(const CArcToDoStat &stat) x; \
virtual HRESULT GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode) x; \
virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x; \
virtual HRESULT ReadingFileError(const FString &path, DWORD systemError) x; \
@@ -120,8 +132,11 @@ public:
const CObjectVector<CArcItem> *ArcItems;
const CRecordVector<CUpdatePair2> *UpdatePairs;
const UStringVector *NewNames;
+ int CommentIndex;
+ const UString *Comment;
bool ShareForWrite;
+ bool StopAfterOpenError;
bool StdInMode;
bool KeepOriginalItemNames;
diff --git a/CPP/7zip/UI/Common/UpdatePair.cpp b/CPP/7zip/UI/Common/UpdatePair.cpp
index 10864b2..5153671 100644
--- a/CPP/7zip/UI/Common/UpdatePair.cpp
+++ b/CPP/7zip/UI/Common/UpdatePair.cpp
@@ -38,14 +38,13 @@ static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time
throw 4191618;
}
-static const char *k_Duplicate_inArc_Message = "Duplicate filename in archive:";
-static const char *k_Duplicate_inDir_Message = "Duplicate filename on disk:";
-static const char *k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):";
+static const char * const k_Duplicate_inArc_Message = "Duplicate filename in archive:";
+static const char * const k_Duplicate_inDir_Message = "Duplicate filename on disk:";
+static const char * const k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):";
static void ThrowError(const char *message, const UString &s1, const UString &s2)
{
- UString m;
- m.SetFromAscii(message);
+ UString m (message);
m.Add_LF(); m += s1;
m.Add_LF(); m += s2;
throw m;
diff --git a/CPP/7zip/UI/Common/UpdateProduce.cpp b/CPP/7zip/UI/Common/UpdateProduce.cpp
index 4f28a1e..c025ac4 100644
--- a/CPP/7zip/UI/Common/UpdateProduce.cpp
+++ b/CPP/7zip/UI/Common/UpdateProduce.cpp
@@ -6,7 +6,7 @@
using namespace NUpdateArchive;
-static const char *kUpdateActionSetCollision = "Internal collision in update action set";
+static const char * const kUpdateActionSetCollision = "Internal collision in update action set";
void UpdateProduce(
const CRecordVector<CUpdatePair> &updatePairs,
diff --git a/CPP/7zip/UI/Common/ZipRegistry.h b/CPP/7zip/UI/Common/ZipRegistry.h
index d349fae..4c16b61 100644
--- a/CPP/7zip/UI/Common/ZipRegistry.h
+++ b/CPP/7zip/UI/Common/ZipRegistry.h
@@ -48,9 +48,14 @@ namespace NCompression
UString Options;
UString EncryptionMethod;
+ void Reset_BlockLogSize()
+ {
+ BlockLogSize = (UInt32)(Int32)-1;
+ }
+
void ResetForLevelChange()
{
- BlockLogSize = NumThreads = Level = Dictionary = Order = UInt32(-1);
+ BlockLogSize = NumThreads = Level = Dictionary = Order = (UInt32)(Int32)-1;
Method.Empty();
// Options.Empty();
// EncryptionMethod.Empty();
diff --git a/CPP/7zip/UI/Console/Console.manifest b/CPP/7zip/UI/Console/Console.manifest
new file mode 100644
index 0000000..77ecaad
--- /dev/null
+++ b/CPP/7zip/UI/Console/Console.manifest
@@ -0,0 +1,13 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7z" type="win32"></assemblyIdentity>
+<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+<security><requestedPrivileges><requestedExecutionLevel level="asInvoker" uiAccess="false">
+</requestedExecutionLevel></requestedPrivileges></security></trustInfo>
+<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application>
+<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+</application></compatibility>
+</assembly> \ No newline at end of file
diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
index cc82770..bdf9549 100644
--- a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
@@ -32,7 +32,7 @@ static HRESULT CheckBreak2()
return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK;
}
-static const char *kError = "ERROR: ";
+static const char * const kError = "ERROR: ";
void CExtractScanConsole::StartScanning()
@@ -60,8 +60,9 @@ HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError)
if (_se)
{
- *_se << endl << kError << NError::MyFormatMessage(systemError) << endl <<
- fs2us(path) << endl << endl;
+ *_se << endl << kError << NError::MyFormatMessage(systemError) << endl;
+ _se->NormalizePrint_UString(fs2us(path));
+ *_se << endl << endl;
_se->Flush();
}
return HRESULT_FROM_WIN32(systemError);
@@ -95,6 +96,16 @@ void PrintSize_bytes_Smart(AString &s, UInt64 val)
s += ')';
}
+void PrintSize_bytes_Smart_comma(AString &s, UInt64 val)
+{
+ if (val == (UInt64)(Int64)-1)
+ return;
+ s += ", ";
+ PrintSize_bytes_Smart(s, val);
+}
+
+
+
void Print_DirItemsStat(AString &s, const CDirItemsStat &st)
{
if (st.NumDirs != 0)
@@ -103,17 +114,48 @@ void Print_DirItemsStat(AString &s, const CDirItemsStat &st)
s += ", ";
}
Print_UInt64_and_String(s, st.NumFiles, st.NumFiles == 1 ? "file" : "files");
- s += ", ";
- PrintSize_bytes_Smart(s, st.FilesSize);
+ PrintSize_bytes_Smart_comma(s, st.FilesSize);
if (st.NumAltStreams != 0)
{
s.Add_LF();
Print_UInt64_and_String(s, st.NumAltStreams, "alternate streams");
- s += ", ";
- PrintSize_bytes_Smart(s, st.AltStreamsSize);
+ PrintSize_bytes_Smart_comma(s, st.AltStreamsSize);
}
}
+
+void Print_DirItemsStat2(AString &s, const CDirItemsStat2 &st)
+{
+ Print_DirItemsStat(s, (CDirItemsStat &)st);
+ bool needLF = true;
+ if (st.Anti_NumDirs != 0)
+ {
+ if (needLF)
+ s.Add_LF();
+ needLF = false;
+ Print_UInt64_and_String(s, st.Anti_NumDirs, st.Anti_NumDirs == 1 ? "anti-folder" : "anti-folders");
+ }
+ if (st.Anti_NumFiles != 0)
+ {
+ if (needLF)
+ s.Add_LF();
+ else
+ s += ", ";
+ needLF = false;
+ Print_UInt64_and_String(s, st.Anti_NumFiles, st.Anti_NumFiles == 1 ? "anti-file" : "anti-files");
+ }
+ if (st.Anti_NumAltStreams != 0)
+ {
+ if (needLF)
+ s.Add_LF();
+ else
+ s += ", ";
+ needLF = false;
+ Print_UInt64_and_String(s, st.Anti_NumAltStreams, "anti-alternate-streams");
+ }
+}
+
+
void CExtractScanConsole::PrintStat(const CDirItemsStat &st)
{
if (_so)
@@ -138,33 +180,33 @@ static NSynchronization::CCriticalSection g_CriticalSection;
#endif
-static const char *kTestString = "T";
-static const char *kExtractString = "-";
-static const char *kSkipString = ".";
+static const char * const kTestString = "T";
+static const char * const kExtractString = "-";
+static const char * const kSkipString = ".";
-// static const char *kCantAutoRename = "can not create file with auto name\n";
-// static const char *kCantRenameFile = "can not rename existing file\n";
-// static const char *kCantDeleteOutputFile = "can not delete output file ";
+// static const char * const kCantAutoRename = "can not create file with auto name\n";
+// static const char * const kCantRenameFile = "can not rename existing file\n";
+// static const char * const kCantDeleteOutputFile = "can not delete output file ";
-static const char *kMemoryExceptionMessage = "Can't allocate required memory!";
+static const char * const kMemoryExceptionMessage = "Can't allocate required memory!";
-static const char *kExtracting = "Extracting archive: ";
-static const char *kTesting = "Testing archive: ";
+static const char * const kExtracting = "Extracting archive: ";
+static const char * const kTesting = "Testing archive: ";
-static const char *kEverythingIsOk = "Everything is Ok";
-static const char *kNoFiles = "No files to process";
+static const char * const kEverythingIsOk = "Everything is Ok";
+static const char * const kNoFiles = "No files to process";
-static const char *kUnsupportedMethod = "Unsupported Method";
-static const char *kCrcFailed = "CRC Failed";
-static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?";
-static const char *kDataError = "Data Error";
-static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?";
-static const char *kUnavailableData = "Unavailable data";
-static const char *kUnexpectedEnd = "Unexpected end of data";
-static const char *kDataAfterEnd = "There are some data after the end of the payload data";
-static const char *kIsNotArc = "Is not archive";
-static const char *kHeadersError = "Headers Error";
-static const char *kWrongPassword = "Wrong password";
+static const char * const kUnsupportedMethod = "Unsupported Method";
+static const char * const kCrcFailed = "CRC Failed";
+static const char * const kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?";
+static const char * const kDataError = "Data Error";
+static const char * const kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?";
+static const char * const kUnavailableData = "Unavailable data";
+static const char * const kUnexpectedEnd = "Unexpected end of data";
+static const char * const kDataAfterEnd = "There are some data after the end of the payload data";
+static const char * const kIsNotArc = "Is not archive";
+static const char * const kHeadersError = "Headers Error";
+static const char * const kWrongPassword = "Wrong password";
static const char * const k_ErrorFlagsMessages[] =
{
@@ -206,12 +248,14 @@ STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue)
return CheckBreak2();
}
-static const char *kTab = " ";
+static const char * const kTab = " ";
static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size)
{
- *_so << kTab << "Path: " << path << endl;
- if (size)
+ *_so << kTab << "Path: ";
+ _so->NormalizePrint_wstr(path);
+ *_so << endl;
+ if (size && *size != (UInt64)(Int64)-1)
{
AString s;
PrintSize_bytes_Smart(s, *size);
@@ -220,10 +264,8 @@ static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIM
if (ft)
{
char temp[64];
- FILETIME locTime;
- if (FileTimeToLocalFileTime(ft, &locTime))
- if (ConvertFileTimeToString(locTime, temp, true, true))
- *_so << kTab << "Modified: " << temp << endl;
+ if (ConvertUtcFileTimeToString(*ft, temp, kTimestampPrintLevel_SEC))
+ *_so << kTab << "Modified: " << temp << endl;
}
}
@@ -256,6 +298,8 @@ STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
case NUserAnswerMode::kYesAll: *answer = NOverwriteAnswer::kYesToAll; break;
case NUserAnswerMode::kYes: *answer = NOverwriteAnswer::kYes; break;
case NUserAnswerMode::kAutoRenameAll: *answer = NOverwriteAnswer::kAutoRename; break;
+ case NUserAnswerMode::kEof: return E_ABORT;
+ case NUserAnswerMode::kError: return E_FAIL;
default: return E_FAIL;
}
@@ -299,7 +343,10 @@ STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3
_tempU.Empty();
if (name)
+ {
_tempU = name;
+ _so->Normalize_UString(_tempU);
+ }
_so->PrintUString(_tempU, _tempA);
if (position)
*_so << " <" << *position << ">";
@@ -388,10 +435,8 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest)
dest += s;
else
{
- char temp[16];
- ConvertUInt32ToString(opRes, temp);
dest += "Error #";
- dest += temp;
+ dest.Add_UInt32(opRes);
}
}
@@ -422,7 +467,10 @@ STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encr
*_se << s;
if (!_currentName.IsEmpty())
- *_se << " : " << _currentName;
+ {
+ *_se << " : ";
+ _se->NormalizePrint_UString(_currentName);
+ }
*_se << endl;
_se->Flush();
}
@@ -474,7 +522,11 @@ HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name, bool testMode)
ClosePercents_for_so();
if (_so)
- *_so << endl << (testMode ? kTesting : kExtracting) << name << endl;
+ {
+ *_so << endl << (testMode ? kTesting : kExtracting);
+ _so->NormalizePrint_wstr(name);
+ *_so << endl;
+ }
if (NeedPercents())
_percent.Command = "Open";
@@ -524,22 +576,23 @@ void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags)
void Add_Messsage_Pre_ArcType(UString &s, const char *pre, const wchar_t *arcType)
{
s.Add_LF();
- s.AddAscii(pre);
- s.AddAscii(" as [");
+ s += pre;
+ s += " as [";
s += arcType;
- s.AddAscii("] archive");
+ s += "] archive";
}
void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc)
{
const CArcErrorInfo &er = arc.ErrorInfo;
- UString s = L"WARNING:\n";
- s += arc.Path;
+ *_so << "WARNING:\n";
+ _so->NormalizePrint_UString(arc.Path);
+ UString s;
if (arc.FormatIndex == er.ErrorFormatIndex)
{
s.Add_LF();
- s.AddAscii("The archive is open with offset");
+ s += "The archive is open with offset";
}
else
{
@@ -580,7 +633,10 @@ HRESULT CExtractCallbackConsole::OpenResult(
{
*_se << endl;
if (level != 0)
- *_se << arc.Path << endl;
+ {
+ _se->NormalizePrint_UString(arc.Path);
+ *_se << endl;
+ }
}
if (errorFlags != 0)
@@ -614,7 +670,10 @@ HRESULT CExtractCallbackConsole::OpenResult(
{
*_so << endl;
if (level != 0)
- *_so << arc.Path << endl;
+ {
+ _so->NormalizePrint_UString(arc.Path);
+ *_so << endl;
+ }
}
if (warningFlags != 0)
@@ -669,7 +728,9 @@ HRESULT CExtractCallbackConsole::OpenResult(
_so->Flush();
if (_se)
{
- *_se << kError << name << endl;
+ *_se << kError;
+ _se->NormalizePrint_wstr(name);
+ *_se << endl;
HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink);
RINOK(res);
if (result == S_FALSE)
diff --git a/CPP/7zip/UI/Console/HashCon.cpp b/CPP/7zip/UI/Console/HashCon.cpp
index 863c5e5..ec8e6dc 100644
--- a/CPP/7zip/UI/Console/HashCon.cpp
+++ b/CPP/7zip/UI/Console/HashCon.cpp
@@ -7,9 +7,9 @@
#include "ConsoleClose.h"
#include "HashCon.h"
-static const wchar_t *kEmptyFileAlias = L"[Content]";
+static const char * const kEmptyFileAlias = "[Content]";
-static const char *kScanningMessage = "Scanning";
+static const char * const kScanningMessage = "Scanning";
static HRESULT CheckBreak2()
{
@@ -168,7 +168,7 @@ HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb)
if (PrintSize)
{
_s.Add_Space();
- const AString s2 = "Size";
+ const AString s2 ("Size");
AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len());
_s += s2;
}
@@ -269,7 +269,7 @@ HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBun
if (_fileName.IsEmpty())
*_so << kEmptyFileAlias;
else
- *_so << _fileName;
+ _so->NormalizePrint_UString(_fileName);
}
*_so << endl;
}
diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp
index 77168c9..ebcabb6 100644
--- a/CPP/7zip/UI/Console/List.cpp
+++ b/CPP/7zip/UI/Console/List.cpp
@@ -128,14 +128,14 @@ static const char * const kPropIdToName[] =
static const char kEmptyAttribChar = '.';
-static const char *kListing = "Listing archive: ";
+static const char * const kListing = "Listing archive: ";
-static const char *kString_Files = "files";
-static const char *kString_Dirs = "folders";
-static const char *kString_AltStreams = "alternate streams";
-static const char *kString_Streams = "streams";
+static const char * const kString_Files = "files";
+static const char * const kString_Dirs = "folders";
+static const char * const kString_AltStreams = "alternate streams";
+static const char * const kString_Streams = "streams";
-static const char *kError = "ERROR: ";
+static const char * const kError = "ERROR: ";
static void GetAttribString(UInt32 wa, bool isDir, bool allAttribs, char *s)
{
@@ -417,9 +417,8 @@ static void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UStr
nameU = name;
else
{
- char s[16];
- ConvertUInt32ToString(propID, s);
- nameA = s;
+ nameA.Empty();
+ nameA.Add_UInt32(propID);
}
}
@@ -429,7 +428,7 @@ void CFieldPrinter::AddProp(const wchar_t *name, PROPID propID, bool isRawProp)
f.PropID = propID;
f.IsRawProp = isRawProp;
GetPropName(propID, name, f.NameA, f.NameU);
- f.NameU.AddAscii(" = ");
+ f.NameU += " = ";
if (!f.NameA.IsEmpty())
f.NameA += " = ";
else
@@ -499,10 +498,7 @@ static void PrintTime(char *dest, const FILETIME *ft)
*dest = 0;
if (ft->dwLowDateTime == 0 && ft->dwHighDateTime == 0)
return;
- FILETIME locTime;
- if (!FileTimeToLocalFileTime(ft, &locTime))
- throw 20121211;
- ConvertFileTimeToString(locTime, dest, true, true);
+ ConvertUtcFileTimeToString(*ft, dest, kTimestampPrintLevel_SEC);
}
#ifndef _SFX
@@ -564,7 +560,7 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st)
{
if (!techMode)
g_StdOut << temp;
- g_StdOut.PrintUString(FilePath, TempAString);
+ g_StdOut.NormalizePrint_UString(FilePath, TempWString, TempAString);
if (techMode)
g_StdOut << MY_ENDL;
continue;
@@ -675,9 +671,10 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st)
else if (prop.vt == VT_BSTR)
{
TempWString.SetFromBstr(prop.bstrVal);
+ // do we need multi-line support here ?
+ g_StdOut.Normalize_UString(TempWString);
if (techMode)
{
- // replace CR/LF here.
g_StdOut.PrintUString(TempWString, TempAString);
}
else
@@ -686,7 +683,7 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st)
else
{
char s[64];
- ConvertPropertyToShortString(s, prop, f.PropID);
+ ConvertPropertyToShortString2(s, prop, f.PropID);
if (techMode)
g_StdOut << s;
else
@@ -819,25 +816,81 @@ static void PrintPropNameAndNumber_Signed(CStdOutStream &so, PROPID propID, Int6
so << val << endl;
}
-static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val)
+
+static void UString_Replace_CRLF_to_LF(UString &s)
+{
+ // s.Replace(L"\r\n", L"\n");
+ wchar_t *src = s.GetBuf();
+ wchar_t *dest = src;
+ for (;;)
+ {
+ wchar_t c = *src++;
+ if (c == 0)
+ break;
+ if (c == '\r' && *src == '\n')
+ {
+ src++;
+ c = '\n';
+ }
+ *dest++ = c;
+ }
+ s.ReleaseBuf_SetEnd((unsigned)(dest - s.GetBuf()));
+}
+
+
+static void PrintPropVal_MultiLine(CStdOutStream &so, const wchar_t *val)
{
- so << name << " = " << val << endl;
+ UString s = val;
+ if (s.Find(L'\n') >= 0)
+ {
+ so << endl;
+ so << "{";
+ so << endl;
+ UString_Replace_CRLF_to_LF(s);
+ so.Normalize_UString__LF_Allowed(s);
+ so << s;
+ so << endl;
+ so << "}";
+ }
+ else
+ {
+ so.Normalize_UString(s);
+ so << s;
+ }
+ so << endl;
+}
+
+
+static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val, bool multiLine)
+{
+ so << name << " = ";
+ if (multiLine)
+ {
+ PrintPropVal_MultiLine(so, val);
+ return;
+ }
+ UString s = val;
+ so.Normalize_UString(s);
+ so << s;
+ so << endl;
}
static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *name, const CPropVariant &prop)
{
UString s;
- ConvertPropertyToString(s, prop, propID);
+ ConvertPropertyToString2(s, prop, propID);
if (!s.IsEmpty())
{
AString nameA;
UString nameU;
GetPropName(propID, name, nameA, nameU);
if (!nameA.IsEmpty())
- PrintPropPair(so, nameA, s);
+ so << nameA;
else
- so << nameU << " = " << s << endl;
+ so << nameU;
+ so << " = ";
+ PrintPropVal_MultiLine(so, s);
}
}
@@ -866,11 +919,11 @@ static void ErrorInfo_Print(CStdOutStream &so, const CArcErrorInfo &er)
{
PrintErrorFlags(so, "ERRORS:", er.GetErrorFlags());
if (!er.ErrorMessage.IsEmpty())
- PrintPropPair(so, "ERROR", er.ErrorMessage);
+ PrintPropPair(so, "ERROR", er.ErrorMessage, true);
PrintErrorFlags(so, "WARNINGS:", er.GetWarningFlags());
if (!er.WarningMessage.IsEmpty())
- PrintPropPair(so, "WARNING", er.WarningMessage);
+ PrintPropPair(so, "WARNING", er.WarningMessage, true);
}
HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink)
@@ -881,7 +934,7 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const
const CArcErrorInfo &er = arc.ErrorInfo;
so << "--\n";
- PrintPropPair(so, "Path", arc.Path);
+ PrintPropPair(so, "Path", arc.Path, false);
if (er.ErrorFormatIndex >= 0)
{
if (er.ErrorFormatIndex == arc.FormatIndex)
@@ -889,7 +942,7 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const
else
PrintArcTypeError(so, codecs->GetFormatNamePtr(er.ErrorFormatIndex), true);
}
- PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex));
+ PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex), false);
ErrorInfo_Print(so, er);
@@ -947,7 +1000,8 @@ HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const
{
if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
{
- so << arcLink.NonOpen_ArcPath << endl;
+ so.NormalizePrint_UString(arcLink.NonOpen_ArcPath);
+ so << endl;
PrintArcTypeError(so, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
}
else
@@ -1018,15 +1072,18 @@ HRESULT ListArchives(CCodecs *codecs,
errorCode = ERROR_FILE_NOT_FOUND;
lastError = HRESULT_FROM_WIN32(lastError);;
g_StdOut.Flush();
- *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) <<
- endl << arcPath << endl << endl;
+ *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << endl;
+ g_ErrStream->NormalizePrint_UString(arcPath);
+ *g_ErrStream << endl << endl;
numErrors++;
continue;
}
if (fi.IsDir())
{
g_StdOut.Flush();
- *g_ErrStream << endl << kError << arcPath << " is not a file" << endl << endl;
+ *g_ErrStream << endl << kError;
+ g_ErrStream->NormalizePrint_UString(arcPath);
+ *g_ErrStream << " is not a file" << endl << endl;
numErrors++;
continue;
}
@@ -1065,7 +1122,9 @@ HRESULT ListArchives(CCodecs *codecs,
if (enableHeaders)
{
- g_StdOut << endl << kListing << arcPath << endl << endl;
+ g_StdOut << endl << kListing;
+ g_StdOut.NormalizePrint_UString(arcPath);
+ g_StdOut << endl << endl;
}
HRESULT result = arcLink.Open_Strict(options, &openCallback);
@@ -1075,7 +1134,9 @@ HRESULT ListArchives(CCodecs *codecs,
if (result == E_ABORT)
return result;
g_StdOut.Flush();
- *g_ErrStream << endl << kError << arcPath << " : ";
+ *g_ErrStream << endl << kError;
+ g_ErrStream->NormalizePrint_UString(arcPath);
+ *g_ErrStream << " : ";
if (result == S_FALSE)
{
Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink);
@@ -1259,7 +1320,7 @@ HRESULT ListArchives(CCodecs *codecs,
if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
{
g_StdOut << "----------\n";
- PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath);
+ PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath, false);
PrintArcTypeError(g_StdOut, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false);
}
}
diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp
index f54e9c3..8f2825c 100644
--- a/CPP/7zip/UI/Console/Main.cpp
+++ b/CPP/7zip/UI/Console/Main.cpp
@@ -10,10 +10,6 @@
#include "../../../../C/CpuArch.h"
-#if defined( _7ZIP_LARGE_PAGES)
-#include "../../../../C/Alloc.h"
-#endif
-
#include "../../../Common/MyInitGuid.h"
#include "../../../Common/CommandLineParser.h"
@@ -25,10 +21,6 @@
#include "../../../Windows/ErrorMsg.h"
-#ifdef _WIN32
-#include "../../../Windows/MemoryLock.h"
-#endif
-
#include "../../../Windows/TimeUtils.h"
#include "../Common/ArchiveCommandLine.h"
@@ -64,6 +56,8 @@ using namespace NCommandLineParser;
HINSTANCE g_hInstance = 0;
#endif
+extern bool g_LargePagesMode;
+
extern CStdOutStream *g_StdStream;
extern CStdOutStream *g_ErrStream;
@@ -73,24 +67,19 @@ extern const CCodecInfo *g_Codecs[];
extern unsigned g_NumHashers;
extern const CHasherInfo *g_Hashers[];
-static const char *kCopyrightString = "\n7-Zip"
-#ifndef EXTERNAL_CODECS
-#ifdef PROG_VARIANT_R
-" (r)"
-#else
-" (a)"
-#endif
-#endif
-
-#ifdef MY_CPU_64BIT
-" [64]"
-#elif defined MY_CPU_32BIT
-" [32]"
-#endif
+static const char * const kCopyrightString = "\n7-Zip"
+ #ifndef EXTERNAL_CODECS
+ #ifdef PROG_VARIANT_R
+ " (r)"
+ #else
+ " (a)"
+ #endif
+ #endif
-" " MY_VERSION_COPYRIGHT_DATE "\n\n";
+ " " MY_VERSION_CPU
+ " : " MY_COPYRIGHT_DATE "\n\n";
-static const char *kHelpString =
+static const char * const kHelpString =
"Usage: 7z"
#ifndef EXTERNAL_CODECS
#ifdef PROG_VARIANT_R
@@ -100,7 +89,6 @@ static const char *kHelpString =
#endif
#endif
" <command> [<switches>...] <archive_name> [<file_names>...]\n"
- " [<@listfiles...>]\n"
"\n"
"<Commands>\n"
" a : Add files to archive\n"
@@ -117,6 +105,7 @@ static const char *kHelpString =
"\n"
"<Switches>\n"
" -- : Stop switches parsing\n"
+ " @listfile : set path to listfile that contains file names\n"
" -ai[r[-|0]]{@listfile|!wildcard} : Include archives\n"
" -ax[r[-|0]]{@listfile|!wildcard} : eXclude archives\n"
" -ao{a|s|t|u} : set Overwrite mode\n"
@@ -128,6 +117,7 @@ static const char *kHelpString =
" -i[r[-|0]]{@listfile|!wildcard} : Include filenames\n"
" -m{Parameters} : set compression Method\n"
" -mmt[N] : set number of CPU threads\n"
+ " -mx[N] : set compression level: -mx1 (fastest) ... -mx9 (ultra)\n"
" -o{Directory} : set Output directory\n"
#ifndef _NO_CRYPTO
" -p{Password} : set Password\n"
@@ -152,6 +142,7 @@ static const char *kHelpString =
" -spe : eliminate duplication of root folder for extract command\n"
" -spf : use fully qualified file paths\n"
" -ssc[-] : set sensitive case mode\n"
+ " -sse : stop archive creating, if it can't open some input file\n"
" -ssw : compress shared files\n"
" -stl : set archive timestamp from the most recently modified file\n"
" -stm{HexMask} : set CPU thread affinity mask (hexadecimal number)\n"
@@ -166,13 +157,13 @@ static const char *kHelpString =
// ---------------------------
// exception messages
-static const char *kEverythingIsOk = "Everything is Ok";
-static const char *kUserErrorMessage = "Incorrect command line";
-static const char *kNoFormats = "7-Zip cannot find the code that works with archives.";
-static const char *kUnsupportedArcTypeMessage = "Unsupported archive type";
-// static const char *kUnsupportedUpdateArcType = "Can't create archive for that type";
+static const char * const kEverythingIsOk = "Everything is Ok";
+static const char * const kUserErrorMessage = "Incorrect command line";
+static const char * const kNoFormats = "7-Zip cannot find the code that works with archives.";
+static const char * const kUnsupportedArcTypeMessage = "Unsupported archive type";
+// static const char * const kUnsupportedUpdateArcType = "Can't create archive for that type";
-static CFSTR kDefaultSfxModule = FTEXT("7zCon.sfx");
+#define kDefaultSfxModule "7zCon.sfx"
static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code)
{
@@ -204,9 +195,9 @@ static void ShowCopyrightAndHelp(CStdOutStream *so, bool needHelp)
}
-static void PrintStringRight(CStdOutStream &so, const AString &s, unsigned size)
+static void PrintStringRight(CStdOutStream &so, const char *s, unsigned size)
{
- unsigned len = s.Len();
+ unsigned len = MyStringLen(s);
for (unsigned i = len; i < size; i++)
so << ' ';
so << s;
@@ -245,7 +236,8 @@ static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so)
{
FOR_VECTOR(i, pc.Paths)
{
- so << pc.Paths[i] << " : ";
+ so.NormalizePrint_UString(pc.Paths[i]);
+ so << " : ";
so << NError::MyFormatMessage(pc.Codes[i]) << endl;
}
so << "----------------" << endl;
@@ -279,7 +271,7 @@ static int WarningsCheck(HRESULT result, const CCallbackConsoleBase &callback,
UString message;
if (!errorInfo.Message.IsEmpty())
{
- message.AddAscii(errorInfo.Message);
+ message += errorInfo.Message.Ptr();
message.Add_LF();
}
{
@@ -384,11 +376,14 @@ static void PrintMemUsage(const char *s, UInt64 val)
*g_StdStream << " " << s << " Memory =";
PrintNum(SHIFT_SIZE_VALUE(val, 20), 7);
*g_StdStream << " MB";
+ if (g_LargePagesMode)
+ *g_StdStream << " (LP)";
}
EXTERN_C_BEGIN
typedef BOOL (WINAPI *Func_GetProcessMemoryInfo)(HANDLE Process,
PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb);
+typedef BOOL (WINAPI *Func_QueryProcessCycleTime)(HANDLE Process, PULONG64 CycleTime);
EXTERN_C_END
#endif
@@ -415,6 +410,8 @@ static void PrintStat()
PROCESS_MEMORY_COUNTERS m;
memset(&m, 0, sizeof(m));
BOOL memDefined = FALSE;
+ BOOL cycleDefined = FALSE;
+ ULONG64 cycleTime = 0;
{
/* NT 4.0: GetProcessMemoryInfo() in Psapi.dll
Win7: new function K32GetProcessMemoryInfo() in kernel32.dll
@@ -425,8 +422,9 @@ static void PrintStat()
// memDefined = GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m));
*/
+ HMODULE kern = ::GetModuleHandleW(L"kernel32.dll");
Func_GetProcessMemoryInfo my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)
- ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "K32GetProcessMemoryInfo");
+ ::GetProcAddress(kern, "K32GetProcessMemoryInfo");
if (!my_GetProcessMemoryInfo)
{
HMODULE lib = LoadLibraryW(L"Psapi.dll");
@@ -436,6 +434,11 @@ static void PrintStat()
if (my_GetProcessMemoryInfo)
memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m));
// FreeLibrary(lib);
+
+ Func_QueryProcessCycleTime my_QueryProcessCycleTime = (Func_QueryProcessCycleTime)
+ ::GetProcAddress(kern, "QueryProcessCycleTime");
+ if (my_QueryProcessCycleTime)
+ cycleDefined = my_QueryProcessCycleTime(GetCurrentProcess(), &cycleTime);
}
#endif
@@ -448,6 +451,16 @@ static void PrintStat()
UInt64 totalTime = curTime - creationTime;
PrintTime("Kernel ", kernelTime, totalTime);
+
+ #ifndef UNDER_CE
+ if (cycleDefined)
+ {
+ *g_StdStream << " ";
+ PrintNum(cycleTime / 1000000, 22);
+ *g_StdStream << " MCycles";
+ }
+ #endif
+
PrintTime("User ", userTime, totalTime);
PrintTime("Process", kernelTime + userTime, totalTime);
@@ -470,6 +483,7 @@ static void PrintHexId(CStdOutStream &so, UInt64 id)
PrintStringRight(so, s, 8);
}
+
int Main2(
#ifndef _WIN32
int numArgs, char *args[]
@@ -488,20 +502,25 @@ int Main2(
GetArguments(numArgs, args, commandStrings);
#endif
- if (commandStrings.Size() == 1)
+ #ifndef UNDER_CE
+ if (commandStrings.Size() > 0)
+ commandStrings.Delete(0);
+ #endif
+
+ if (commandStrings.Size() == 0)
{
ShowCopyrightAndHelp(g_StdStream, true);
return 0;
}
- commandStrings.Delete(0);
-
CArcCmdLineOptions options;
CArcCmdLineParser parser;
parser.Parse1(commandStrings, options);
+ g_StdOut.IsTerminalMode = options.IsStdOutTerminal;
+ g_StdErr.IsTerminalMode = options.IsStdErrTerminal;
if (options.Number_for_Out != k_OutStream_stdout)
g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL);
@@ -519,20 +538,6 @@ int Main2(
return 0;
}
- #if defined(_WIN32) && !defined(UNDER_CE)
- NSecurity::EnablePrivilege_SymLink();
- #endif
-
- #ifdef _7ZIP_LARGE_PAGES
- if (options.LargePages)
- {
- SetLargePageSize();
- #if defined(_WIN32) && !defined(UNDER_CE)
- NSecurity::EnablePrivilege_LockMemory();
- #endif
- }
- #endif
-
if (options.EnableHeaders)
ShowCopyrightAndHelp(g_StdStream, false);
@@ -579,7 +584,7 @@ int Main2(
#ifdef EXTERNAL_CODECS
if (!codecs->MainDll_ErrorPath.IsEmpty())
{
- UString s = L"Can't load module ";
+ UString s ("Can't load module: ");
s += fs2us(codecs->MainDll_ErrorPath);
throw s;
}
@@ -639,7 +644,7 @@ int Main2(
so << endl << "Formats:" << endl;
- const char *kArcFlags = "KSNFMGOPBELH";
+ const char * const kArcFlags = "KSNFMGOPBELH";
const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags);
for (i = 0; i < codecs->Formats.Size(); i++)
@@ -673,9 +678,9 @@ int Main2(
s += ext.Ext;
if (!ext.AddExt.IsEmpty())
{
- s += L" (";
+ s += " (";
s += ext.AddExt;
- s += L')';
+ s += ')';
}
}
diff --git a/CPP/7zip/UI/Console/MainAr.cpp b/CPP/7zip/UI/Console/MainAr.cpp
index 311c575..fdac643 100644
--- a/CPP/7zip/UI/Console/MainAr.cpp
+++ b/CPP/7zip/UI/Console/MainAr.cpp
@@ -24,12 +24,12 @@ extern int Main2(
#endif
);
-static const char *kException_CmdLine_Error_Message = "Command Line Error:";
-static const char *kExceptionErrorMessage = "ERROR:";
-static const char *kUserBreakMessage = "Break signaled";
-static const char *kMemoryExceptionMessage = "ERROR: Can't allocate required memory!";
-static const char *kUnknownExceptionMessage = "Unknown Error";
-static const char *kInternalExceptionMessage = "\n\nInternal Error #";
+static const char * const kException_CmdLine_Error_Message = "Command Line Error:";
+static const char * const kExceptionErrorMessage = "ERROR:";
+static const char * const kUserBreakMessage = "Break signaled";
+static const char * const kMemoryExceptionMessage = "ERROR: Can't allocate required memory!";
+static const char * const kUnknownExceptionMessage = "Unknown Error";
+static const char * const kInternalExceptionMessage = "\n\nInternal Error #";
static void FlushStreams()
{
@@ -79,7 +79,7 @@ int MY_CDECL main
PrintError(kUserBreakMessage);
return (NExitCode::kUserBreak);
}
- catch(const CArcCmdLineException &e)
+ catch(const CMessagePathException &e)
{
PrintError(kException_CmdLine_Error_Message);
if (g_ErrStream)
diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
index f1a1688..6e58c1f 100644
--- a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
@@ -32,13 +32,17 @@ HRESULT COpenCallbackConsole::Open_SetTotal(const UInt64 *files, const UInt64 *b
if (bytes)
{
- _totalBytesDefined = true;
- // _totalBytes = *bytes;
+ // _totalBytesDefined = true;
+ _totalBytes = *bytes;
if (!files)
_percent.Total = *bytes;
}
else
- _totalBytesDefined = false;
+ {
+ // _totalBytesDefined = false;
+ if (!files)
+ _percent.Total = _totalBytes;
+ }
}
return CheckBreak2();
@@ -83,7 +87,7 @@ HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password)
if (!PasswordIsDefined)
{
ClosePercents();
- Password = GetPassword(_so);
+ RINOK(GetPassword_HRESULT(_so, Password));
PasswordIsDefined = true;
}
return StringToBstr(Password, password);
diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.h b/CPP/7zip/UI/Console/OpenCallbackConsole.h
index fd07b98..b9270f8 100644
--- a/CPP/7zip/UI/Console/OpenCallbackConsole.h
+++ b/CPP/7zip/UI/Console/OpenCallbackConsole.h
@@ -18,9 +18,9 @@ protected:
CStdOutStream *_se;
bool _totalFilesDefined;
- bool _totalBytesDefined;
+ // bool _totalBytesDefined;
// UInt64 _totalFiles;
- // UInt64 _totalBytes;
+ UInt64 _totalBytes;
bool NeedPercents() const { return _percent._so != NULL; }
@@ -36,7 +36,8 @@ public:
COpenCallbackConsole():
_totalFilesDefined(false),
- _totalBytesDefined(false),
+ // _totalBytesDefined(false),
+ _totalBytes(0),
MultiArcMode(false)
#ifndef _NO_CRYPTO
diff --git a/CPP/7zip/UI/Console/PercentPrinter.cpp b/CPP/7zip/UI/Console/PercentPrinter.cpp
index f94d827..20249ed 100644
--- a/CPP/7zip/UI/Console/PercentPrinter.cpp
+++ b/CPP/7zip/UI/Console/PercentPrinter.cpp
@@ -141,8 +141,9 @@ void CPercentPrinter::Print()
{
_s += ' ';
- StdOut_Convert_UString_to_AString(FileName, _temp);
- _temp.Replace('\n', ' ');
+ _tempU = FileName;
+ _so->Normalize_UString(_tempU);
+ StdOut_Convert_UString_to_AString(_tempU, _temp);
if (_s.Len() + _temp.Len() > MaxLen)
{
unsigned len = FileName.Len();
@@ -153,8 +154,9 @@ void CPercentPrinter::Print()
delta = 1;
len -= delta;
_tempU = FileName;
- _tempU.Delete(len / 2, FileName.Len() - len);
+ _tempU.Delete(len / 2, _tempU.Len() - len);
_tempU.Insert(len / 2, L" . ");
+ _so->Normalize_UString(_tempU);
StdOut_Convert_UString_to_AString(_tempU, _temp);
if (_s.Len() + _temp.Len() <= MaxLen)
break;
diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
index d43a490..46ffaba 100644
--- a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
@@ -23,15 +23,15 @@ static NSynchronization::CCriticalSection g_CriticalSection;
#define MT_LOCK
#endif
-static const wchar_t *kEmptyFileAlias = L"[Content]";
+static const wchar_t * const kEmptyFileAlias = L"[Content]";
-static const char *kOpenArchiveMessage = "Open archive: ";
-static const char *kCreatingArchiveMessage = "Creating archive: ";
-static const char *kUpdatingArchiveMessage = "Updating archive: ";
-static const char *kScanningMessage = "Scanning the drive:";
+static const char * const kOpenArchiveMessage = "Open archive: ";
+static const char * const kCreatingArchiveMessage = "Creating archive: ";
+static const char * const kUpdatingArchiveMessage = "Updating archive: ";
+static const char * const kScanningMessage = "Scanning the drive:";
-static const char *kError = "ERROR: ";
-static const char *kWarning = "WARNING: ";
+static const char * const kError = "ERROR: ";
+static const char * const kWarning = "WARNING: ";
static HRESULT CheckBreak2()
{
@@ -143,7 +143,9 @@ HRESULT CUpdateCallbackConsole::OpenResult(
_so->Flush();
if (_se)
{
- *_se << kError << name << endl;
+ *_se << kError;
+ _se->NormalizePrint_wstr(name);
+ *_se << endl;
HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink);
RINOK(res);
_se->Flush();
@@ -185,7 +187,9 @@ void CCallbackConsoleBase::CommonError(const FString &path, DWORD systemError, b
*_se << endl << (isWarning ? kWarning : kError)
<< NError::MyFormatMessage(systemError)
- << endl << fs2us(path) << endl << endl;
+ << endl;
+ _se->NormalizePrint_UString(fs2us(path));
+ *_se << endl << endl;
_se->Flush();
}
}
@@ -241,6 +245,7 @@ static void PrintPropPair(AString &s, const char *name, UInt64 val)
void PrintSize_bytes_Smart(AString &s, UInt64 val);
void Print_DirItemsStat(AString &s, const CDirItemsStat &st);
+void Print_DirItemsStat2(AString &s, const CDirItemsStat2 &st);
HRESULT CUpdateCallbackConsole::FinishScanning(const CDirItemsStat &st)
{
@@ -259,7 +264,7 @@ HRESULT CUpdateCallbackConsole::FinishScanning(const CDirItemsStat &st)
return S_OK;
}
-static const char *k_StdOut_ArcName = "StdOut";
+static const char * const k_StdOut_ArcName = "StdOut";
HRESULT CUpdateCallbackConsole::StartOpenArchive(const wchar_t *name)
{
@@ -280,8 +285,8 @@ HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating)
if (_so)
{
*_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage);
- if (name != 0)
- *_so << name;
+ if (name)
+ _so->NormalizePrint_wstr(name);
else
*_so << k_StdOut_ArcName;
*_so << endl << endl;
@@ -316,7 +321,7 @@ HRESULT CUpdateCallbackConsole::WriteSfx(const wchar_t *name, UInt64 size)
{
*_so << "Write SFX: ";
*_so << name;
- AString s = " : ";
+ AString s (" : ");
PrintSize_bytes_Smart(s, size);
*_so << s << endl;
}
@@ -342,6 +347,7 @@ HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool
_tempA.Add_Space();
*_so << _tempA;
_tempU = fs2us(path);
+ _so->Normalize_UString(_tempU);
_so->PrintUString(_tempU, _tempA);
*_so << endl;
if (NeedFlush)
@@ -398,14 +404,31 @@ HRESULT CUpdateCallbackConsole::Finalize()
}
*/
-HRESULT CUpdateCallbackConsole::SetNumItems(UInt64 numItems)
+
+void static PrintToDoStat(CStdOutStream *_so, const CDirItemsStat2 &stat, const char *name)
+{
+ AString s;
+ Print_DirItemsStat2(s, stat);
+ *_so << name << ": " << s << endl;
+}
+
+HRESULT CUpdateCallbackConsole::SetNumItems(const CArcToDoStat &stat)
{
if (_so)
{
ClosePercents_for_so();
- AString s;
- PrintPropPair(s, "Items to compress", numItems);
- *_so << s << endl << endl;
+ if (!stat.DeleteData.IsEmpty())
+ {
+ *_so << endl;
+ PrintToDoStat(_so, stat.DeleteData, "Delete data from archive");
+ }
+ if (!stat.OldData.IsEmpty())
+ PrintToDoStat(_so, stat.OldData, "Keep old data in archive");
+ // if (!stat.NewData.IsEmpty())
+ {
+ PrintToDoStat(_so, stat.NewData, "Add new data to archive");
+ }
+ *_so << endl;
}
return S_OK;
}
@@ -457,7 +480,10 @@ HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *com
_tempU.Empty();
if (name)
+ {
_tempU = name;
+ _so->Normalize_UString(_tempU);
+ }
_so->PrintUString(_tempU, _tempA);
*_so << endl;
if (NeedFlush)
@@ -550,7 +576,9 @@ HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypt
AString s;
SetExtractErrorMessage(opRes, isEncrypted, s);
- *_se << s << " : " << endl << name << endl << endl;
+ *_se << s << " : " << endl;
+ _se->NormalizePrint_wstr(name);
+ *_se << endl << endl;
_se->Flush();
}
return S_OK;
@@ -622,7 +650,7 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined,
{
if (AskPassword)
{
- Password = GetPassword(_so);
+ RINOK(GetPassword_HRESULT(_so, Password));
PasswordIsDefined = true;
}
}
@@ -649,7 +677,7 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password)
if (!PasswordIsDefined)
{
{
- Password = GetPassword(_so);
+ RINOK(GetPassword_HRESULT(_so, Password))
PasswordIsDefined = true;
}
}
diff --git a/CPP/7zip/UI/Console/UserInputUtils.cpp b/CPP/7zip/UI/Console/UserInputUtils.cpp
index d45e840..7bdafda 100644
--- a/CPP/7zip/UI/Console/UserInputUtils.cpp
+++ b/CPP/7zip/UI/Console/UserInputUtils.cpp
@@ -14,8 +14,8 @@ static const char kNoAll = 's';
static const char kAutoRenameAll = 'u';
static const char kQuit = 'q';
-static const char *kFirstQuestionMessage = "? ";
-static const char *kHelpQuestionMessage =
+static const char * const kFirstQuestionMessage = "? ";
+static const char * const kHelpQuestionMessage =
"(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? ";
// return true if pressed Quite;
@@ -31,9 +31,16 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
*outStream << kHelpQuestionMessage;
outStream->Flush();
}
- AString scannedString = g_StdIn.ScanStringUntilNewLine();
+ AString scannedString;
+ if (!g_StdIn.ScanAStringUntilNewLine(scannedString))
+ return NUserAnswerMode::kError;
+ if (g_StdIn.Error())
+ return NUserAnswerMode::kError;
scannedString.Trim();
- if (!scannedString.IsEmpty())
+ if (scannedString.IsEmpty() && g_StdIn.Eof())
+ return NUserAnswerMode::kEof;
+
+ if (scannedString.Len() == 1)
switch (::MyCharLower_Ascii(scannedString[0]))
{
case kYes: return NUserAnswerMode::kYes;
@@ -52,7 +59,7 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
#endif
#endif
-UString GetPassword(CStdOutStream *outStream)
+static bool GetPassword(CStdOutStream *outStream, UString &psw)
{
if (outStream)
{
@@ -72,19 +79,32 @@ UString GetPassword(CStdOutStream *outStream)
if (console != INVALID_HANDLE_VALUE && console != 0)
if (GetConsoleMode(console, &mode))
wasChanged = (SetConsoleMode(console, mode & ~ENABLE_ECHO_INPUT) != 0);
- UString res = g_StdIn.ScanUStringUntilNewLine();
+ bool res = g_StdIn.ScanUStringUntilNewLine(psw);
if (wasChanged)
SetConsoleMode(console, mode);
+
+ #else
+
+ bool res = g_StdIn.ScanUStringUntilNewLine(psw);
+
+ #endif
+
if (outStream)
{
*outStream << endl;
outStream->Flush();
}
+
return res;
-
- #else
-
- return g_StdIn.ScanUStringUntilNewLine();
-
- #endif
+}
+
+HRESULT GetPassword_HRESULT(CStdOutStream *outStream, UString &psw)
+{
+ if (!GetPassword(outStream, psw))
+ return E_INVALIDARG;
+ if (g_StdIn.Error())
+ return E_FAIL;
+ if (g_StdIn.Eof() && psw.IsEmpty())
+ return E_ABORT;
+ return S_OK;
}
diff --git a/CPP/7zip/UI/Console/UserInputUtils.h b/CPP/7zip/UI/Console/UserInputUtils.h
index df2773d..ebe09c1 100644
--- a/CPP/7zip/UI/Console/UserInputUtils.h
+++ b/CPP/7zip/UI/Console/UserInputUtils.h
@@ -14,11 +14,14 @@ enum EEnum
kYesAll,
kNoAll,
kAutoRenameAll,
- kQuit
+ kQuit,
+ kEof,
+ kError
};
}
NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream);
-UString GetPassword(CStdOutStream *outStream);
+// bool GetPassword(CStdOutStream *outStream, UString &psw);
+HRESULT GetPassword_HRESULT(CStdOutStream *outStream, UString &psw);
#endif
diff --git a/CPP/7zip/UI/Console/resource.rc b/CPP/7zip/UI/Console/resource.rc
index 20dfee1..8d721f5 100644
--- a/CPP/7zip/UI/Console/resource.rc
+++ b/CPP/7zip/UI/Console/resource.rc
@@ -1,3 +1,7 @@
#include "../../MyVersionInfo.rc"
-MY_VERSION_INFO_APP("7-Zip Console", "7z")
+MY_VERSION_INFO_APP("7-Zip Console" , "7z")
+
+#ifndef UNDER_CE
+1 24 MOVEABLE PURE "Console.manifest"
+#endif
diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/CPP/7zip/UI/FileManager/BrowseDialog.cpp
index 703754f..d5c981c 100644
--- a/CPP/7zip/UI/FileManager/BrowseDialog.cpp
+++ b/CPP/7zip/UI/FileManager/BrowseDialog.cpp
@@ -209,7 +209,7 @@ bool CBrowseDialog::OnInit()
if (!FilterDescription.IsEmpty())
s = FilterDescription;
else if (ShowAllFiles)
- s = L"*.*";
+ s = "*.*";
else
{
FOR_VECTOR (i, Filters)
@@ -468,11 +468,11 @@ bool CBrowseDialog::GetParentPath(const UString &path, UString &parentPrefix, US
if (_topDirPrefix == path)
return false;
UString s = path;
- if (s.Back() == WCHAR_PATH_SEPARATOR)
+ if (IS_PATH_SEPAR(s.Back()))
s.DeleteBack();
if (s.IsEmpty())
return false;
- if (s.Back() == WCHAR_PATH_SEPARATOR)
+ if (IS_PATH_SEPAR(s.Back()))
return false;
int pos = s.ReverseFind_PathSepar();
parentPrefix.SetFrom(s, pos + 1);
@@ -531,7 +531,7 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
#ifndef UNDER_CE
bool isDrive = false;
- if (pathPrefix.IsEmpty() || pathPrefix == kSuperPathPrefix)
+ if (pathPrefix.IsEmpty() || pathPrefix.IsEqualTo(kSuperPathPrefix))
{
isDrive = true;
FStringVector drives;
@@ -551,7 +551,8 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
else
#endif
{
- CEnumerator enumerator(us2fs(pathPrefix + L'*'));
+ CEnumerator enumerator;
+ enumerator.SetDirPrefix(us2fs(pathPrefix));
for (;;)
{
bool found;
@@ -596,7 +597,7 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
if (_showDots && _topDirPrefix != DirPrefix)
{
item.iItem = index;
- const UString itemName = L"..";
+ const UString itemName ("..");
if (selectedName.IsEmpty())
cursorIndex = index;
item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
@@ -642,16 +643,14 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
_list.InsertItem(&item);
wchar_t s[32];
{
- FILETIME ft;
s[0] = 0;
- if (FileTimeToLocalFileTime(&fi.MTime, &ft))
- ConvertFileTimeToString(ft, s,
+ ConvertUtcFileTimeToString(fi.MTime, s,
#ifndef UNDER_CE
- true
+ kTimestampPrintLevel_MIN
#else
- false
+ kTimestampPrintLevel_DAY
#endif
- , false);
+ );
_list.SetSubItem(index, subItem++, s);
}
{
@@ -780,8 +779,10 @@ void CBrowseDialog::OnItemEnter()
*/
return;
}
- UString s = DirPrefix + fs2us(file.Name) + WCHAR_PATH_SEPARATOR;
- HRESULT res = Reload(s, L"");
+ UString s = DirPrefix;
+ s += fs2us(file.Name);
+ s.Add_PathSepar();
+ HRESULT res = Reload(s, UString());
if (res != S_OK)
MessageBox_HResError(*this, res, s);
SetPathEditText();
@@ -853,17 +854,17 @@ bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path,
#else
// maybe we must use GetLastError in WinCE.
DWORD errorCode = CommDlgExtendedError();
- const wchar_t *errorMessage = NULL;
+ const char *errorMessage = NULL;
switch (errorCode)
{
case 0: return false; // cancel or close obn dialog
- case FNERR_INVALIDFILENAME: errorMessage = L"Invalid File Name"; break;
- default: errorMessage = L"Open Dialog Error";
+ case FNERR_INVALIDFILENAME: errorMessage = "Invalid File Name"; break;
+ default: errorMessage = "Open Dialog Error";
}
if (!errorMessage)
return false;
{
- UString s = errorMessage;
+ UString s (errorMessage);
s.Add_LF();
s += path;
MessageBox_Error_Global(owner, s);
diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.cpp b/CPP/7zip/UI/FileManager/ExtractCallback.cpp
index 1c3141c..6433e91 100644
--- a/CPP/7zip/UI/FileManager/ExtractCallback.cpp
+++ b/CPP/7zip/UI/FileManager/ExtractCallback.cpp
@@ -335,20 +335,18 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileNam
s += msg;
else
{
- char temp[16];
- ConvertUInt32ToString(opRes, temp);
- s.AddAscii("Error #");
- s.AddAscii(temp);
+ s += "Error #";
+ s.Add_UInt32(opRes);
}
if (encrypted && opRes != NArchive::NExtract::NOperationResult::kWrongPassword)
{
- // s.AddAscii(" : ");
+ // s += " : ";
// AddLangString(s, IDS_EXTRACT_MSG_ENCRYPTED);
- s.AddAscii(" : ");
+ s += " : ";
AddLangString(s, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
}
- s.AddAscii(" : ");
+ s += " : ";
s += fileName;
}
}
@@ -466,7 +464,7 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags)
continue;
if (f == kpv_ErrorFlags_EncryptedHeadersError)
{
- m.AddAscii(" : ");
+ m += " : ";
AddLangString(m, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
}
if (!s.IsEmpty())
@@ -483,7 +481,7 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags)
ConvertUInt32ToHex(errorFlags, sz + 2);
if (!s.IsEmpty())
s.Add_LF();
- s.AddAscii(sz);
+ s += sz;
}
return s;
@@ -503,7 +501,7 @@ static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
if (warningFlags != 0)
{
s += GetNameOfProperty(kpidWarningFlags, L"Warnings");
- s.AddAscii(":");
+ s += ":";
s.Add_LF();
AddNewLineString(s, GetOpenArcErrorMessage(warningFlags));
}
@@ -511,7 +509,7 @@ static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
if (!er.WarningMessage.IsEmpty())
{
s += GetNameOfProperty(kpidWarning, L"Warning");
- s.AddAscii(": ");
+ s += ": ";
s += er.WarningMessage;
s.Add_LF();
}
@@ -519,9 +517,9 @@ static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
static UString GetBracedType(const wchar_t *type)
{
- UString s = L'[';
+ UString s ('[');
s += type;
- s += L']';
+ s += ']';
return s;
}
@@ -1009,7 +1007,7 @@ HRESULT CVirtFileSystem::FlushToDisk(bool closeLast)
{
_outFileStream.Release();
return E_FAIL;
- // MessageBoxMyError(UString(L"Can't create file ") + fs2us(tempFilePath));
+ // MessageBoxMyError(UString("Can't create file ") + fs2us(tempFilePath));
}
_fileIsOpen = true;
RINOK(WriteStream(_outFileStream, file.Data, (size_t)file.Size));
@@ -1027,7 +1025,7 @@ HRESULT CVirtFileSystem::FlushToDisk(bool closeLast)
_numFlushed++;
_fileIsOpen = false;
if (file.AttribDefined)
- NDir::SetFileAttrib(path, file.Attrib);
+ NDir::SetFileAttrib_PosixHighDetect(path, file.Attrib);
}
return S_OK;
}
diff --git a/CPP/7zip/UI/FileManager/OverwriteDialog.cpp b/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
index c5191d0..3f0180d 100644
--- a/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
+++ b/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
@@ -40,6 +40,12 @@ void COverwriteDialog::ReduceString(UString &s)
s.Delete(size / 2, s.Len() - size);
s.Insert(size / 2, L" ... ");
}
+ if (!s.IsEmpty() && s.Back() == ' ')
+ {
+ // s += (wchar_t)(0x2423);
+ s.InsertAtFront(L'\"');
+ s += L'\"';
+ }
}
void COverwriteDialog::SetFileInfoControl(int textID, int iconID,
@@ -66,13 +72,10 @@ void COverwriteDialog::SetFileInfoControl(int textID, int iconID,
if (fileInfo.TimeIsDefined)
{
- FILETIME localFileTime;
- if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime))
- throw 4190402;
AddLangString(s, IDS_PROP_MTIME);
- s += L": ";
- wchar_t t[32];
- ConvertFileTimeToString(localFileTime, t);
+ s += ": ";
+ char t[32];
+ ConvertUtcFileTimeToString(fileInfo.Time, t);
s += t;
}
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.cpp b/CPP/7zip/UI/FileManager/ProgressDialog.cpp
index 820e409..27d42b2 100644
--- a/CPP/7zip/UI/FileManager/ProgressDialog.cpp
+++ b/CPP/7zip/UI/FileManager/ProgressDialog.cpp
@@ -120,7 +120,7 @@ bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
wchar_t s[64];
ConvertUInt64ToString(percentValue, s);
UString title = s;
- title += L"% ";
+ title += "% ";
SetText(title + _title);
#ifndef _SFX
AddToTitle(title + MainAddTitle);
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
index dd3b493..bdb2be3 100644
--- a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
@@ -217,7 +217,7 @@ void CProgressSync::AddError_Message_Name(const wchar_t *message, const wchar_t
UString s;
if (name && *name != 0)
s += name;
- if (message && *message != 0 )
+ if (message && *message != 0)
{
if (!s.IsEmpty())
s.Add_LF();
@@ -232,11 +232,14 @@ void CProgressSync::AddError_Code_Name(DWORD systemError, const wchar_t *name)
{
UString s = NError::MyFormatMessage(systemError);
if (systemError == 0)
- s = L"Error";
+ s = "Error";
AddError_Message_Name(s, name);
}
-CProgressDialog::CProgressDialog(): _timer(0), CompressingMode(true), MainWindow(0)
+CProgressDialog::CProgressDialog():
+ _timer(0),
+ CompressingMode(true),
+ MainWindow(0)
{
_isDir = false;
@@ -828,8 +831,8 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
ConvertUInt64ToString(completedFiles, s);
if (IS_DEFINED_VAL(totalFiles))
{
- wcscat(s, L" / ");
- ConvertUInt64ToString(totalFiles, s + wcslen(s));
+ MyStringCat(s, L" / ");
+ ConvertUInt64ToString(totalFiles, s + MyStringLen(s));
}
if (_filesStr_Prev != s)
{
@@ -862,7 +865,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
{
_ratio_Prev = ratio;
ConvertUInt64ToString(ratio, s);
- wcscat(s, L"%");
+ MyStringCat(s, L"%");
SetItemText(IDT_PROGRESS_RATIO_VAL, s);
}
}
@@ -974,7 +977,9 @@ bool CProgressDialog::OnExternalCloseMessage()
::SendMessage(GetItem(IDCANCEL), BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0));
HideItem(IDB_PROGRESS_BACKGROUND);
HideItem(IDB_PAUSE);
-
+
+ ProcessWasFinished_GuiVirt();
+
bool thereAreMessages;
CProgressFinalMessage fm;
{
@@ -982,20 +987,22 @@ bool CProgressDialog::OnExternalCloseMessage()
thereAreMessages = !Sync.Messages.IsEmpty();
fm = Sync.FinalMessage;
}
+
if (!fm.ErrorMessage.Message.IsEmpty())
{
MessagesDisplayed = true;
if (fm.ErrorMessage.Title.IsEmpty())
- fm.ErrorMessage.Title = L"7-Zip";
+ fm.ErrorMessage.Title = "7-Zip";
MessageBoxW(*this, fm.ErrorMessage.Message, fm.ErrorMessage.Title, MB_ICONERROR);
}
else if (!thereAreMessages)
{
MessagesDisplayed = true;
+
if (!fm.OkMessage.Message.IsEmpty())
{
if (fm.OkMessage.Title.IsEmpty())
- fm.OkMessage.Title = L"7-Zip";
+ fm.OkMessage.Title = "7-Zip";
MessageBoxW(*this, fm.OkMessage.Message, fm.OkMessage.Title, MB_OK);
}
}
@@ -1050,8 +1057,8 @@ void CProgressDialog::SetTitleText()
{
char temp[32];
ConvertUInt64ToString(_prevPercentValue, temp);
- s.AddAscii(temp);
- s += L'%';
+ s += temp;
+ s += '%';
}
if (!_foreground)
{
@@ -1245,11 +1252,24 @@ void CProgressDialog::ProcessWasFinished()
}
+static THREAD_FUNC_DECL MyThreadFunction(void *param)
+{
+ CProgressThreadVirt *p = (CProgressThreadVirt *)param;
+ try
+ {
+ p->Process();
+ p->ThreadFinishedOK = true;
+ }
+ catch (...) { p->Result = E_FAIL; }
+ return 0;
+}
+
+
HRESULT CProgressThreadVirt::Create(const UString &title, HWND parentWindow)
{
NWindows::CThread thread;
RINOK(thread.Create(MyThreadFunction, this));
- ProgressDialog.Create(title, thread, parentWindow);
+ CProgressDialog::Create(title, thread, parentWindow);
return S_OK;
}
@@ -1265,7 +1285,7 @@ static void AddMessageToString(UString &dest, const UString &src)
void CProgressThreadVirt::Process()
{
- CProgressCloser closer(ProgressDialog);
+ CProgressCloser closer(*this);
UString m;
try { Result = ProcessVirt(); }
catch(const wchar_t *s) { m = s; }
@@ -1273,12 +1293,10 @@ void CProgressThreadVirt::Process()
catch(const char *s) { m = GetUnicodeString(s); }
catch(int v)
{
- wchar_t s[16];
- ConvertUInt32ToString(v, s);
- m = L"Error #";
- m += s;
+ m = "Error #";
+ m.Add_UInt32(v);
}
- catch(...) { m = L"Error"; }
+ catch(...) { m = "Error"; }
if (Result != E_ABORT)
{
if (m.IsEmpty() && Result != S_OK)
@@ -1295,7 +1313,7 @@ void CProgressThreadVirt::Process()
}
}
- CProgressSync &sync = ProgressDialog.Sync;
+ CProgressSync &sync = Sync;
NSynchronization::CCriticalSectionLock lock(sync._cs);
if (m.IsEmpty())
{
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.h b/CPP/7zip/UI/FileManager/ProgressDialog2.h
index 0e2f2ce..5e916e6 100644
--- a/CPP/7zip/UI/FileManager/ProgressDialog2.h
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2.h
@@ -261,7 +261,18 @@ public:
INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0);
+
+ /* how it works:
+ 1) the working thread calls ProcessWasFinished()
+ that sends kCloseMessage message to CProgressDialog (GUI) thread
+ 2) CProgressDialog (GUI) thread receives kCloseMessage message and
+ calls ProcessWasFinished_GuiVirt();
+ So we can implement ProcessWasFinished_GuiVirt() and show special
+ results window in GUI thread with CProgressDialog as parent window
+ */
+
void ProcessWasFinished();
+ virtual void ProcessWasFinished_GuiVirt() {}
};
@@ -273,7 +284,8 @@ public:
~CProgressCloser() { _p->ProcessWasFinished(); }
};
-class CProgressThreadVirt
+
+class CProgressThreadVirt: public CProgressDialog
{
protected:
FStringVector ErrorPaths;
@@ -281,33 +293,59 @@ protected:
// error if any of HRESULT, ErrorMessage, ErrorPath
virtual HRESULT ProcessVirt() = 0;
- void Process();
public:
HRESULT Result;
bool ThreadFinishedOK; // if there is no fatal exception
- CProgressDialog ProgressDialog;
-
- static THREAD_FUNC_DECL MyThreadFunction(void *param)
- {
- CProgressThreadVirt *p = (CProgressThreadVirt *)param;
- try
- {
- p->Process();
- p->ThreadFinishedOK = true;
- }
- catch (...) { p->Result = E_FAIL; }
- return 0;
- }
+ void Process();
void AddErrorPath(const FString &path) { ErrorPaths.Add(path); }
HRESULT Create(const UString &title, HWND parentWindow = 0);
CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {}
CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; }
-
};
UString HResultToMessage(HRESULT errorCode);
+/*
+how it works:
+
+client code inherits CProgressThreadVirt and calls
+CProgressThreadVirt::Create()
+{
+ it creates new thread that calls CProgressThreadVirt::Process();
+ it creates modal progress dialog window with ProgressDialog.Create()
+}
+
+CProgressThreadVirt::Process()
+{
+ {
+ ProcessVirt(); // virtual function that must implement real work
+ }
+ if (exceptions) or FinalMessage.ErrorMessage.Message
+ {
+ set message to ProgressDialog.Sync.FinalMessage.ErrorMessage.Message
+ }
+ else if (FinalMessage.OkMessage.Message)
+ {
+ set message to ProgressDialog.Sync.FinalMessage.OkMessage
+ }
+
+ PostMsg(kCloseMessage);
+}
+
+
+CProgressDialog::OnExternalCloseMessage()
+{
+ if (ProgressDialog.Sync.FinalMessage)
+ {
+ WorkWasFinishedVirt();
+ Show (ProgressDialog.Sync.FinalMessage)
+ MessagesDisplayed = true;
+ }
+}
+
+*/
+
#endif
diff --git a/CPP/7zip/UI/FileManager/resource.h b/CPP/7zip/UI/FileManager/resource.h
index 0b282b0..4666269 100644
--- a/CPP/7zip/UI/FileManager/resource.h
+++ b/CPP/7zip/UI/FileManager/resource.h
@@ -85,6 +85,8 @@
#define IDM_VIEW_TOOLBARS_LARGE_BUTTONS 752
#define IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT 753
+#define IDM_VIEW_TIME 761
+
#define IDS_BOOKMARK 801
#define IDM_OPTIONS 900
diff --git a/CPP/7zip/UI/GUI/ExtractDialog.cpp b/CPP/7zip/UI/GUI/ExtractDialog.cpp
index 283713d..71c2a3b 100644
--- a/CPP/7zip/UI/GUI/ExtractDialog.cpp
+++ b/CPP/7zip/UI/GUI/ExtractDialog.cpp
@@ -143,7 +143,7 @@ bool CExtractDialog::OnInit()
GetText(s);
if (!ArcPath.IsEmpty())
{
- s.AddAscii(" : ");
+ s += " : ";
s += ArcPath;
}
SetText(s);
@@ -409,10 +409,10 @@ void CExtractDialog::OnOK()
}
#ifndef NO_REGISTRY
-static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/extract.htm";
+#define kHelpTopic "fm/plugins/7-zip/extract.htm"
void CExtractDialog::OnHelp()
{
- ShowHelpWindow(NULL, kHelpTopic);
+ ShowHelpWindow(kHelpTopic);
CModalDialog::OnHelp();
}
#endif
diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp
index f3b08c2..37aa45b 100644
--- a/CPP/7zip/UI/GUI/ExtractGUI.cpp
+++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp
@@ -34,7 +34,7 @@ using namespace NWindows;
using namespace NFile;
using namespace NDir;
-static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path";
+static const wchar_t * const kIncorrectOutDir = L"Incorrect output directory path";
#ifndef _SFX
@@ -42,29 +42,19 @@ static void AddValuePair(UString &s, UINT resourceID, UInt64 value, bool addColo
{
AddLangString(s, resourceID);
if (addColon)
- s += L':';
+ s += ':';
s.Add_Space();
char sz[32];
ConvertUInt64ToString(value, sz);
- s.AddAscii(sz);
+ s += sz;
s.Add_LF();
}
static void AddSizePair(UString &s, UINT resourceID, UInt64 value)
{
- wchar_t sz[32];
AddLangString(s, resourceID);
- s += L": ";
- ConvertUInt64ToString(value, sz);
- s += MyFormatNew(IDS_FILE_SIZE, sz);
- // s += sz;
- if (value >= (1 << 20))
- {
- ConvertUInt64ToString(value >> 20, sz);
- s += L" (";
- s += sz;
- s += L" MB)";
- }
+ s += ": ";
+ AddSizeValue(s, value);
s.Add_LF();
}
@@ -83,16 +73,31 @@ public:
UStringVector *ArchivePathsFull;
const NWildcard::CCensorNode *WildcardCensor;
const CExtractOptions *Options;
+
#ifndef _SFX
CHashBundle *HashBundle;
+ virtual void ProcessWasFinished_GuiVirt();
#endif
+
CMyComPtr<IExtractCallbackUI> ExtractCallback;
UString Title;
+
+ CPropNameValPairs Pairs;
};
+
+#ifndef _SFX
+void CThreadExtracting::ProcessWasFinished_GuiVirt()
+{
+ if (HashBundle && !Pairs.IsEmpty())
+ ShowHashResults(Pairs, *this);
+}
+#endif
+
HRESULT CThreadExtracting::ProcessVirt()
{
CDecompressStat Stat;
+
#ifndef _SFX
if (HashBundle)
HashBundle->Init();
@@ -106,16 +111,23 @@ HRESULT CThreadExtracting::ProcessVirt()
HashBundle,
#endif
FinalMessage.ErrorMessage.Message, Stat);
+
#ifndef _SFX
- if (res == S_OK && Options->TestMode && ExtractCallbackSpec->IsOK())
+ if (res == S_OK && ExtractCallbackSpec->IsOK())
{
- UString s;
+ if (HashBundle)
+ {
+ AddValuePair(Pairs, IDS_ARCHIVES_COLON, Stat.NumArchives);
+ AddSizeValuePair(Pairs, IDS_PROP_PACKED_SIZE, Stat.PackSize);
+ AddHashBundleRes(Pairs, *HashBundle, UString());
+ }
+ else if (Options->TestMode)
+ {
+ UString s;
- AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false);
- AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize);
+ AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false);
+ AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize);
- if (!HashBundle)
- {
if (Stat.NumFolders != 0)
AddValuePair(s, IDS_PROP_FOLDERS, Stat.NumFolders);
AddValuePair(s, IDS_PROP_FILES, Stat.NumFiles);
@@ -126,24 +138,19 @@ HRESULT CThreadExtracting::ProcessVirt()
AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, Stat.NumAltStreams);
AddSizePair(s, IDS_PROP_ALT_STREAMS_SIZE, Stat.AltStreams_UnpackSize);
}
- }
-
- if (HashBundle)
- {
s.Add_LF();
- AddHashBundleRes(s, *HashBundle, UString());
+ AddLangString(s, IDS_MESSAGE_NO_ERRORS);
+ FinalMessage.OkMessage.Title = Title;
+ FinalMessage.OkMessage.Message = s;
}
-
- s.Add_LF();
- AddLangString(s, IDS_MESSAGE_NO_ERRORS);
-
- FinalMessage.OkMessage.Title = Title;
- FinalMessage.OkMessage.Message = s;
}
#endif
+
return res;
}
+
+
HRESULT ExtractGUI(
CCodecs *codecs,
const CObjectVector<COpenType> &formatIndices,
@@ -249,11 +256,11 @@ HRESULT ExtractGUI(
extracter.Title = title;
extracter.ExtractCallbackSpec = extractCallback;
- extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog;
+ extracter.ExtractCallbackSpec->ProgressDialog = &extracter;
extracter.ExtractCallback = extractCallback;
extracter.ExtractCallbackSpec->Init();
- extracter.ProgressDialog.CompressingMode = false;
+ extracter.CompressingMode = false;
extracter.ArchivePaths = &archivePaths;
extracter.ArchivePathsFull = &archivePathsFull;
@@ -263,10 +270,9 @@ HRESULT ExtractGUI(
extracter.HashBundle = hb;
#endif
- extracter.ProgressDialog.IconID = IDI_ICON;
+ extracter.IconID = IDI_ICON;
RINOK(extracter.Create(title, hwndParent));
- messageWasDisplayed = extracter.ThreadFinishedOK &
- extracter.ProgressDialog.MessagesDisplayed;
+ messageWasDisplayed = extracter.ThreadFinishedOK && extracter.MessagesDisplayed;
return extracter.Result;
}
diff --git a/CPP/7zip/UI/GUI/HashGUI.h b/CPP/7zip/UI/GUI/HashGUI.h
index 4fb0666..d6caa53 100644
--- a/CPP/7zip/UI/GUI/HashGUI.h
+++ b/CPP/7zip/UI/GUI/HashGUI.h
@@ -4,6 +4,7 @@
#define __HASH_GUI_H
#include "../Common/HashCalc.h"
+#include "../Common/Property.h"
HRESULT HashCalcGUI(
DECL_EXTERNAL_CODECS_LOC_VARS
@@ -11,6 +12,16 @@ HRESULT HashCalcGUI(
const CHashOptions &options,
bool &messageWasDisplayed);
+typedef CObjectVector<CProperty> CPropNameValPairs;
+
+void AddValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value);
+void AddSizeValue(UString &s, UInt64 value);
+void AddSizeValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value);
+
+void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb, const UString &firstFileName);
void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName);
+void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd);
+void ShowHashResults(const CHashBundle &hb, const UString &firstFileName, HWND hwnd);
+
#endif